C51中断处理过程
- 格式:doc
- 大小:20.50 KB
- 文档页数:4
c51串行中断的概念-回复什么是c51串行中断?C51是英特尔公司推出的一款基于MCS-51架构的单片机。
它的串行中断是指在C51单片机中通过串行通信接口实现的中断功能。
串行中断允许在数据传输过程中,当预设条件满足时,系统能够主动中断当前的任务,转而处理其他更加紧急或重要的任务。
串行中断在提高系统的实时性、可靠性和灵活性方面具有重要的作用。
那么,具体来看,C51串行中断是如何工作的呢?串行中断的工作原理可以简单概括为:当串行数据传输接口发生某种事态时,如数据传输完成、数据接收完成、传输错误等,C51单片机会在此时产生中断信号,引发一系列的中断处理操作。
具体实现串行中断的过程如下:1. 配置串行通信接口首先,需要在C51单片机中进行串行通信接口的配置。
这通常包括设置波特率、数据位、停止位等参数,以确保数据的正确传输和解析。
2. 中断向量表的设置C51单片机中的中断向量表记录了各个中断服务程序的入口地址。
在串行中断的情况下,需要设置相应的中断向量表,以在发生中断时,能够跳转到对应中断服务程序的入口地址。
3. 中断触发条件的编程设置运行中的C51单片机会不断监测串行通信接口的状态,以判断是否发生中断触发条件。
在串行中断的情况下,可以通过设置相应的寄存器位,来指定触发中断的条件。
例如,当串口接收缓冲区非空时,触发中断。
4. 保存现场并切换中断服务程序当满足中断触发条件时,C51单片机会立即中断当前任务,并将相关的寄存器值保存在栈中,以备后续恢复现场使用。
接着,C51单片机会跳转至设置中断向量表中该中断的入口地址,执行中断服务程序。
5. 执行中断服务程序中断服务程序是中断处理的核心部分,用于处理中断事件。
在串行中断的情况下,中断服务程序通常包括数据的接收与发送、错误处理、状态更新等功能。
一旦中断事件得到处理,C51单片机将恢复先前的现场,并返回到原先被中断的任务继续执行。
除了以上的基本过程外,C51串行中断还可以根据需求进行各种扩展和优化。
)/INT0)的溢出中断请求(TF0,它们设置在特殊IT0:外部中断0触发方式控制位。
当IT0=0时,为电平触发方式(低电平有效)。
当IT0=1时,为边沿触发方式(下降沿有效)。
IE0:外部中断0中断请求标志位。
(IE0=1,外部中断0向CPU申请中断)IT1:外部中断1触发方式控制位。
IE1:外部中断1中断请求标志位。
串行口控制寄存器SCON中的低两位用作串行接口中断标志位,其中:RI(SCON.0),串行口接收中断标志位。
当允许串行口接收数据时,每接收完一个串行帧,由硬件置位RI。
CPU响应中断时,不能自动清除RI,RI必须由软件清除。
TI(SCON.1),串行口发送中断标志位。
当CPU将一个发TCONSCON 总结:EX0(IE.0),外部中断0允许位;ET0(IE.1),定时/计数器T0中断允许位;EX1(IE.2),外部中断1允许位;ET1(IE.3),定时/计数器T1中断允许位;ES(IE.4),串行口中断允许位;每一个中断源有相应的中断允许位,1允许相应中断源的中断,0禁止相应中断源的中断,例:允许定时器T0中断:SETB EA位操作命令SETB ET0或:IE定的。
PX0(IP.0),外部中断0优先级设定位;PT0(IP.1),定时/计数器T0优先级设定位;PX1(IP.2),外部中断1优先级设定位;PT1(IP.3),定时/计数器T1优先级设定位;注意:1、该寄存器可以位寻址2、系统复位时均为低优先级0 1 0 1 0中断优中断请求标志位中断源允许总允许先级下列三个条件中任何一个都可阻碍CPU1、CPU正在处理同级或高优先级中断;2、当前查询的机器周期期。
即在完成所执行指令前,不会响应中断,从而保证指令在执行过程中不被打断;3、正在执行的指令为RET、RETI或任何访问IE或IP寄存器的指令。
只有在这些指令后面至少再执行一条指令时才能接受中断请求。
若由于上述条件的阻碍中断未能得到响应,当条件消失时该中断标志却已不再有效,那么该中断将不被响应。
基于C51中断过程及interrupt和using的使用
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 溢出。
c51语言处理单片机的中断是由专门的中断函数来处理的C51语言处理单片机的中断是由专门的中断函数来处理的。
中断是一种在程序执行过程中被外部事件触发的事件,它可以打断程序的正常执行,使得程序能够及时响应外部设备的请求。
C51语言中,中断函数是由程序员自定义的函数,用来处理中断事件。
当中断事件发生时,单片机会自动跳转到对应的中断函数进行处理。
中断函数通常包括以下几个部分:1.中断向量表:中断向量表是存储中断向量地址的表格。
每个中断向量对应一个中断类型,当中断事件发生时,单片机会根据中断类型找到对应的中断向量并跳转到相应的中断函数。
在C51语言中,中断向量表是通过设置中断向量地址的方式来定义的。
2.中断优先级:C51语言支持多级中断优先级,用来确定一些中断是否可以打断另一个中断的执行。
中断优先级可以通过设置特定的寄存器来实现,具体优先级的设置需要根据实际应用场景来确定。
3.中断服务程序:中断服务程序是中断函数的核心部分,用来处理中断事件。
在中断服务程序中,通常会进行以下几个步骤:a.保存现场:在进入中断服务程序之前,需要保存当前程序的执行状态,包括各个寄存器的值、堆栈指针等。
这样可以保证在中断处理完成后,程序能够正确地返回到中断发生前的执行状态。
b.清除中断标志:在进入中断服务程序之前,需要将中断标志位清除,以防止重复触发中断。
中断标志位通常是由硬件自动设置的,在中断服务程序中需要手动清除。
c.执行中断处理逻辑:在中断服务程序中,可以编写相应的逻辑代码来处理中断事件。
这可以包括读取外部设备的数据、进行数据处理、发送数据等。
中断服务程序中的代码需要尽量简洁高效,以确保及时响应外部事件。
d.恢复现场:在中断服务程序执行完成后,需要恢复之前保存的执行状态,包括恢复各个寄存器的值、堆栈指针等。
这样可以保证程序能够正确地返回到中断发生前的执行状态。
4.中断返回指令:在中断服务程序执行完成后,需要使用特定的指令来返回到主程序的执行位置。
KeilC51学习4按键外部中断主板介绍:P3^2~P^5为四个按键;P1^0~P1^7为8个LED灯#include "reg52.h"//此⽂件中定义了单⽚机的⼀些特殊功能寄存器typedef unsigned int uint; //对数据类型进⾏声明定义typedef unsigned char u8;sbit k1=P3^5; //定义P31⼝是k1sbit led=P1^0; //定义P10⼝是led/******************************************************************************** 函数名 : delay* 函数功能 : 晶振11.0592M延时函数*******************************************************************************/void delay(uint z){uint i,j;for(j=z;j>0;j--)for(i=112;i>0;i--);}/******************************************************************************** 函数名 : keypros* 函数功能 : 按键处理函数,判断按键K1是否按下*******************************************************************************/void keypros(){if(k1==0){delay(50);if(k1==0) //再次判断按键是否按下led=~led; //led状态取反}while(!k1); //检测按键是否松开}/******************************************************************************** 函数名 : main* 函数功能 : 主函数* 输⼊ : ⽆* 输出 : ⽆*******************************************************************************/void main(){while(1){keypros(); //按键处理函数}}按键取反灯亮或灭计数器(计数器0⽤P3^4按钮,计数器1⽤P3^5按钮,不懂)/*-----------------------------------------------名称:计数器0论坛:编写:shifang⽇期:2009.5修改:⽆内容:通过外部按键计数进⼊中断执⾏LED取反------------------------------------------------*/#include<reg52.h> //包含头⽂件,⼀般情况不需要改动,头⽂件包含特殊功能寄存器的定义sbit LED=P1^0; //定义LED端⼝/*------------------------------------------------定时器初始化⼦程序(按钮P3^4控制,不知为什么)------------------------------------------------*/void Init_Timer0(void){TMOD |= 0x01 | 0x04; //使⽤模式1,16位计数器,使⽤"|"符号可以在使⽤多个定时器时不受影响TH0=0xFF; //给定初值TL0=245; //从245计数到255EA=1; //总中断打开ET0=1; //定时器中断打开}/*------------------------------------------------主程序------------------------------------------------*/main(){Init_Timer0();while(1);}/*------------------------------------------------定时器中断⼦程序------------------------------------------------*/void Timer0_isr(void) interrupt 1using1{TH0=0xFF; //重新给定初值TL0=245;LED=~LED; //指⽰灯反相,可以看到闪烁}计数器0/*-----------------------------------------------名称:计数器1论坛:编写:shifang⽇期:2009.5修改:⽆内容:通过外部按键计数进⼊中断执⾏LED取反------------------------------------------------*/#include<reg52.h> //包含头⽂件,⼀般情况不需要改动,头⽂件包含特殊功能寄存器的定义sbit LED=P1^0; //定义LED端⼝/*------------------------------------------------定时器初始化⼦程序------------------------------------------------*/void Init_Timer1(void){TMOD |= 0x10 | 0x40; //使⽤模式1,16位计数器,使⽤"|"符号可以在使⽤多个定时器时不受影响TH1=0xFF; //给定初值TL1=245; //从245计数到255EA=1; //总中断打开ET1=1; //定时器中断打开TR1=1; //定时器开关打开}/*------------------------------------------------主程序------------------------------------------------*/main(){Init_Timer1();while(1);}/*------------------------------------------------定时器中断⼦程序------------------------------------------------*/void Timer1_isr(void) interrupt 3{TH1=0xFF; //重新给定初值TL1=245;LED=~LED; //指⽰灯反相,可以看到闪烁}计数器1中断定义:当机器正在执⾏程序的过程中,⼀旦遇到⼀些异常或者特殊请求时,停⽌正在执⾏的程序转⼊必要的处理,处理完毕后,⽴即返回断点继续执⾏。
引言:C51单片机中断是单片机开发中一个非常重要的概念。
通过中断,程序能够在运行过程中及时响应外部事件,提高系统的实时性和可靠性。
本文将进一步探讨C51单片机中断的相关知识,特别是中断优先级、中断嵌套、中断服务函数等方面的内容。
概述:C51单片机中断机制是通过改变程序的执行流程来实现的。
当中断事件发生时,CPU会暂停当前的执行任务,保存现场后转去执行中断服务程序,待中断服务程序执行完毕后,再恢复到之前的执行状态。
C51单片机中断机制通过这样的方式,有效地实现了对外部事件的及时响应。
正文内容:1. 中断优先级1.1 中断优先级的概念中断优先级是指在多个中断事件同时发生时,CPU按照一定的优先级顺序处理这些中断请求。
在C51单片机中,中断优先级是通过中断控制器来实现的。
中断控制器按照预先设定的优先级进行中断请求的响应,优先级越高的中断请求将被优先处理。
1.2 中断优先级的设置在C51单片机中,中断优先级的设置是通过特殊功能寄存器(SFR)来完成的。
通过设置SFR中的相关位,可以对不同的中断请求进行优先级设置。
具体的设置方法可以参考C51单片机的相关手册和数据手册。
2. 中断嵌套2.1 中断嵌套的概念中断嵌套是指在中断服务程序执行过程中,又发生了其他的中断事件,并且这些中断事件的优先级高于当前正在执行的中断服务程序。
在C51单片机中,中断嵌套是通过中断控制器的中断请求线来实现的。
当一个中断事件发生时,如果其优先级高于当前执行的中断服务程序,CPU会立即切换到新的中断服务程序中去执行。
2.2 中断嵌套的处理方法在C51单片机中,中断嵌套的处理是通过中断服务程序的堆栈来实现的。
当发生中断嵌套时,CPU将当前的现场信息保存到堆栈中,然后切换到新的中断服务程序中执行。
当新的中断服务程序执行完毕后,CPU会从堆栈中恢复之前的现场信息,并回到原来的中断服务程序继续执行。
3. 中断服务函数3.1 中断服务函数的概念中断服务函数是指用来处理中断事件的函数。
C51中断处理过程
3 C51中断处理过程
C51编译器支持在C源程序中直接开发中断过程,因此减轻了使用汇编语言的繁琐工作,提高了开发效率。
中断服务函数的完整语法如下:
void函数名(void)[模式]
[再入]interrupt n [using r]
其中n(0~31)代表中断号。
C51编译器允许32个中断,具体使用哪个中断由80C51系列的芯片决定。
r(0~3)代表第r组寄存器。
在调用中断函数时,要求中断过程调用的函数所使用的寄存器组必须与其相同。
"再入"用于说明中断处理函数有无"再入"能力。
C51编译器及其对C语言的扩充允许编程者对中断所有方面的控制和寄存器组的使用。
这种支持能使编程者创建高效的中断服务程序,用户只须在C语言下关心中断和必要的寄存器组切换操作。
例3 设单片机的fosc=12MHz,要求用T0的方式1编程,在P1.0脚输出周期为2ms的方波。
例3 设单片机的fosc=12MHz,要求用T0的方式1编程,在P1.0脚输出周期为2ms的方波。
用C语言编写的中断服务程序如下:
#include
sbit P1_0=P1^0;
void timer0(void)interrupt 1 using 1 {
/*T0中断服务程序入口*/
P1_0=!P1_0;
TH0=-(1000/256); /*计数初值重装*/
TL0=-(1000%256);
}
void main(void)
{
TMOD=0x01; /*T0工作在定时器方式1*/
P1_0=0;
TH0=-(1000/256); /*预置计数初值*/
TL0=-(1000%256);
EA=1; /*CPU开中断*/
ET0=1; /*T0开中断*/
TR0=1; /*启动T0*/
do{}while(1);
}
在编写中断服务程序时必须注意不能进行参数传递,不能有返回值。
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,选中“Don't use absolute register accesses”,使所有代码均不使用绝对寄存器寻址方式(这样,执行效率将稍有降低)。
不论以上的哪一种情况,编译器均会给出重入警告,需手工更改OVERLAY 参数,做重入说明。
3、还有一种办法:如果被调用函数的代码不是很长,还是将该函数复制一份,用不同的函数名代替,这种情况适合ROM有足够多余的空间。
因此,对using关键字的使用,如果没把握,宁可不用,交给编译系统自己去处理好了。
详细使用可参见C51.PDF文件,以上供参考。