今天是: <%response.write formatdatetime(date(),1)%> 电子制作天地网站欢迎您的光临,欢迎提出宝贵意见或建议。本站信息产业部备案: 粤ICP备05114582号
 
C51单片机中断及寄存器使用的总结
单片机寄存器总结

时间:2013-5-19 20:06:40 来源:互联网 作者:不详 编辑: 【关闭


如果在中断服务函数 ISR 中使用寄存器,那么必须处理好 using 的使用问题:
1、中断服务函数使用 using 指定与主函数不同的寄存器组(主函数一般使用 Register bank 0)。
2、中断优先级相同的ISR 可用 using 指定相同的寄存器组,但优先级不同的 ISR 必须使用不同的寄存器组,在 ISR 中被调用的函数也要使用 using 指定与中断函数相同的寄存器组。用reentranr指明可重入函数。
3、如果不用 using 指定,在 ISR 的入口,C51 默认选择寄存器组0,这相当于中断服务程序的入口首先执行指令:
MOV PSW #0
这点保证了,没使用 using 指定的高优先级中断。可以中断使用不同的寄存器组的低优先级中断。
4、使用 using 关键字给中断指定寄存器组,这样直接切换寄存器组而不必进行大量的 PUSH  POP 操作,可以节省RAM空间,加速 MCU 执行时间。寄存器组的切换,总的来说比较容易出错,要对内存的使用情况有比较清晰的认识,其正确性要由你自己来保证。特别在程序中有直接地址访问的时候,一定要小心谨慎!至于什么时候要用到寄存器组切换,一种情况是:当你试图让两个(或以上)作业同时运行,而且它们的现场需要一些隔离的时候,就会用上了。在 ISR 或使用实时操作系统 RTOS 中,寄存器非常有用。

寄存器组使用的原则:
18051 的最低32 个字节分成 4  8 寄存器。分别为寄存器R0 R7。寄存器组由PSW 的低两位选择。在 ISR 中,MCU 可以切换到一个不同的寄存器组。对寄存器组的访问不可位寻址,C51 编译器规定使用using  禁止中断的函数(#pragma disable )均不能返回 bit 类型的值。
2、主程序(main函数)使用一组,如 bank 0;低中断优先级的所有中断均使用第二组,如 bank 1;高中断优先级的所有中断均使用再另外一组,如 bank 2。显然,同级别的中断使用同一组寄存器不会有问题,因为不会发生中断嵌套;而高优先级的中断则要使用与低优先级中断不同的一组,因为有可能出现在低优先级中断中发生高优先级中断的情况。编译器会自动判断何时可使用绝对寄存器存取。
3、在 ISR 中调用其它函数,必须和中断使用相同的寄存器组。当没用 NOAREGS 命令做明确的声明,编译器将使用绝对寄存器寻址方式访问函数选定(即用 using  REGISTERBANK 指定)的寄存器组,当函数假定的和实际所选的寄存器组不同时,将产生不可预知的结果,从而可能出现参数传递错误,返回值可能会在错误的寄存器组中。
举一例子:当需要在中断内和中断外调用同一个函数,假定按照程序的流程控制,不会出现函数的递归调用现象,这样的调用会不会出现问题?若确定不会发生重入情况,则有以下两种情况:
1、如果 ISR 和主程序使用同一寄存器组(主程序缺省使用BANK 0,若 ISR 没有使用 using 为其指定寄存器区,则缺省也使用 BANK 0),则不需其他设置。
2、如果 ISR 和主程序使用不同的寄存器组(主程序缺省使用BANK 0ISR 使用 using 指定了其他BANK),则被调用函数必须放在:
#pragma NOAREGS
#pragma AREGS
控制参数对中,指定编译器不要对该函数使用绝对寄存器寻址方式;或者也可在 Options->C51,选中“Dont use absolute register accesses”,使所有代码均不使用绝对寄存器寻址方式(这样,执行效率将稍有降低)。不论以上的哪一种情况,编译器均会给出重入警告,需手工更改 OVERLAY 参数,做重入说明。
3、还有一种办法:如果被调用函数的代码不是很长,还是将该函数复制一份,用不同的函数名代替,这种情况适合ROM有足够多余的空间。
因此,对using关键字的使用,如果没把握,宁可不用,交给编译系统自己去处理好了。

#pragma disable
在函数前声明,只对一个函数有用,该函数调用过程中,将不可被中断。

递归或可重入函数指定


在主程序和中断程序都调用的函数容易出现问题,用寄存器传递参数,内部变量在RAM中,函数重入时候,会破坏上次的数据,用下面两种方法解决函数重入问题:
在相应的函数前,加“#pramga disable”声明,只允许主程序或者中断之一调用该函数;
将该函数说明为可重入:VOID func(para..) reentrant;

指定存储模式
small compact large 说明,例如:
void fun1(void) small { }
提示:small 说明的函数内部变量全部使用内部RAM。关键的经常性的耗时的
地方可以这样声明,以提高运行速度。

◆相关文章◆
◆ 编辑推荐 ◆
用户:
更多评论
您要为您所发的言论的后果负责,故请各位遵纪守法并注意语言文明。60个字以内
留言:
验证码:
 
 
 

免责声明:
●本站所有内容均来自网络,以学习为目的,如果侵犯了您的利益,请来信告知,立即删除,站长邮件为"diy+dzdiy.com",请将"+"变更为"@"
●电子制作存在风险,请注意人身安全,如果您在根据本站电路进行制作过程中发生伤害,本站不负任何责任。

版权所有:www.dzdiy.com © 2001-2019 本站信息产业部备案: 粤ICP备05114582号