8051单片机的C语言程序设计

   日期:2020-10-17     浏览:154    评论:0    
核心提示:一、数据类型(一)基本类型:1. 位类型(bit):1)是C51的扩充数据类型,用于访问8051中可寻址的位单元。2)8051支持两种位类型:bit型和sbit类型,它们在内存中都只占一个二进制位,其值可以是1或0。3)用bit定义的位变量在C51编译器编译时,在不同的时候位地址是可以变化的。4)用sbit定义的位变量必须与8051系列单片机的一个可以寻址单元或可位寻址的字节单元中的某一位联系在一起,在C51编译器编译时,其对应的位地址是不可以变化的。2. 字符型(char):1)有signe

一、数据类型
(一)基本类型:
1. 位类型(bit):1)是C51的扩充数据类型,用于访问8051中可寻址的位单元。
2)8051支持两种位类型:bit型和sbit类型,它们在内存中都只占一个二进制位,其值可以是1或0。
3)用bit定义的位变量在C51编译器编译时,在不同的时候位地址是可以变化的。
4)用sbit定义的位变量必须与8051系列单片机的一个可以寻址单元或可位寻址的字节单元中的某一位
联系在一起,在C51编译器编译时,其对应的位地址是不可以变化的。
2. 字符型(char):1)有signed char和unsigned char之分,默认signed char。占一个字节。
2)signed char定义带符号字节数据,字节最高位用0表示正数,1表示负数,一补码表示,数值
范围-128~+127.
3)unsigned char定义无符号字节数据或字符,可以存放一个字节的无符号数,数值范围0~255;
unsigned char还可以表示西文字符,占一个字节,在计算机中用ASCII码存放
3. 整型(int):1)有signed int和unsigned int之分,默认signed int。占两个字节。
2)signed int,用于存放两字节带符号数,以补码表示,数值范围-32768~+32767;
3)unsigned int,用于存放两个字节无符号数,数值范围0~65535;
4. 长整型(long):1)有signed long和unsigned long之分,默认signed long,占4个字节;
2)signed long,用于存放4字节带符号数,以补码表示,数值范围-2147483648~+2147483648;
3)unsigned long,用于存放4个字节无符号数,数值范围0~4294967695;
5. 浮点型(float):占4个字节
6. 特殊功能寄存器型:1)这是C51的扩充的数据类型,用于访问8051单片机中的特殊功能寄存器数据;
2)分为sfr和sfr16两种。sfr为字节型特殊功能寄存器类型,占一个字节单元,利用它可以访问
8051单片机内部所有的特殊功能寄存器;sfr16为2字节特殊功能寄存器类型,占2进行个字
节单元,利用它可以访问8051单片机内部所有2字节的特殊功能寄存器。
3)在C51中对特殊功能寄存器的访问必须先用sfr和sfr16进行声明
(二)构造类型
1. 数组类型(array)
2. 结构体类型(struct)
3. 共用体(union)
4. 枚举(enum)
(三)指针类型
指针型本身是一个变量,在这个变量中存放着指向另一个数据的地址。这个指针变量要占用一定的内 存单元,对于不 同的处理器器长度不一样,在C51中指针的长度一般为1~3个字节。
(四)空类型
二、C51的运算量
(一)常量
包括整型常量、浮点型常量、字符型常量、字符串型常量
(二)变量
1. 存储器类型
2. 特殊功能寄存器变量
1)格式:sfr/sfr16 特殊功能寄存器名=地址。
2)特殊功能寄存器名一般用大写字母表示,地址一般采用直接地址形式,具体特殊功能寄存器地址看之前的文章
例:sfr PSW=0xD0;–>定义程序状态字PSW的地址为D0H;
sfr TMOD=0x89;–>定义定时器控制寄存器TMOD的地址为89H;
sfr P1=0x90;–>定义p1端口的地址为90H;
3. 位变量
1)格式:bit 位变量名(注意:在格式中可以加上各种修饰符,但存储器类型只有bdata data idata)
例:bit data a1;正确
bit pdata a2;错误
2)格式:sbit 位变量名=位地址;(注意:如位地址为为直接地址,其取值范围为0x00~0xFF;如位地址是可位寻址变量带位号或特殊功能寄存器名带位号,则在它前面需对可位寻址变量或特殊功能寄存器进行定义。字节地址与位号之间、特殊功能寄存器与位号之间一般用……作间隔。
例:sbit Cy=0xD7;–>定义进位标志Cy的地址位D7H;
sbit AC=0xD0……6;–>定义辅助进位标志AC的地址为D6H;
sbit RS0=0xD0^3;–>定义RS0的地址为D0H;
(三)存储模式
C51编译器支持3种存储模式:SMALL模式、COMPACT模式和LARGE模式。
1. SMALL模式:称为小编译模式,编译时函数参数和变量被默认在片内RAM中,存储器类型为data;
2. COMPACT模式:称为紧凑编译模式,函数参数被默认在片外RAM的低256B空间,存储类型为pdata;
3. LARGE模式:称为大编译模式,编译时函数参数和变量被默认在片外RAM的64B空间,存储类型为xdata;
在程序中变量存储模式的指定通过#pragma预处理指令来实现。函数的存储模式可通过函数定义时后面带存储模式来说明。如果没有指定,则默认为SMALL模式。
例:#pragma small/int func() small/int func() -->都是变量的存储模式为small模式
(四)绝对地址访问
在C51中,可以通过变量的形式访问8051单片机的的存储器,也可以通过绝对地址来访问存储器,访问绝对地址有3种
1. 使用C51运行库中预定义宏(使用时加头文件 #include <absacc.h>)
在C51中,可以通过变量的形式访问8051单片机的code、data、pdata、xdata空间进行绝对寻址。规定只能以无符号的方式访问,定义了8个宏,原型如下:
#difine CBYTE((unsigned char volatile*)0x50000L)–>(CBYTE以字节形式对code区寻址)
#difine DBYTE((unsigned char volatile*)0x40000L)–>(DBYTE以字节形式对data区寻址)
#difine PBYTE((unsigned char volatile*)0x30000L)–>(PBYTE以字节形式对pdata区寻址)
#difine XBYTE((unsigned char volatile*)0x20000L)–>(XBYTE以字节形式对xdata区寻址)
#difine CWORd((unsigned int volatile*)0x50000L)–>(CWORD以字节形式对code区寻址)
#difine DWORd((unsigned int volatile*)0x50000L)–>(DWORD以字节形式对data区寻址)
#difine PWORd((unsigned int volatile*)0x50000L)–>(PWORD以字节形式对pdata区寻址)
#difine XWORd((unsigned int volatile*)0x50000L)–>(XWORD以字节形式对xdata区寻址)
访问形式:宏名[地址];其中CBYTE、DBYTE、PBYTE、XBYTE、CWORD、DWORD、PWORD、XWORD为宏名,地址用16进制表示:
例:var1 = XBYTE[0x0005];–>XBYTE[0x0005]访问片外RAM的0005字节单元;
2. 通过指针访问
采用指针的方法,可以实现C51程序中对任意指定的存储器单元进行访问。
例: int xdata *dpt1;–>定义一个指向xdata区的指针dpt1;
dpt1=0x30;–>dpt1指针赋值,指向xdata区的30H单元;
dpt1=0xFF;–>将数据0xFF送到片外RAM的30H单元;
3. 使用C51关键扩展字_at_
使用_at_是对指定的存储器空间的绝对地址进行访问,格式:[存储器类型] 数据类型说明符 变量名 at 地址常数;
地址常数用于指定变量的绝对地址,必须位于有效的存储空间之内,使用_at_定义的变量必须为全局变量。
例:data char x1_at_0x40;–>在data区中定义字节变量x1,它的地址为40H;
三、函数
(一)函数的定义
一般格式:函数类型 函数名(形式参数表) [reentrant] [interrupt m] using n
(二)reentrant修饰符
在C51中,这个修饰符用于把函数定义可重入函数。所谓的可重入的函数就是允许被递归调用的函数。一般的函数不可以递归调用,只有可重入函数才允许递归调用。在C51中,当函数被定义为可重入函数,C51编译器编译时将会为可重入函数生成一个模块栈,通过这个模块栈来完成参数的传递和局部变量存放。关于可重入函数,应该注意以下几点:
1. 用reentrant修饰的可重入函数被调用的时,实参列表内不允许使用bit类型的参数。函数体内也不允许存在任何关于位变量的操作,更不能返回bit类型的值。
2. 编译时,系统为可重入函数在内部或外部存储器中建立一个模拟堆栈区,称为重入栈。可重入函数的局部变量及参数被放入重入栈中,时可重入函数可以实现被递归调用。
3. 在参数的传递上,实际参数可以传递给间接调用的可重入参数。无重入属性的间接调用函数不能包含调用函数,但是可以使用定义的全局变量来进行参数传递。
(三)interrupt m修饰符
interrupt m是C51函数中一个非常重要的修饰符,是因为中断函数必须通过它来进行修饰。在C51程序设计时,当函数用interrupt 修饰时,系统编译把对应的函数转化为中断函数,自动加上程序头段和尾段,并按MCS-51系统中断的处理方式自动把它安排在程序存储器的相应位置。在该修饰符中,m的取值为0~31,对应的中断如下:
0——外部中断;1——定时器/计数器T0;2——外部中断;3——定时器/计数器T1;
4——串行口中断;5——定时器/计数器T2;其他值预留。使用中断函数应注意以下7点:
1. 中断函数不能进行参数传递,如果中断函数中包含任何参数声明,都将导致编译出错;
2. 中断函数没有返回值,如果试图定义一个返回值,将得不到正确的结果,建议在定义中断函数时将其定义为void型,以说明没有返回值;
3. 在任何情况下都不能之间调用中断函数,否则会产生编译错误。因为中断函数的返回由8051单片机的RETI指令完成,RETI指令影响8051单片机的硬件中断系统。如果在没有实际中断情况下之间调用中断函数,RETI指令的操作结果会产生一个致命的错误。当中断条件满足时自动调用。
4. 如果在中断函数中直接调用了其他函数,则被调用函数所使用的寄存器必须与中断函数相同,否则不会输出正确结果。
5. C51编译器对中断函数编译时,会自动在程序开始和结束加上相应的内容。具体如下:在程序开始处ACC、B、DPH、DPL、PSW入栈,结束时出栈;中断函数未加using n修饰符的,开始时还要将R0~R1入栈,结束时出栈,如中断函数加using n修饰符,则在开始PSW将入栈后还要修改PSW中的工作寄存组选择位。
6. C51编译器从绝对地址8m+3处产生一个中断向量,其中m为中断号,即interrupt后面的数字,该向量包含一个到中断函数入口的绝对跳转。
7. 中断函数最好写在文件的尾部,并且禁止使用extern存储类型说明,以防其他程序调用。
(四)using n修饰符
MCS-51单片机有4组工作寄存器:0组、1组、2组、3组。每组8个寄存器,分别用R0~7R表示。修饰符using n用于指定本函数内部使用的工作寄存器组,其中n的取值范围0–3,表示寄存器组号。对应using n的使用,注意以下几点:
1. 加入using n后,C51在编译时自动在函数的开始处和结束处加入以下命令。
{
PUSH PSW;//标志寄存器入栈
MOV PSW,#与寄存器组号n相关的常量;//常量值为(PSW&OXET)&n
8
~~~~~
POP PSW;//标志寄存器出栈
}
2. using n修饰符不能用于有返回值的函数,因为C51函数的返回值是放在寄存器中的。如果寄存器组改变了,返回值就会出错。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服