爱收集资源网

C51中断函数的几个注意事项,让你避开高手绕行

网络整理 2023-09-28 21:04

关于C51的中断函数要注意的几个问题(高手绕行)

最近在虾潭逛,发现一些小虾米对C51中断函数有些不了解,今天假期,抽空发个技术贴子,希望对小虾米有所帮助,如

有错误之处,还请见谅,就当抛砖引玉吧!

C51的中断函数的格式为:

void FuncIr(void) interrupt x [using y]

以下是梦游的一些剖析:

一、中断函数是一个特殊的函数,没有参数,也没有返回值;但是程序中允不容许使用return呢?答案是容许的,不过

只能用"return;",不能用"return(z);";用在一些须要快速返回的地方,对应的汇编会有多个ret句子,相对效率会初一

些。

二、using的用法,using可以修饰任何函数,不过个人建议只拿来修饰中断函数;简单的说,“using”会指定工作寄存

器组,由于中断函数通常都是比较紧急的事情,有时一条句子就会斤斤计较,所以使用using切换寄存器组可以省去一些压栈

的动作,由于51只有两级中断,同级中断不能被打断,因此,我们可以同级中断设成同样的寄存器组,从某种意义上来说,

有一组寄存器是多余的。同时个人建议中断函数应当使用using这个关键字。

三、中断中调用函数,首先要讨论中断函数中调用函数的必要性,前天在峰会上我和他人争辩过这个问题,现在我还是

这个观点:有些情况中断中调用函数还是必要的,这个时侯是不是该调用函数,其实和普通函数差不多,首先是这个函数如

果调用多次,或者要带一些参数哪些的就愈加必要的;前天有人跟我叫劲,说如果只调用一次且无参数无返回的函数要直接

写,因为假如用函数,至少会降低CALL和RET两条句子,我不敢苟同,我是实际调试发觉的,当你程序比较复杂时,你将那部

分单独拉下来弄成函数,可能代码和时间就会更好

四、中断中调用的函数最好不要被中断外的其它函数调用,因为会出现“重复调用”的警告,有时这些调用是很致命

的,有人说这个函数可以用reentrant来修饰,是的,的确可以这样解决,不过个人不建议如此做,也许这样会跟你降低好多

堆栈空间,并且整个程序的优化要差好多,个人建议出现此类情况就把这个函数写两遍,分成两个函数分别调用。

五,中断调用了函数,会出现一些莫名其妙的问题,一些数据不对。其实通常是因为汇编中使用了绝对寄存器造成的,有人说中断函数使用哪个寄存器组,被中断调用的

函数就使用那个寄存器组,我觉得这样不好:

这样会降低额外的消耗,使用using会降低一下句子:

PUSH PSW

MOV PSW, #XX

....

POP PSW

更重要的是,使用using的函数不能有返回值,这是致命伤

个人推荐的方式有两种:

1、使用“#pragma NOAREGS”禁止使用绝对寄存器

2、使用“#pragme RB(x)”来指定本文件的工作寄存器组

六、一般说来,要求中断函数尽可能的短,但也有特殊情况,有些前/后台的系统中,就会把好多相对重要的事情放在定

时中断(这个定时中断类似实时操作系统中的时钟节拍)去做,而且程序很长。我单独提下来这点是想告诉你们,中断函数

也是一个函数而已,只要系统有必要,可以做一些看似不合理的事情,该出手时就出手,就像goto句子一样。

51单片机的中断函数

中断使用interrupt 关键字和中断编号0-4来实现:

返回值 函数名 interrupt n

n对应中断源的编号,中断编号告诉中断器中断程序的入口地址,它对应着IE寄存器中的使能位,即IE寄存器中的0位对应着外部中断0。

8051单片机的中断源以及终端编号如下:

中断编号 中断源 入口地址

0 外部中断0 0003H

1 定时器/计数器0 溢出 000BH

2 外部中断1 0013H

3 定时器/计数器1 溢出 001BH

4 串行口中断 0023H

在51系列单片机中,有的单片机多达32个中断源,所以中断编号是0-31.

当正在执行一个特定的任务时,可能有更紧急的事情须要CPU处理,这就涉及到了中断优先级。高优先级中断可以中断正在处理的低优先级中断程序,因而最好给每种优先级程序分配不同的寄存器组。在C51中可使用using指定寄存器组,using后的变量为0-3的常整数,分别表示51单片机内的4哥寄存器组。中断函数的完整句型如下:

返回值 函数名([参数])[模式][重入]interrupt n[usingn]

unsigned int interruptcnt;

unsigned char second;

void timer0(void) interrupt 1 using 2

if(++interruptcnt==4000) // 计数到4000

second++; //另一个计数器

interruptcnt=0; //计数器清零

中断函数可重入是什么
上一篇:快速找回微信聊天记录的绝招 下一篇:没有了
相关文章