单片机C语言头文件.docx
- 文档编号:3915090
- 上传时间:2023-05-06
- 格式:DOCX
- 页数:11
- 大小:20.37KB
单片机C语言头文件.docx
《单片机C语言头文件.docx》由会员分享,可在线阅读,更多相关《单片机C语言头文件.docx(11页珍藏版)》请在冰点文库上搜索。
单片机C语言头文件
单片机C语言编程头文件解析
一,C51内存结构深度剖析
二,reg51.头文件剖析
三,浅淡变量类型及其作用域
四,C51常用头文件
五,浅谈中断
六,C51编译器的限制
七,小淡C51指针
*************************************
reg51.头文件剖析
我们平时写单片机应用程序的时候,所使用的头文件大多都是用的的reg51.h或是用reg52.h。
会写C51的人都会用,但对其头文件内部的定义有所了解的人确并不多。
下面对其内部做详细解释,方便读者作进一步的了解,并能运用各类型号的单片机。
因为增强型号的单片机的增强功能都是通过特殊功能寄存器(SFR)控制。
打开reg52.h头文件,会发现是由大量的sfr,sbit的声明组成,甚至于还有sfr16.其实这样的声明都是与单片机内部功能寄存器(特殊功能寄存器)联系起来的,下面对其做出详细解释
sfr:
声明变量
SFR声明一个变量,它的声明与其它的C变量声明基本相同,唯一的区别,SFR在声明的同时为其指定特殊功能寄存器作为存储地址,而不同于C变量声明的整型,字符型等等由编译器自动分配存储空间。
(sfr只用于特殊功能寄存器的声明)
如reg52.h头文件,第一条声明就是sfrP0=0x80;
此处声明一个变量P0,并指定其存储地址为特殊功能寄存器0x80;,在加入reg52.h头文件后。
编写应用程序时P0就可以直接使用而无需定义,对P0的操作就是,对内部特殊功能寄存器(0x80对应用MCU的P0口)的操作,可进行读写操作。
如果将第一条声明改为sfrK0=0x80;那么,如果要把单片机的P0口全部拉低,则不能写P0=0x00;而应保存后再在应用程序中写成K0=0x00;否则编译器会提示“P0为未定义标识符”
使用方法:
sfr[variable]=[address]//为变量分配一个特殊功能寄存器。
1、等号右边,只能是十进制,十六进制整型的数据常量,不允许带操作符的表达式。
经典的8051内核支持的SFR地址从0x80H~0xFF飞利浦80C51MX系列0x180H~0x1FF
2、SFR不能声明于任何函数内部,包括main函数。
只能声明于函数外。
3、用SFR声明一个变量后,不能用取地址运算符&获取其地址,编译无法通过,编译器会提示非法操作。
4、有一点须特别注意,51内核0x80~0xff,为特殊功能寄存器地址区间,但并不是所有的地址都有定义,如果说你所用的MCU芯片上对于某个地址没有定义,那么用sfr在定义变量的时候,不要把变量的地址分配到未定义的特殊功能寄存器上,虽然编译时能通过,用KEIL仿真时貌似是没有问题,但下载到芯片里运行时,是会出问题的。
比如说,向一个未定义的特殊功能寄存器执行读操作,读出来的就是一个未知的数。
(读者可自行测试,先把串口通信调通,然后做一个简单的人机交互。
读出一个数后,再发给计算机,用串口调试助手或是串口监控查看。
这用方法在仿真的时候很有用。
)所以具体那些特殊功能寄存器能够用,就要查看你使用的芯片手册。
5、若遇到增强性的单片机,只要知道其扩展的特殊功能寄存器的地址,用SFR定
就可以很方便进行编程。
*************************************
sbit:
声明变量
sbit同样是声明一个变量,和SFR使用方法类似,但是SBIT是用来声明一个位变量,因为,在51系列的应用中,非常有必要对SFR的单个位进行存取,而通过bit数据类型,使其具备位寻址功能。
如,在reg52.h中有如下声明
sfrIE=0xA8;
sbitEA=IE^7;
sbitET2=IE^5;//8052only
sbitES=IE^4;
sbitET1=IE^3;
sbitEX1=IE^2;
sbitET0=IE^1;
sbitEX0=IE^0;
所以,对EA的操作即是对IE最高位的操作。
但如果想让SPDPLDPHPCONTMOCTL0TL1TH0TH1SBUF这些特殊功能寄存器具备位寻址,采用上述如IE类似的定义,是不行的,虽然修改后,在编译的时候不会出现错误,但只要用到你定义的位变量名时就会出错。
原因是,只有特殊功能寄存器的地址是8的倍数(十六进制以0或8结尾)才能进行位寻址。
打开reg52.h头文件可以看到,所有用sbit声明了的特殊功能寄存器的地址均是以0或8结尾
如硬要达到上述要求,可用带参的宏定义来完成。
此处不做详细说明(意义并不大)。
下面对sbit的使用做详细介绍:
随着8051的应用,非常有必要对特殊功能寄存器的单个bit位进行存取,C51编译器通过sbit数据类型,提供了对特殊功能寄存器的位操作。
以下是sbit的三种应用形式:
一,sbitname=sfr-name^bit-position;
sfrPSW=0xD0;
sfrIE=0xA8;
sbitOV=PSW^2;
sbitCY=PSW^7;
sbitEA=IE^7;
二,sbitname=sft-address^bit-position;
sbitOV=0xD0^2;
sbitCY=0xD0^7;
sbitEA=0xA8^7;
三,sbitname=sbit-address;
sbitOV=0xD2;
sbitCY=0xD7;
sbitEA=0xAF;
现对上述三种形式的声明做必要的说明
第一种形式sbitname=sfr-name^bit-position;如sbitOV=PSW^2;当中的这个特殊功能寄存器必须在此之前已经用sfr定义,否则编译会出错。
bit-position范围从0~7;
第二种形式sbitname=sft-address^bit-position如sbitOV=0xD0^2;与第一种形式不同之外在于,此处直接使用PSW的地址.第一种形式须先定义PSW
第三种形式.sbitname=sbit-address如sbitOV=0xD2是直接用的OV的地址
OV的地址计算方式,是OV所在的寄存器地址加上OV的bit-position
注意:
不是所有的SFR都可位寻址。
只有特殊功能寄存器的地址是8的倍数(十六进制以0或8结尾)才能进行位寻址,并且sbit声明的变量名,虽可以是任意取,但是最好不要以下划线开头,因为以下划线开头的都保留给了C51的头文件做保留字。
sfr16:
声明变量
许多8051的派生型单片机,用两个连续地址的特殊功能寄存器,来存储一个16bit的值。
例如,8052就用了0xCC和0xCD来保存定时/计数寄存器2的高字节和低字节。
编译器提供sfr16这种数据类型,来保存两个字节的数据。
虚拟出一个16bit的寄存器。
如下:
sfr16T2=0xCC
存储方面为小端存储方式,低字节在前,高字节在后。
定义时,只写低字节地址,如上,则定义T2为一个16位的特殊功能寄存器。
T2L=0CCh,T2H=0CDh
使用方法:
sfr[variable]=[low_address]
1等号右边,只写两个特殊功能寄存器的低地址,且只能是十进制,十六进制的整型数据常量,不允许带操作符的表达式
2SFR不能声明于任何函数内部,包括main函数。
只能声明于函数外。
3用SFR声明一个变量后,不能用取地址运算符&获取其地址,编译无法通过,编译器会提示非法操作。
4当你向一个sfr16写入数据的时候,KEILCX51编译器生成的代码,是先写高字节,后写低字节,(可通过返汇编窗口查看)在有些情况下,这并非我们所想要的操作顺序。
使用时,须注意。
5当你所要写入sfr16的数据,当是高字节先写还是低字节先写非常重要的时候,就只能用sfr这个关键字来定义,并且任意时刻只保存一个字节,这样操作才能保证写入正确。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
C51常用头文件
在KEIL中,对于单片机所使用的头文件,除了reg51reg52以外,还有一些从各芯片制商的官网下载与reg51,reg52功能类似的头文件,需了解透外,还要对各类型单片机均可通用且相当有用的的头文件,做相应的了解。
因为,内部所包含的函数与宏定义,可以及大的方便我们编写应用程序。
1字符函数ctype.h
1externbitisalpha(char);
功能:
检查参数字符是否为英文字母,是则返回1
2externbitisalnum(char)
功能:
检查字符是否为英文字母或数字字符,是则返回1
3externbitiscntrl(char)
功能:
检查参数值是否在0x00~0x1f之间或等于0x7f,是则返回1
4externbitisdigit(char)
功能:
检查参数是否为数字字符,是则返回1
5externbitisgraph(char)
功能:
检查参数值是否为可打印字符,是则返回1,可打印字符为0x21~0x7e
6externbitisprint(char)
功能:
除了与isgraph相同之外,还接受空格符0x20
7externbitispunct(char)
功能:
不做介绍。
8externbitislower(char)
功能:
检查参数字符的值是否为小写英文字母,是则返回1
9externbitisupper(char)
功能:
检查参数字符的值是否为大写英文字母,是则返回1
10externbitisspace(char)
功能:
检查字符是否为下列之一,空格,制表符,回车,换行,垂直制表符和送纸。
如果为真则返回1
11externbitisxdigit(char)
功能:
检查参数字符是否为16进制数字字符,是则返回1
12externchartoint(char)
功能:
将ASCII字符0~9a~f(大小写无关)转换成对应的16进制数字,
返回值00H~0FH
13externchartolower(char)
功能:
将大写字符转换成小写形式,如字符变量不在A~Z之间,则不作转换而直接返回该字符
14externchartoupper(char)
功能:
将小写字符转换成大写形式,如字符变量不在a~z之间,则不作转换而直接返回该字符
15definetoascii(c)((c)&0x7f)
功能:
该宏将任何整形数值缩小到有效的ASCII范围之内,它将变量和0x7f相与从而去掉第7位以上的所有数位
16#definetolower(c)(c-‘A’+’a’)
功能:
该宏将字符与常数0x20逐位相或
17#definetoupper(c)((c)-‘a’+’A’)
功能:
该宏将字符与常数0xdf逐位相与
2数学函数math.h
externintabs(intval);
externcharcabs(charval);
externlonglabs(longval);
externfloatfabs(floatval);
功能:
返回绝对值。
上面四个函数,除了形参和返回值不一样之外,
其它功能完全相同。
externfloatexp(floatval);
externfloatlog(floatval);
externfloatlog10(floatval);
功能:
exp返回eval
log返回val的自然对数
log10返回以10为底,val的对数
externfloatsqrt(floatval);
功能:
返回val的正平方根
externintrand();
externvoidsrand(intn);
功能:
rand返回一个0到32767之间的伪随机数,srand用来将随机数发生器初始化成一个已知的(期望)值。
KeiluVision3中的math.h库中,不包含此函数。
externfloatsin(floatval);
externfloatcos(floatval);
externfloattan(floatval);
功能:
返回val的正弦,余弦,正切值。
val为弧度fabs(var)<=65535
externfloatasin(floatval);
externfloatacos(floatval);
externfloatatan(floatval);
externfloatatan2(floaty,floatx);
功能:
asin返回val的反正弦值。
acos返回val的反余弦值。
atan返回val的反正切值。
asinatanacos的值域均为-π/2~+π/2
atan2返回x/y,的反正切值,其值域为-π~+π
externfloatsinh(floatval);
externfloatcosh(floatval);
externfloattanh(floatval);
功能:
cosh返回var的双曲余弦值,sinh返回var的双曲正弦值,
tanh返回var的双曲正切值。
externfloatceil(floatval);
功能:
向上取整,返回一个大于val的最小整数。
externfloatfloor(floatval);
功能:
向下取整,返回一个小于val的最大整数。
externfloatpow(floatx,floaty);
功能:
计算计算xy的值。
当(x=0,y<=0)或(x<0.y不是整数)时会发生错误。
externvoidfpsave(structFPBUF*p)
externvoidfprestore(structFPBUF*p)
功能:
fpsave保存浮点了程序的状态,fprestore恢复浮点子程序的原始状态,当中断程序中需要执行浮点运算时,这两个函数是很有用的。
注:
KeiluVision3中的math.h库中,不包含此函数。
3绝对地址访问absacc.h
#defineCBYTE((unsignedcharvolatilecode*)0)
#defineDBYTE((unsignedcharvolatiledata*)0)
#definePBYTE((unsignedcharvolatilepdata*)0)
#defineXBYTE((unsignedcharvolatilexdata*)0)
功能:
CBYTE寻址CODE区
DBYTE寻址DATA区
PBYTE寻址XDATA(低256)区
XBYTE寻址XDATA区
例:
如下指令在对外部存储器区域访问地址0x1000
xvar=XBYTE[0x1000];
XBYTE[0x1000]=20;
#defineCWORD((unsignedintvolatilecode*)0)
#defineDWORD((unsignedintvolatiledata*)0)
#definePWORD((unsignedintvolatilepdata*)0)
#defineXWORD((unsignedintvolatilexdata*)0)
功能:
与前面的一个宏相似,只是它们指定的数据类型为unsignedint.。
通过灵活运用不同的数据类型,所有的8051地址空间都是可以进行访问。
如
DWORD[0x0004]=0x12F8;
即内部数据存储器中(0x08)=0x12;(0x09)=0xF8
4内部函数intrins.h
externunsignedchar_cror_(unsignedcharvar,unsignedcharn);
externunsignedint_iror_(unsignedintvar,unsignedcharn);
externunsignedlong_lror_(unsignedlongvar,unsignedcharn);
功能:
将变量var循环右移n位。
上三个函数的区别在于,参数及返回值的类型不同
externunsignedchar_crol_(unsignedcharvar,unsignedcharn);
externunsignedint_irol_(unsignedintvar,unsignedcharn);
externunsignedlong_lrol_(unsignedlongvar,unsignedcharn);
功能:
将变量var循环左移n位。
上三个函数的区别在于,参数及返回值的类型不同
例如:
#include
voidmain()
{
unsignedinty;
y=0x0ff0;
y=_irol_(y,4);//y=0xff00
y=_iror_(y,4);//y=0x0ff0
}
void_nop_(void);
功能:
_nop_产生一个8051单片机的NOP指令,C51编译器在程序调用_nop_函数的地方,直接产生一条NOP指令。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 语言 文件