8051 系列 MCU 的根本结构包含:32 个 I/O 口(4 组8 bit 端口);两个16 位守时计数器;全双工串行通讯;6 个中止源(2 个外部中止、2 个守时/计数器中止、1 个串口输入/输出中止),两级中止优先级;128 字节内置RAM;独立的 64K 字节可寻址数据和代码区。中止产生后,MCU 转到 5 个中止进口处之一,然后履行相应的中止服务
处理程序。中止程序的进口地址被编译器放在中止向量中,中止向量坐落程序代码段的最低地址处,留意这儿的串口输入/输出中止共用一个中止向量。8051的中止向量表如下:
中止源 中止向量
—————————
上电复位 0000H
外部中止0 0003H
守时器0 溢出 000BH
外部中止1 0013H
守时器1 溢出 001BH
串行口中止 0023H
守时器2 溢出 002BH
interrupt 和 using 都是 C51 的关键字。C51 中止进程经过运用 interrupt 关键字和中止号(0 到 31)来完成。中止号指明编译器中止程序的进口地址中止序号对应着 8051中止使能寄存器IE 中的使能位,对应联系如下:
IE寄存器 C51中的 8051的
的使能位 中止号 中止源
——————————–
IE.0 0 外部中止0
IE.1 1 守时器0 溢出
IE.2 2 外部中止1
IE.3 3 守时器1 溢出
IE.4 4 串口中止
IE.5 5 守时器2 溢出
有了这一声明,编译器不需理睬寄存器组参数的运用和对累加器A、状况寄存器、寄存器B、数据指针和默许的寄存器的维护。只要在中止程序中用到,编译器会把它们压栈,在中止程序结束时将他们出栈。C51 支撑一切 5 个 8051 规范中止从 0 到 4 和在 8051 系列(增强型)中多达 27 个中止源。
using 关键字用来指定中止服务程序运用的寄存器组。用法是:using 后跟一个0 到3 的数,对应着 4 组作业寄存器。一旦指定作业寄存器组,默许的作业寄存器组就不会被压栈,这将节约 32 个处理周期,由于入栈和出栈都需求 2 个处理周期。这一做法的缺陷是一切调用中止的进程都有必要运用指定的同一个寄存器组,不然参数传递会产生过错。因而关于using,在运用中需灵敏取舍。
关于using:
您在文中阐明“这一做法的缺陷是一切调用中止的进程都有必要运用指定的同一个寄存器组”是不是这个意思?
举个比如来说:
界说一个函数
void func(unsigned char i) {
…
if(++i==0x12) {
…
}
…
}
有如下一个中止函数
void int_0(void) interrupt 0 using 1 {
….
}
在默许状况下,func运用寄存器组0(BANK0),那么当int_0调用func时是否存在当传递参数时会形成参数传递过错?
谢谢!
假如在中止服务函数 ISR 中运用寄存器,那么有必要处理好 using 的运用问题:
1、中止服务函数运用 using 指定与主函数不同的寄存器组(主函数一般运用 Register bank 0)。
2、中止优先级相同的ISR 可用 using 指定相同的寄存器组,但优先级不同的 ISR 有必要运用不同的寄存器组,在 ISR 中被调用的函数也要运用 using 指定与中止函数相同的寄存器组。
3、假如不必 using 指定,在 ISR 的进口,C51 默许挑选寄存器组0,这相当于中止服务程序的进口首要履行指令:
MOV PSW #0
这点确保了,没运用 using 指定的高优先级中止。能够中止运用不同的寄存器组的低优先级中止。
4、运用 using 关键字给中止指定寄存器组,这样直接切换寄存器组而不必进行很多的 PUSH 和 POP 操作,能够节约RAM空间,加快 MCU 履行时间。寄存器组的切换,总的来说比较简单犯错,要对内存的运用状况有比较明晰的知道,其正确性要由你自己来确保。特别在程序中有直接地址拜访的时分,一定要小心翼翼!至于“什么时分要用到寄存器组切换”,一种状况是:当你企图让两个(或以上)作业一起运转,并且它们的现场需求一些阻隔的时分,就会用上了。在 ISR 或运用实时操作体系 RTOS 中,寄存器十分有用。
寄存器组运用的准则:
1、8051 的最低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 0,ISR 运用 using 指定了其他 BANK),则被调用函数有必要放在:
#pragma NOAREGS
#pragma AREGS
操控参数对中,指定编译器不要对该函数运用肯定寄存器寻址方法;或许也可在 Options->C51,选中“Dont use absolute register accesses”,使一切代码均不运用肯定寄存器寻址方法(这样,履行功率将稍有下降)。不管以上的哪一种状况,编译器均会给出重入正告,需手艺更改 OVERLAY 参数,做重入阐明。
3、还有一种方法:假如被调用函数的代码不是很长,仍是将该函数仿制一份,用不同的函数名替代,这种状况合适ROM有满足剩余的空间。
因而,对using关键字的运用,假如没把握,宁可不必,交给编译体系自己去向理好了。