8051单片机C51语言规范简介
Keil的C51编译器是目前各种8051单片机的主流编译器,C51是该编译器制定的单片机C语言标准,本文将介绍C51的各个规范。一、基本说明C51语言是基于标准C语言(ANSI C)为8051单片机扩展的专业嵌入式开发语言,由Keil公司实现并集成于µVision开发环境。学习者应首先掌握标准C语法基础,再学习C51的扩展特性。以下按知识点逐条列出学习内容和要求。
二、特殊功能寄存器(SFR)定义学习目标:能够正确访问单片机内部SFR及其可寻址位。知识点:1. sfr关键字 - 用于定义8位特殊功能寄存器,格式:`sfr 寄存器名 = 地址常数;` - 示例:`sfr P0 = 0x80;`// 定义P0口寄存器地址2. sbit关键字 - 用于定义SFR中的可独立寻址的位。 - 三种格式: sbit 位名 = 寄存器名 ^ 位序号;` sbit 位名 = 地址常数;` (位地址,0x80~0xFF) sbit 位名 = SFR地址 ^ 位序号;` - 示例:`sbitLED = P1^0;`要求:- 掌握通过 `reg51.h` 或 `reg52.h` 头文件引用已定义的SFR。- 能独立使用sfr/sbit定义用户所需的寄存器或引脚。
三数据类型学习目标:区分C51与标准C的数据类型差异,理解硬件资源对类型选择的影响。知识点: 扩展存储类型(重要):- `code` – 程序存储器(只读,存放常量/表格)- `data` – 直接寻址片内数据存储器(最快,128字节)- `idata`– 间接寻址片内数据存储器(256字节)- `bdata`– 可位寻址的片内数据存储器(16字节)- `xdata`– 外部数据存储器(最大64KB,访问较慢)示例:unsignedchar data var1; // 内部RAM直接寻址unsignedint xdata buffer; // 外部RAM数组code chartable[] = {0x3F,0x06}; // 常量表存于ROM```要求:- 熟记每种数据类型在8051中的字节数及默认符号特性(char默认无符号)。- 能够根据变量用途(频繁访问、数据量大小、位操作)合理选择存储类型。
四、运算符的分类与功能学习目标:熟悉 C51的各种运算,能正确使用各种运算。知识点:算术运算符- `+`(加)、`-`(减)、`*`(乘)、`/`(除)、`%`(取模)- 功能:执行基本的数学运算。注意整数除法会截断小数部分,取模运算要求操作数为整型。关系运算符- `>`、`<`、`>=`、`<=`、`==`(等于)、`!=`(不等于)- 功能:比较两个值,返回真(1)或假(0),常用于条件判断。逻辑运算符-`&&`(逻辑与)、`||`(逻辑或)、`!`(逻辑非)- 功能:用于组合多个条件,返回布尔结果。逻辑与、或具有短路特性。二进制运算(位运算符)- `&`(按位与)、`|`(按位或)、`^`(按位异或)、`~`(按位取反)、`<<`(左移)、`>>`(右移)- 功能:直接操作数据的二进制位,在控制 I/O 口、状态寄存器时极为常用。赋值运算符- `=`(直接赋值)、`+=`、`-=`、`*=`、`/=`、`%=`、`&=`、`|=`、`^=`、`<<=`、`>>=`- 功能:将右侧表达式的值赋给左侧变量,复合赋值运算符可简化书写。自增自减运算符- `++`(自增1)、`--`(自减1)- 功能:分为前缀(`++i`)和后缀(`i++`)形式,前缀先变化后参与运算,后缀则相反。条件运算符- `? :`(三元运算符),格式:`表达式1 ? 表达式2 : 表达式3`- 功能:若表达式1为真,则返回表达式2的值,否则返回表达式3的值。逗号运算符- `,`(逗号)- 功能:从左到右依次计算各表达式,整个逗号表达式的值为最后一个表达式的值。sizeof 运算符-`sizeof(类型或表达式)`- 功能:返回对象或类型所占的字节数(编译时计算)。指针运算符- `*`(取内容)、`&`(取地址)- 功能:通过指针间接访问变量。C51 中指针可以指向不同存储区(如 data, xdata),需要留意存储类型。C51 特有的位运算- 使用 `bit` 类型定义位变量,`sbit` 定义可独立寻址的位(如引脚或寄存器中的某一位)。- 位变量可直接参与逻辑运算,如 `bit f = a && b;`或 `sbit LED = P1^0; LED =1;`。要求:- 熟记各种数据类型支持的运算。- 能够根据变量用途正确使用运算来完成数据处理。
五、各种类型语句学习目标:标准C的所有控制语句均适用,同时掌握C51的若干特殊语句形式。知识点:1. 标准控制语句 - 选择:`if ... else`,`switch ... case` - 循环:`while`,`do ... while`,`for` - 跳转:`break`,`continue`,`return`,`goto`
2. C51扩展语句/关键字 - `interrupt` – 在函数定义中声明为中断服务函数 - `using` – 指定中断服务函数使用的工作寄存器组 - `reentrant` – 声明可重入函数(允许递归或被多任务调用) - `_at_` – 绝对地址变量定位(如 `unsigned char xdata var_at_ 0x1000;`)3. 预处理语句 - 与标准C相同:`#include`,`#define`,`#ifdef`,`#pragma` 等。要求:- 能正确使用标准选择、循环结构设计程序流程。- 了解中断函数和重入函数的声明语法。
六、函数定义与调用学习目标:掌握C51函数结构、参数传递方式以及中断服务函数的特殊写法。知识点:1. 普通函数定义 - 格式:`[存储类型] 返回值类型 函数名([参数列表]) [重入声明] { 函数体 }` - 示例: unsigned char add(unsignedchara, unsignedcharb){ returna + b; } ```2. 函数参数与返回值 - 参数通过寄存器(R7及工作寄存器组)传递,最多3个参数用寄存器,其余用固定存储区。 - 返回值(若长度≤4B)存放于R7/R6/R5/R4。 - 原则上避免使用带大量参数的函数,以减少代码量和调用开销。3. 中断服务函数 - 格式:`void 函数名(void)interrupt 中断号 寄存器组号] { ... }` - 中断号: - 示例:
void timer0_isr(void) interrupt 1 using 1{ TH0 = 0xDC;// 重装初值 } ```4. 可重入函数 - 格式:`返回值 函数名(参数列表) reentrant { ... }` - 需在项目配置中占用一块模拟堆栈区(非必需时不使用,因为开销大)。5. 函数调用规范 - 支持函数嵌套调用,不支持递归(除非声明为 `reentrant`)。 - 中断函数不可被普通函数直接调用,但普通函数可被中断函数调用。
要求:- 能编写无参、有参、有返回值的基本函数。- 会编写及配置一个中断服务函数(包含中断号和寄存器组选择)。- 知道递归在C51中的限制及解决办法(使用reentrant)。
七、库函数学习目标:熟悉Keil C51自带的常用库函数,能正确包含头文件并调用。知识点:1. 标准输入输出库 `<stdio.h>`* - 需自行实现底层字符输出函数(如 `putchar`),常用于串口打印调试。 - 常用函数:`printf`,`scanf`,`puts`,`gets` 等(受限于硬件资源,建议慎用)。2. 数学库 `<math.h>` - 浮点运算函数:`sin`,`cos`,`sqrt`,`pow`,`abs` 等。 - 注意:浮点运算会生成较大代码量,资源紧张的芯片避免使用。3. 字符串与内存操作 `<string.h>` - `strcpy`,`strlen`,`memcpy`,`memset`(与标准C相同)。 - 可直接操作xdata/code区的字符串。4. 绝对地址访问库 `<absacc.h>`** - 提供 `CBYTE`(code区字节)、`DBYTE`(data区)、`XBYTE`(xdata区)等宏,用于直接读写指定地址。 - 示例:`XBYTE = 0x55;`5. 内嵌函数和 intrinsics 库 `<intrins.h>` - 循环移位:`_crol_`,`_cror_`(字节循环左移/右移)。 - 空操作:`_nop_()`(对应单周期NOP指令)。 - 特殊指令:`_push_`,`_pop_`(很少直接使用)。要求:- 记住常用库函数所属头文件及基本功能。- 能够利用 `_nop_()` 产生精确延时,利用 `XBYTE` 访问外部设备。- 注意库函数对ROM和RAM的消耗,谨慎用于资源限制型项目。
八、学习者应具备的知识与能力总结1. 先修基础 - 标准C语法:数据类型、运算符、表达式、流程控制、数组、指针、函数、结构体。 - 8051硬件基本概念:ROM/RAM映射、SFR地址、中断向量表、寄存器组。2. C51核心技能 - 使用 `sfr` / `sbit` 定义或访问硬件寄存器。 - 为变量选择正确的存储类型(`code`,`data`,`xdata` 等),理解速度与空间的权衡。 - 编写普通函数与中断服务函数,掌握 `interrupt` 和 `using` 的用法。 - 调用标准库函数(尤其字符串操作、绝对地址访问、内嵌NOP和循环移位)。 - 阅读并修改由Keil生成的启动文件(STARTUP.A51)以配置堆栈和内存模式。掌握以上内容后,学习者应能独立阅读并编写规范的C51工程代码,为后续开发实际单片机应用打下坚实基础。3.C51学习重点与常见误区 - 误区1:认为标准C的 `int` 是32位 —— 实际为16位,注意溢出。 - 误区2:在中断函数中调用普通函数(若普通函数不可重入且被主循环调用,将导致数据错乱)。 - 误区3:错误选择寄存器组,导致中断现场被破坏。 - 重点:资源有限,优先使用无符号整数、尽量缩短函数调用栈、大数组置于xdata。
重要的知识点
对学生朋友作用大
页:
[1]