大家都知道51单片机有的寄存器R0-R7共有四组。很多朋友对寄存器组的使用时经常出现问题。虽然这并不是多难的问题,但如果出现错误,也会造成很严重的后果。
首先介绍一下51的寄存器组:
通过设置PSW寄存器的第3位和第4位可以任意切换寄存器组。在进入中断前,切换寄存器组,可以方便的保护原寄存器组的数据不被中断里的语句破坏,很方便。
RS1 RS0 字节地址
0 0 0组寄存器 00H~07H
0 1 1组寄存器 08H~0FH
1 0 2组寄存器 10H~17H
1 1 3组寄存器 18H~1FH
RS1=PSW.4 RS0=PSW.3
常见错误有三种:
1、为中断函数指定了第0组寄存器
C程序: void int0() interrupt 0 using 0
编译后的汇编如下:
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
MOV PSW,#0x00
。。。。。。
因为main()函数使用的就是第0组寄存器,中断程序会改变寄存器组的数据。主程序运行时,随时都有可能产生中断,等中断返回主程序时,寄存器R0-R7的值已经被改变了。这是非常严重的错误。而且故障时有时无,错误也是莫明其妙。
2、中断优先级不同,寄存器组号相同
C程序: void int0() interrupt 0 using 1 //低优先级中断
void T0() interrupt 1 using 1 //高优先级中断
因为高优先级的中断可以打断正在执行的低级中断,转向持行高级中断。这就是所谓的中断的中断。与第1种错语一样,高级中断的程序,会改变低级中断正在使用的寄存器。
3、不写using 。严格的说,这样写不能算是错误。但这是相当不好的习惯。
C程序: void int0() interrupt 0
编译后的汇编如下:
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
MOV PSW,#0x00
PUSH 0x00
PUSH 0x01
PUSH 0x02
PUSH 0x03
PUSH 0x04
PUSH 0x05
PUSH 0x06
PUSH 0x07
。。。。。。
没用using指定寄存器组,编译器就默认分配了第0组寄存器,然后又用8条语句把第0组的R0-R7保存到栈中,退出中断时还需要8个弹栈。这样“笨拙”的写法,占用了程序空间32个字节、占有堆栈8个字节。也许高级版本的编译器会改进吧,搞单片机的还是规矩些好。
经验总结:
1、写中断程序一定要用using语句指定寄存器组。第1、2、3组都可以,不能是0.
2、51单片机的中断有两个优先级。一个中断不会打断另一个相同优先级的中断。这样相同级别中断可以使用同一个组。比如:低优先级的中断函数都用 using 1,高优先级的中断都用 using 2 。这样不会冲突。
下面是一个正常的例子:
C程序: void int0() interrupt 0 using 1
编译后的汇编如下:
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
MOV PSW,#0x08
。。。。。。
就是这么简单。虽然这点事儿对老鸟不算什么问题,但新手朋友犯此错误的可不少。我遇到的就不下15个了。今天我写这个贴子,也是为所有新手提个醒。到处救火不如防患于未燃。
关键字:单片机 寄存器组
引用地址:
单片机寄存器组注意重复使用原数据可能被覆盖危险
推荐阅读最新更新时间:2024-03-16 14:39
单片机I/O口管脚内部结构
学习ARM嵌入式的时候,发现自己对以前学过的数模器件的知识遗忘了不少,按照我的进度本来应该继续学习ARM微处理器控制的课程,但想着后来势必还会遇到相同的问题所以就准备中断一下,杀回来把汇编和一些电路知识再总结一下,查漏补缺。如果有写的不合理的地方,还请多多指教。 言归正传,先来一幅图片来引入今天要讲述的三个知识点: 锁存器(由一个D触发器构成) D:数据输入端; CP/CLK:时序信号输入端; Q:输出端; ~Q:反向输出端; 工作原理: 当D端输入数据信号,CP/CLK端没有时序信号时,Q和~Q端将不会有信号输出; 当D端输入数据信号,CP/CLK端有时序信号时,Q和~Q端有信号输出; 当D端和CP/CLK端同时有信号输入后
[单片机]
MCS-51单片机的算术运算指令解析
MCS-51具有强大的加、减、乘、除四则算术运算指令。 1.程序状态字PSW MCS-51有一个程序状态字寄存器PSW,用来保存指令执行结果的标志,供程序查讯和判别。PSW是特殊功能寄存器中的一个,其格式如下: PSW7--既是布尔处理机的累加器C,又是进位标志CY,如果操作结果在最高位有进位输出(加法时)或借位输入(减法时),置位CY,否则清“0”CY。 AC--辅助进位(半进位)标志。如果操作结果的低4位有进位(加法时)或向高4位借位时(减法),置AC,否则清“0”AC,AC主要用于二-十进制数加法调整。 OV--溢出标志。如果操作结果有进位进入最高位,但最高位没有产生进位,或者最高位产生进位而低位没有向最高位进位,这时置位溢
[单片机]
1602液晶测试程序2
程序共分为3个文件:1602-2.c、LCD1602.h、lcd1602define.h 1602-2.c /*单片机学习板V1.0 */ /*模块名 :LCD1602控制显示 */ /*创建人 :ClimberWin 日期:2009-03-26 */ /*功能描述:LCD1602显示 */ /*版本 :V1.0 */ /************************************************************/ #include reg51.h #include LCD1602.h
[单片机]
ESP8266 wifi模块与51单片机通信入门教程,模块出厂固件烧录
前段时间在某宝买了个ESP8266模块,用来实现和51单片机的通信,现在将大致过程分享一下,希望能帮助到那些想学习的小白 三部分内容:配置模块、模块与51单片机简单通信、出厂固件的烧录 附件里有pdf教程,跟帖子内容一样的,浏览体验可能会更好一点 我买的是8266-01,引脚图如下 引脚说明: • VCC接3.3v,接5v时间长了可能会烧 • UTXD,URXD和其它的TXD,RXD接时注意交叉接就行了 • CH_PD要给高电平模块才工作 • GPIO0一般不用管,烧录固件时要接地 • RST低电平复位,高电平工作(默认高) • GPIO2必须为高电平,内部默认已拉高,不用管
[单片机]
英飞凌新款8位、16位和32位微控制器产品
2009年3月13日,德国Neubiberg讯——英飞凌科技股份公司(FSE/NYSE:IFX)近日宣布推出内嵌闪存组件的新款微控制器(MCU)产品,包括面向多种工业应用的8位微控制器、16位微控制器系列,以及归属TriCore™ 32位产品系列的部分型号。所有这些微控制器解决方案,被设计用于满足多个行业众多驱动应用对性能和可靠性的要求,譬如泵机、风扇、安全自动控制系统、交通系统和白色家电的驱动装置。
英飞凌这次推出的微控制器包括8位XC864、8位XC886 HOT和16位XE162M系列、16位XE164M系列、16位XE167M系列和32位TC1167与TC1197等。此外,英飞凌的8位XC800
[单片机]
经典常用的单片机c程序
//16进制 - 10进制互换程序 unsigned char d ; //用于显示的10位显示缓存 //======================================================== //16进制to10进制输出子程序:显示数据,起始位,结束位,有无小数点 //======================================================== void output(unsigned long dd,unsigned char s,unsigned char e,unsigned char DIP ) { unsigned long div;
[单片机]
基于AVR单片机的LED显示屏的灰度设计与实现
LED点阵块具有亮度高、发光均匀、可靠性好、拼装方便等优点,能构成各种尺寸的显示屏。目前,LED显示屏已被广泛应用于文字显示并取得了很好的效果,但是大部分仅能显示滚动的文字信息而不能显示图像,并且还存在系统复杂等缺点。本文提出了一种主从式单片机的LED显示屏解决方案,该设计方案利用AVR单片机自身的FLASH ROM和RAM,外部无需任何存储电路,电路结构简单。该系统实现了图像的16阶灰度显示,可广泛用于商场、车站等公共场合。 1 AVR单片机简介 AVR单片机是增强型内置FLASH的RISC(ReducedInstruction Set CPU)精简指令集高速8位单片机,硬件采用哈佛(Harward)结
[工业控制]
用CP2200实现MCU的简易型以太网接口
引 言 当前,嵌入式设计人员在为远程控制或监控设备提供以太网接入时,使用的以太网控制器(如RTL8019、DM9008、CS8900A等)都是专为个人计算机系统设计的。这些器件不仅接口电路复杂,体积较大,而且比较昂贵。CP2200是Silabs公司于近期推出的一款48引脚独立以太网控制器。它符合IEEE 802.3协议,支持10M以太网接入,而且仅需很少的外部电路连线就可满足绝大多数嵌入式以太嗣接口的设计要求,简化了嵌入式以太网接口的设计,减小了占板空间,降低了系统开发成本。 另外,该以太网控制器具有8位并行主机接口,可以为绝大多数微控制器或主处理器提供以太网通信功能。8位并行总线接口支持Intel和Motorola总线方式,
[网络通信]