历史上的今天
返回首页

历史上的今天

今天是:2025年01月05日(星期日)

正在发生

2018年01月05日 | C51中断应用interrupt 和 using

2018-01-05 来源:eefocus

8051 系列 MCU 的基本结构包括:32 个 I/O 口(4 组8 bit 端口);两个16 位定时计数器;全双工串行通信;5个中断源(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,选中“Don't use absolute register aCCesses”,使所有代码均不使用绝对寄存器寻址方式(这样,执行效率将稍有降低)。不论以上的哪一种情况,编译器均会给出重入警告,需手工更改 OVERLAY 参数,做重入说明。 
3、还有一种办法:如果被调用函数的代码不是很长,还是将该函数复制一份,用不同的函数名代替,这种情况适合ROM有足够多余的空间。 
因此,对using关键字的使用,如果没把握,宁可不用,交给编译系统自己去处理好了。

推荐阅读

史海拾趣

Herga公司的发展小趣事

近年来,Herga公司紧跟智能制造的发展趋势,大力推动生产线的自动化和智能化升级。公司引入了先进的机器人、自动化设备和智能管理系统,实现了从原材料采购、生产加工到成品检验的全流程自动化控制。这一举措不仅大大提高了生产效率和质量稳定性,还降低了人力成本和运营风险。Herga公司的智能制造实践为电子行业树立了典范,也为公司的持续发展注入了新的动力。

Brilliance公司的发展小趣事

Brilliance公司起源于科技创新的热潮之中,由一群充满激情的电子工程师和创业者共同创立。公司成立之初,便致力于研发具有创新性和实用性的电子产品。通过不断的技术攻关和市场调研,Brilliance成功推出了一系列受到消费者欢迎的产品,逐步在电子行业中崭露头角。

Fong Ya Enterprise Co Ltd公司的发展小趣事

在快速发展的同时,Brilliance公司始终关注社会责任和可持续发展。公司积极参与公益事业,为社会做出贡献。同时,公司还注重环保和节能减排,努力降低生产过程中的环境影响。这种积极履行社会责任的态度也赢得了社会各界的广泛认可。

通过以上五个故事,我们可以看到Brilliance公司在电子行业发展中的艰辛与辉煌。凭借技术创新、市场拓展、产业链整合以及社会责任等方面的努力,Brilliance成功地在电子行业中树立了自己的品牌形象,并为未来的发展奠定了坚实的基础。

台湾富晶(FORTUNE)公司的发展小趣事
使用滤波器或隔离器等设备隔离输入信号的干扰。
高通(GENITOP)公司的发展小趣事

随着全球市场的不断拓展,超霸电池的销售网络遍布亚洲、欧洲和北美等多个国家和地区。公司始终坚持绿色环保的生产理念,研发出无汞无镉的电池产品,可随生活垃圾丢弃而不会对环境造成影响。此外,超霸电池还积极参与环保事业,旗下多家工厂获得了UL美国安全试验所废弃物零填埋认证。这些举措不仅彰显了超霸电池的社会责任感,也为其在国际市场上树立了良好的品牌形象。

国产公司的发展小趣事
如电阻的热噪声、晶体管的散粒噪声等。选择低噪声的元器件可以在一定程度上抑制噪声。

问答坊 | AI 解惑

【转帖】飞凌2010人才招聘信息——希望对大家有帮助

飞凌2010人才招聘信息 嵌入式系统硬件研发工程师职位 岗位职责:           1、负责嵌入式系统硬件开发工作;     2、负责ARM相关产品的硬件开发工作;     3、负责定制型项目的硬件开 ...…

查看全部问答>

有没有人用SJF2440烧录过K9F4G08\K9F8G08的弟兄?

好像没有发现现成的支持烧录K9F4G08\\K9F8G08的SJF2440 ?哪位弟兄能提供一下 ?多谢!…

查看全部问答>

安装了Sfilter,怎么看不到调试语句输出呢?

DDK里面的Sfilter例子。编译出sfilter.sys,用里面自带的inf文件安装,重启了。但是用windbg看不到调试语句输出。 怎么回事? …

查看全部问答>

tchar字符串转换为十进制的方法

请教一个问题: 在WinCE环境下,使用eVC编程 定义了2个字节的数据 TCHAR buf1[3]=_T(\"7A\"); SetDlgItemText(IDC_EDIT3,buf1); 显示的ASCII 现在我想用十进制显示出来,怎么转换呢?…

查看全部问答>

基于UCC28019的高功率因数电源设计

      构建有源功率因数校正(APFC)的高功率因数直流电源。该系统采用TI公司专用APFC整流控制芯片UCC28019作为控制核心,构成电压外环和电流内环的双环控制。其中内环电流环作用是使网侧交流输入电流跟踪电网电压的波形与 ...…

查看全部问答>

伺服电机的测速方法介绍.

伺服电机的测速方法介绍.…

查看全部问答>

LED应用-TPS7510x & C2000

本帖最后由 dontium 于 2015-1-23 13:13 编辑 LED应用手册 TPS7510x & C2000   LDO 白光 LED 驱动器 TPS7510x 提供令人难以置信的小型解决方案 C2000 LED 照明开发者套件 超实用的,快来下载啊~~~ …

查看全部问答>

MSP430里的标志位定义方法

MSP430里没有位定义 可下面结构体定义来代替 struct flag_inf{              unsigned doc:1;        unsigned m:1;        unsigned up:1;     ...…

查看全部问答>

LVPECL问题

有个问题,请教大家,如果有个LVPECL的信号Q和Q把,怎么输入到FPGA中去啊?作为外部时钟输入。在管脚分配的时候,选LVPECL外,里面代友怎么写?要描述下,Q和Q把 的逻辑关系就好了?还是要怎么样的?困惑中。…

查看全部问答>