您的位置:首页 > 其它

学习心得之keil C51

2012-02-20 19:50 489 查看
上篇有提到不同的硬件平台用到的C语言也不尽相同,现详细讲讲,MSC51系列单片机的C语言特点。

相对于通用C语言,C51增加了:sfr,sfr16,sbit,bit等共4种数据类型。

1.sfr/sfr16

sfr/sfr16分别占用8位/16位的存储空间,专用于定义特殊功能寄存器如:sfr P0 = 0x80(地址值);

P0 = 0xff;(对p0每一位置1)

2.sbit

此类型占用一位的存储空间,专用于定义特殊功能寄存器的某位,此位必须是可位寻址的:sbit P0_1 = 0x91(位地址);或者sbit P0_1 = P0^1;

P0_1 = 1;(对p0的第一位置1)

或者定义某可位寻址字节变量的某位如:

char bdata pe;[在可位寻址空间开辟]

sbit pe_1 = pe ^1;

sbit pe_2=pe ^2;

3.bit

占用一位的存储空间,用于重新定义一个位变量,在可位寻址空间开辟。

bit flag;(flag是个位变量它的值只能是0或者1)

除此区别外,C51规定int,unsigned int,signed int为两字节;short int为1字节;char ,unsigned char,signed char为1字节;long ,unsigned long ,signed long为4字节。

另外,Keil C51还新增了bdata,idata,xdata,pdata,code,data等六种存储类型。

bdata定义的变量存储在内部ram的可位寻址区内(16B),可以用位直接寻址如MOV C,21H;

data定义的变量存储在前128B的内部ram中即直接寻址区内,直接访问方式:MOV A,80H;因为是直接寻址,因此访问速度最快,在使用ram空间时,最好先将可直接寻址的ram先用尽后,再去使用idata;

idata定义的变量存储在内部ram中,前128B的data区直接寻址,后128B(SFR可以直接寻址,整除8的地址的SFR还可位寻址,)用8位的地址寄存器R0/R1间接寻址方式:

MOV R0,#80H

MOV A,@R0;

pdata定义的变量存储在前256B的外部ram中,,00H~7F的空间,如idata的后128B一样使用间接寻址方式访问;

xdata定义的变量存储在64KB的外部ram中,用R0/R1访问pdata区:

用16位数据指针寄存器DPTR进行间接访问剩余区:0080H~FFFFH的外部空间:

MOV DPTR,#0108H

MOV A,@DPTR;

code定义的变量存储在内部64KB的rom中,rom和ram共用地址值,通过控制引脚来切换;

虽然定义标准C51有256Byte空间,可直接寻址128Byte,但是由于R0~R7寄存器组至少占用8字节,如果要进行寄存器组切换可能更多,因此能用的最大值为120字节;另外堆栈也需要占用空间,因此总共内部ram可用空间最多247字节。建议少用全局变量,因为它们会直接消耗内存,而局部变量使用的是寄存器,但是局部变量长时间使用过多编译器,无法进行优化,也会去使用ram空间,一旦ram耗尽就会内存溢出,总之,C51的RAM和ROM资源很有限,使用时要谨慎。

Keil C51还新增了interrupt/using/reentrant等三种关键字

1.interrupt

用法:函数+interrupt+中断号

用interrupt标志的函数,编译器会自动将此函数的地址生成中断向量,放置于中断向量表中,即内存最开始的1KB空间,那它放置在中断向量表的什么位置呢,通过中断号算出中断向量地址,不同的平台算法可能不一样,一种是中断号*4,即为中断向量的地址,如interrup 1则中断向量的地址为0x0004H,每个中断向量的地址占四个字节的空间,因此此中断向量存放在0x0004H~0x0007H的地址,同样每个中断号对应一个硬件的中断,当硬件中断触发时,就会自动跳入对应于该硬件中断号的相应的中断服务子程序中去。

2.using

用法:函数+interrupt+中断号+using+寄存器组

用using标志的函数,编译器不会将原来函数用的寄存器组(默认为0)R0到R7的值进行压栈保护,而只保存函数的返回的地址。因为用using表示此函数切换为另一组寄存器组来存数据,不会覆盖原来函数寄存器组的值,因此不需将原寄存器组压栈保护。正因为少了大量的压栈出栈的动作,才节省时间。但是如果没有完全掌握using的用法就会出现一些问题,比如在使用了using的中断中调用主程序中调用的函数,如果处理不当就会导致函数传参错误,因此需要用到伪指令操作。

#pragma NOAREGS

定义函数

#pragma AREGS

这样将寄存器绝对寻址方式改为间接寻址方式,使函数不依赖于寄存器

另外同一优先级别的中断时不用using 互相没有影响,但是不同优先级的中断必须使用不同的寄存器组,因为低优先级的中断会被高优先级的打段。

3.reentrant

用法:函数+reentrant

C51的ram资源比较少,因此系统将每个函数每次调用时设定为指定大小的栈空间,这样使得普通函数无法进行递归调用,也无法在主函数中和中断中同时被调用,因此,在函数后面加上reentrant关键字,编译器会使此函数每次调用的栈相互独立,即使该函数可重入。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: