第3章单片机中断系统章节安排:3.1中断系统简介3.2C51中关于中断函数的编写要求3.3外部中断服务程序设计能力要求:了解中断概念掌握51单片机中断系统掌握外部中断处理3.1中断系统简介中断的基本概念:在计算机中,由于计算机内外部原因,或者由于软硬件原因,使CPU从当前正在执行的程序中暂停下来,而自动转去执行预先安排好的为处理该原因所对应的服务程序。执行完服务程序后,再返回被暂停的位置继续执行原理的程序,这个过程称为中断。主任务讲课继续讲课接听电话主程序执行主程序继续主程序执行中断服务程序中断请求中断响应中断返回现实生活的中断事例单片机中断过程3.1中断系统简介中断源及中断请求产生中断请求信号的事件、原因称为中断源。要求中断信号产生一次,CPU中断一次,这就要求中断请求信号及时撤除中断优先权控制如果有多个中断源同时向CPU提出中断请求,CPU必须按照事先设定的优先权选择优先级别最高的为其服务。中断开放与中断屏蔽并不是有了中断请求CPU就能够响应中断,CPU响应中断受中断屏蔽位的控制。若单片机总屏蔽控制位为屏蔽状态,则CPU不会响应任何中断请求每个中断源还有自己独自的中断屏蔽位。若自己的中断屏蔽位为屏蔽状态,CPU不会响应该中断中断响应与中断返回当CPU检测到中断请求,并且该中断屏蔽位为开放状态,CPU就会响应该中断中断处理程序执行完毕,返回到主程序继续执行3.1中断系统简介51单片机一共有5个中断源外部中断0(INT0):由P3.2端口引入,由低电平或者下降沿触发外部中断1(INT1):由P3.3端口引入,由低电平或者下降沿触发定时器/计数器0中断:由定时器T0计数器计满值回零触发定时器/计数器1中断:由定时器T1计数器计满值回零触发串口中断:当串口接收或者发送一帧字符后触发TCOND7D6D5D4D3D2D1D0(88H)TF1TR1TF0TR0IE1IT1IE0IT0IT0(IT1):外部中断0(或1)触发方式控制位。IT0(或IT1)被设置为0,则选择外部中断为电平触发方式;IT0(或IT1)被设置为1,则选择外部中断为边沿触发方式。IE0(IE1):外部中断0(或1)的中断请求标志位。边沿检测时,检测P3.2或者P3.3引脚是否检测到低电平,若检测到,使IE0(IE1)设置为1,从而向CPU提出中断请求,CPU响应中断后由硬件自动将IE0(IE1)清0电平检测时,只要P3.2或者P3.3引脚为低电平,IE0(IE1)就设置为1,从而向CPU提出中断请求。如果中断已返回,而P3.2或者P3.3引脚仍为低电平,则会再次进入中断,因而必须处置该情况。INT1INT01.外部中断外部引脚P3.2和P3.3输入,有两种触发方式:电平(低电平有效)触发及边沿(下降沿有效)触发。由特殊功能寄存器TCON来管理.3.1中断系统简介2.定时/计数器T0和T1中断当定时/计数器T0(或T1)溢出时,由硬件置TF0(或TF1)为“1”,向CPU发送中断请求。当CPU响应中断后,将由硬件自动清除TF0(或TF1)。3.串行口中断MCS-51的串行口中断源对应两个中断标志位:串行口发送中断标志位TI和串行口接收中断标志位RI。无论哪个标志位置“1”,都请求串行口中断到底是发送中断TI还是接收中断RI,只有在中断服务程序中通过指令查询来判断。串行口中断响应后,不能由硬件自动清“0”,必须由软件对TI或RI清“0”。TCOND7D6D5D4D3D2D1D0(88H)TF1TR1TF0TR0IE1IT1IE0IT0中断允许控制MCS-51单片机中没有专门的开中断和关中断指令,对各个中断源的允许和屏蔽是由内部的中断允许寄存器IE的各位来控制的。中断允许寄存器IE的字节地址为A8H,可以进行位寻址.IED7D6D5D4D3D2D1D0(A8H)EAET2ESET1EX1ET0EX0EA:中断允许总控位。EA=0,屏蔽所有的中断请求;EA=1,开放中断。ET2:定时器/计数器T2的溢出中断允许位ES:串行口中断允许位。ET1:定时器/计数器T1的溢出中断允许位。EX1:外部中断INT1的中断允许位。ET0:定时器/计数器T0的溢出中断允许位。EX0:外部中断INT0的中断允许位。优先权控制每个中断源有两级控制:高优先级和低优先级。优先权控制由中断优先级寄存器IP来设置.中断优先级寄存器IP的字节地址为B8H,可以进行位寻址.IPD7D6D5D4D3D2D1D0(B8H)PT2PSPT1PX1PT0PX0PT2:定时器/计数器T2的中断优先级控制位,只用于52子系列。PS:串行口的中断优先级控制位。PT1:定时器/计数器T1的中断优先级控制位。PX1:外部中断INT1的中断优先级控制位。PT0:定时器/计数器T0的中断优先级控制位。PX0:外部中断INT0的中断优先级控制位。如果某位被置“1”,则对应的中断源被设为高优先级;如果某位被清“0”,则对应的中断源被设为低优先级。对于同级中断源,系统有默认的优先权顺序,中断源优先级顺序最高最低外部中断0定时/计数器T0中断外部中断1定时/计数器T1中断串行口中断定时/计数器T2中断通过中断优先级寄存器IP改变中断源的优先级顺序可以实现两个方面的功能:改变系统中断源的优先权顺序和实现二级中断嵌套。对于中断优先权和中断嵌套,MCS-51单片机有以下三条规定。(1)正在进行的中断过程不能被新的同级或低优先级的中断请求所中断,一直到该中断服务程序结束,返回了主程序且执行了主程序中的一条指令后,CPU才响应新的中断请求。(2)正在进行的低优先级中断服务程序能被高优先级中断请求所中断,实现两级中断嵌套。(3)CPU同时接收到几个中断请求时,首先响应优先级最高的中断请求。MCS-51中断系统的逻辑结构IE0INT0IT0=0IT0=1或IEEX0EAIE1INT1IT1=0IT1=1或EX1ET1ET0或ES或ET2TF0TF1TIRITF2EXF2查询顺序(识别)查询顺序(识别)查询硬件高优先级中断中断入口地址低优先级中断中断入口地址PT2PSPT1PX1PT0PX0IP3.2C51中关于中断函数的编写要求中断程序示例:intx;voidint0()interrupt0using1{x++;}中断函数专用修饰符:interruptminterruptm是C51函数中非常重要的一个修饰符,这是因为中断函数必须通过它进行修饰。在C51程序设计中,当函数定义时用了interruptm修饰符,系统编译时把对应函数转化为中断函数,自动加上程序头段和尾段,并按MCS-51系统中断的处理方式自动把它安排在程序存储器中的相应位置。m的取值为0~31,具体如下表。3.2C51中关于中断函数的编写要求中断源中断号(m的取值)外部中断00定时/计数器01外部中断12定时/计数器13串行口4定时/计数器2(仅52子系列有)53.2C51中关于中断函数的编写要求usingn修饰符修饰符usingn用于指定本函数内部使用的工作寄存器组,其中n的取值为0~3,表示寄存器组号。usingn修饰符不能用于有返回值的函数,因为C51函数的返回值是放在寄存器中的。如寄存器组改变了,返回值就会出错。通常,该修饰符可省略,由编译器去分配编写MCS-51中断函数注意如下:中断函数不能进行参数传递,如果中断函数中包含任何参数声明都将导致编译出错。中断函数没有返回值,如果企图定义一个返回值将得不到正确的结果,建议在定义中断函数时将其定义为void类型,以明确说明没有返回值。在任何情况下都不能直接调用中断函数,否则会产生编译错误。因为中断函数的返回是由8051单片机的RETI指令完成的,RETI指令影响8051单片机的硬件中断系统。如果在没有实际中断情况下直接调用中断函数,RETI指令的操作结果会产生一个致命的错误。如果在中断函数中调用了其它函数,则被调用函数所使用的寄存器必须与中断函数相同。否则会产生不正确的结果。3.3外部中断服务程序设计硬件连线如下图。编写外部中断服务程序,每次按键都会改变发光二极管的亮灭3.3外部中断服务程序设计P3.3和P3.5属于端口P3的两位,可以按照第2章所学的端口控制方法。方法一:用键数据控制led,编程如下:#includereg51.hsbitLED=P3^5;sbitKEY=P3^3;voidDelay(uinta);main(){bittemp;while(1){temp=KEY;LED=temp;}}分析:不能达到预期效果:因为键按下LED灭,键抬起LED亮。3.3外部中断服务程序设计方法二:对两个外部中断引脚的访问控制,可以采用一般端口操作方式,即不把它们当做特殊的引脚对待,而是使用前面章节所介绍过的普通端口操作。查询键是否按下,如果有,为了避免一次按键被多次处理,所以可以等待键松开之后再处理。#includereg51.h#defineuintunsignedintsbitLED=P3^5;sbitKEY=P3^3;voidDelay(uinta);main(){while(1){if(KEY==0)//说明有按键{Delay(100);if(KEY==0)//不是抖动{while(!KEY);//等待按键松开LED=~LED;//改变状态}}}}voidDelay(uinta)//延时子函数;{uintb;for(b=0;ba;b++);}3.3外部中断服务程序设计如果采用中断方式处理按键,则如下:外部中断服务程序设计过程分析首先,根据电路连线,明确使用INT1外部中断,键盘的闭合和断开都会使P3.3引脚上的数值(电平)改变,从而触发INT1中断INT1中断请求如果要被CPU接收处理,则INT1中断必须开放,即必须设置EA和EX1控制位由于键是机械元件,键的闭合和断开瞬间都会有抖动现象,使P3.3引脚上的数值发生0、1间的变化,错误的触发中断。因此必须消除键抖动不管INT1中断采用的是边沿检测或是电平检测,都必须做到一次按键值被处理一次。3.3外部中断服务程序设计外部中断服务程序设计软件流程分析编写一函数,实现对外部中断的开放编写中断服务程序,实现每次按键都会改变发光二极管的亮灭编写主函数外部中断程序基本框架#includereg51.hsbitLED=P3^5;sbitKEY=P3^3;voidInt1(void);voidEnableInt1(void);main(){EnableInt1();LED=0;while(1);}voidEnableInt1(void)//外部中断的开放{IT0=1;//设置边沿触发方式EA=1;EX1=1;}voidInt1(void)interrupt2//中断服务程序{LED=~LED;}此程序只是一个基本框架,并不能达到预期成果如何改造该程序?加入去抖动处理一次按键只能处理一次,需加入等待按键松开处理去抖动处理检测到有按键后,调用delay()函数,延迟一会。之后再检测是否还有按键,如果没有,说明是抖动,不需处理;如果有,说明是键按下。等待按键松开处理查询按键是否松开,如果没有(P3.3=1时),则继续查询,直到松开为止。特别强调:中断函数一定要简短,不能执行时间过长,否则执行会混乱。因此可以把占用时间的处理部分(特别是延时等待部分)丢到函数外部去处理3.3外部中断服务程序设计实践项目:通过外部中断控制流水灯流水方向(向左或向右流水),流水灯以软件延时方式实现。项目分析:项目主要包括两部分功能:外部中断识别与处理和流水灯控制目前我们已掌握:外部中断识别与处理功能:如何消除键抖动,如何消除一键处理多次的情况流水灯控制:通过软件延时(调用Delay()函数)实现流水但是,我们还必须考虑到以下情况:外部中断处理和流水灯控制两者都需要调用Delay()函数,可能会造成另一功能不能正常执行。比如:一次按键