分享

单片机 C51 编程要点总结

 媛糖儿 2017-02-25

广告

1、头文件:#include (我用的是 STC 89C54RD )

2、预定义:sbit LED = P1^0  // 定义 P1 口的 0 位为 LED  

注:“P1^0”这个写法,与 A51 不同(A51 是 P1.0),P1 是一组端口,端口号范围 0~7

注2:sbit 用于定义 SFR(特殊功能寄存器)的位变量,上例中 LED 作为“全局变量”进行定义

注3:以下写法是错误的:


sbit code table[ ] = {P1^0, P1^1, P1^2, P1^3};  // 想用 table[i] 指定不同的引脚,但这么做会报错


sbit table[ ] = {P1^0, P1^1, P1^2, P1^3};            // 考虑到上面可能是 code 关键字使用错误,使用标准 C 数组写法,但这同样是错的


3、主函数写法:void main (void)

4、数值的表示:


P1 = 1111 1111       // 二进制

P1 = 0xff 或者 P1 = 0xFF   // 十六进制,0x 开头,且数值不分大小写

P1 = 255          // 十进制


5、定义小数值时,可以使用 unsigned char i,这样 i 的范围为 0~255,作为循环变量比较好用

6、左右移位:


P1 <<= 2 等价于 P1 = P1 << 2  // P1 左移 2 位,左移一位相当于乘以 2

P1 >>= 3 等价于 P1 = P1 >> 3  // P1 右移 3 位,右移一位相当于除以 2


注:左右移位默认为“逻辑移位”,即无论左移还是右移,空位都补 0


7、按位与或:

P1 = P1 & 0x01

P1 = P1 | 0x01

8、定义 ROM 表格(就是数据为常量的数组):


unsigned char code table[ ] = {0xff, 0xff, 0xff, 0xff};


使用:P1 = table[i]


注:table[ ] 定义为“全局变量”,上例中 i 的范围为 0~3


注2:code 定义的常量存于“代码区”,即 ROM 区,可以节省 RAM 空间


9、在使用数码管编程时,假如你正在使用 temp[i] 代表某一个显示字符,突然想显示小数点,可以使用 temp[i] | 0x80,通过“或”运算实现加上小数点……


10、如果你用 Keil C51 进行编译,记住一点:它不区分大小写!!!卧槽,今天编程序那个调错啊,就因为一个数组名和一个变量名完全一样,只是大小写不一样罢了,标准 C 我怎么记得这样可以啊……上网一查,卧槽,Keil C51 不区分大小写,准确的说是“连接的时候不区分大小写”,更准确一点就是“具有外部连接的变量区分大小写,内部连接 static 区分大小写”……至少 Keil uVision2 是这样,不知道别的版本是不是,待验证……


11、没有 unsigned float x !float 型变量从来没有前边加 unsigned 的语法!


12、Keil 编译的程序,main 函数执行完不会停止,会循环执行 main 函数,何解?


结论 1:如果主程序中没有 while(1) 这个无限循环,程序走到最后会再次从头开始执行。

结论 2:如果主程序有 while(1) 这个无限循环,程序走到最后会一直在这个死循环中运行,不会出现再从头执行的情况。


这应该属于 Keil 编译器的 bug,有网友做过实验,表示 Keil 编译后期产生的汇编代码中,结尾有一条 LJMP main,意思就是跳到 main 函数重复执行……还有一种说法是 PC 指针溢出,溢出后的地址指向开头,造成继续执行的效果……(博主觉得还是 Keil 的问题,要是 Keil 编译器不产生 LJMP main 这种语句,也不会产生循环效应……)


不管怎么说,在程序结尾加上 while(1) 能够解决循环执行 main 函数的 bug……

广告

关于立创商城

立创商城(WWW.SZLCSC.COM)是嘉立创集团旗下一家品种齐全、自营库存、质量有保障的电子元器件垂直商城,自建6000多平米现代化元器件仓库,现货库存超35000种。立创商城所有元器件均由原厂或代理商正规渠道采购,保证原装正品。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多