找回密码
 立即注册
查看: 51|回复: 1

8051单片机C51语言规范简介

[复制链接]
  • 打卡等级:常住居民II
  • 打卡总天数:87
  • 最近打卡:2026-05-11 01:12:23

164

主题

1329

回帖

5084

积分

荣誉版主

积分
5084
发表于 2026-5-3 11:20:42 | 显示全部楼层 |阅读模式
KeilC51编译器是目前各种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地址 ^ 位序号;`
   - 示例:`sbit  LED = P1^0;`
要求  
- 掌握通过 `reg51.h` `reg52.h` 头文件引用已定义的SFR  
- 能独立使用sfr/sbit定义用户所需的寄存器或引脚。

数据类型
学习目标:区分C51与标准C的数据类型差异,理解硬件资源对类型选择的影响。
知识点
Fig_01_数据类型.jpg
扩展存储类型(重要):
- `code` 程序存储器(只读,存放常量/表格)  
- `data` 直接寻址片内数据存储器(最快,128字节)  
- `idata` 间接寻址片内数据存储器(256字节)  
- `bdata` 可位寻址的片内数据存储器(16字节)  
- `xdata` 外部数据存储器(最大64KB,访问较慢)  
示例  
unsignedchar data var1;       // 内部RAM直接寻址
unsignedint xdata buffer[10]; // 外部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(unsigned  char  a, unsigned  char  b){
         return  a + b;
     }
     ```
2. 函数参数与返回值
   - 参数通过寄存器(R7及工作寄存器组)传递,最多3个参数用寄存器,其余用固定存储区。  
   - 返回值(若长度≤4B)存放于R7/R6/R5/R4  
   - 原则上避免使用带大量参数的函数,以减少代码量和调用开销。
3. 中断服务函数
   - 格式`void 函数名(void)  interrupt 中断号 [using 寄存器组号] { ... }`  
   - 中断号
Fig_02_中断.jpg
   - 示例:
      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[0x2000] = 0x55;`
5. 内嵌函数和 intrinsics `<intrins.h>`  
   - 循环移位:`_crol_``_cror_`(字节循环左移/右移)。  
   - 空操作:`_nop_()`(对应单周期NOP指令)。  
   - 特殊指令:`_push_``_pop_`(很少直接使用)。
要求  
- 记住常用库函数所属头文件及基本功能。  
- 能够利用 `_nop_()` 产生精确延时,利用 `XBYTE` 访问外部设备。  
- 注意库函数对ROMRAM的消耗,谨慎用于资源限制型项目。

八、学习者应具备的知识与能力总结
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 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:245
  • 最近打卡:2026-05-11 00:03:15
已绑定手机

23

主题

426

回帖

1921

积分

金牌会员

DIY玩家

积分
1921
发表于 2026-5-3 23:31:43 | 显示全部楼层
重要的知识点
对学生朋友作用大
真正的学徒往往怀着大师的心
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-5-11 09:12 , Processed in 0.121911 second(s), 52 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表