维普资讯 http://www.cqvip.com
记 周兴华 请求可以是电平信号或者脉冲信号。中断请求信号一般保 持到微处理器作出响应为止。微处理器在检测到中断请求 信号之后,将中止当前正在执行的程序,并对断点实行保 护,即将断点的地址(PC值)推入堆栈保护,以便在中断 结束时从堆栈弹出断点地址,以便继续执行中断前的任 务。然后,微处理器由中断地址表获取中断入口地址,并 将此地址送入程序计数器(PC),从而开始执行中断服务 程序。在中断服务程序里一般需要完成现场保护、开关中 断、执行中断服务程序、现场恢复和中断返回等工作。 ATMEAG16L具有2O个中断源和1个复位中断,在 中断源中处于低地址的中断具有高的优先级。所有中断源 都有的中断使能位,当相应的使能位和全局中断使能 位(SREG寄存器的位1)都置1时,中断才可以发生, 相应的中断服务程序才会执行。附表为ATMEAGI6L的中 断源。 一个中断产生后,SREG寄存器的全局中断使能位f 附表 下一个工作去处理另一个 辩 ———— 机中, “中断”是兰一 篡f个很I }! 。x。∞lI REsET 进步使单片机的发展和应I 兰 I ,i !工 用大大以地推进了一步。所F— {器器 为衡量单片机功能完善与广_ 1 中断功能的强弱已成r_— — r亍 丽 否的重要指标。中断系统广— —广 『1一 的引入解决了微处理器和卜外设之间数据传输速率的r__ 一十 蔗 问题,提高了微处理器的广 了1 实时性和处理能力。广 ]_ 十 :! 开放时, 才能接受外部的L 三— 坚 旦 中断申请。一个完整的中I l 兰 l 断处理过程包括中断请求、1 1 l !j 断返回。 1l7 I Ox020 l ANA_COI', 中断请求是中断源向f 18 f 0x022 f ^,I 微处理器发出的信号,要I 19{0x024 I INT2 电子世界2007年第2期29 工 将被清零,后续中断被屏蔽。 l¨一 . 维普资讯 http://www.cqvip.com
INTI中断实验:平时8个LED闪烁,点亮/熄灭时 间约500mS。一旦INT1触发中断后,蜂鸣器发出10秒 用户可以在中断服务程序里对l置位从而再次开放中 断。在中断返回后,全局中断位I将重新置位。当程序计 数器指向中断向量开始执行相应的中断服务程序时,对应 中断标志位将被硬件清零。当一个符合条件的中断发生 后,如果相应的中断使能位为0,中断标志位将挂起并一 直保持到中断执行或者被软件清除。如果全局中断标志I 被清零,则所有的中断都不会被执行直到I置位。然后, #include<ioml 6v.h>..//包含头文件 #define uchar unsigned char//变量类型的宏定义 #define uint unsigned int #define BZ_0(PORTD=PORTD&0xdf)∥定义蜂鸣器 端口为低电平 被挂起的各个中断按中断优先级依次被处理。 ATMEAG16L的外部中断编程实践 ATMEAG16L具有多达20个中断源,这里我们首先 进行外部中断的实验,其它的等到介绍到相关内容时再进 行实验。 1.外部中断O外部中断0由引脚INT0(PIND2)触 发。如果INT0引脚按照MCUCR寄存器中的ISC01、 ISC00设置的方式发生跳变,则不管是否INT0中断使能, INT0中断标志位INTF0都将置位。如果SREG寄存器的 全局中断位I和通用中断控制寄存器GICR中的INT0中 断使能位INT0置位,则开始执行中断程序。在进入中断 服务程序时,INTF0被硬件清零。必须指出,不管INT0 (PIND2)引脚方向位设置如何,只要INT0引脚发生规定 的跳变,都会触发中断。中断标志位INTF0只在满足发 生中断的条件时置位,一旦条件变化,INTF0被硬件清 零。向INTF0位写“1,I也会对其清零。 2.外部中断1 外部中断1由引脚INT1(PIND3)触 发。如果INT1引脚按照MCUCR寄存器中的ISC11、 ISC10设置的方式发生跳变,则不管是否INT1中断使能, INT1中断标志位INTF1都将置位。如果SREG寄存器的 全局中断位I和通用中断控制寄存器GICR中的INT1中 断使能位INT1置位,则开始执行中断程序。在进入中断 服务程序时,INTF1被硬件清零。必须指出,不管INT1 (PIND3)引脚方向位设置如何,只要INT1引脚发生规定 的跳变,都会触发中断。中断标志位INTF1只在满足发 生中断的条件时置位,一旦条件变化,INTF1被硬件清 零。向INTF1位写”1,.也会对其清零。 3.外部中断2外部中断2由引脚INT2(PINB2)触 发。如果INT2引脚按照MCUCR寄存器中的ISC2设置 的方式发生跳变,则不管是否INT2中断使能,INT2中断 标志位INTF2都将置位。如果SREG寄存器的全局中断 位I和通用中断控制寄存器GICR中的INT2中断使能位 INT2置位,则开始执行中断程序。在进入中断服务程序 时,INTF2被硬件清零。必须指出,不管INT2(PINB2) 引脚方向位设置如何,只要INT2引脚发生规定的跳变, 都会触发中断。中断标志位INTF2只在满足发生中断的 条件时置位,一旦条件变化,INTF2被硬件清零。向 INTF1位写“1’’也会对其清零。 3O电子世界2007年第2期 #define BZ_1(PORTD=PORTDl0x20)∥定义蜂鸣器 端口为高电平 Uint cnt;//全局变量 J //============:============::== void delay_ms(uint k)//定义毫秒级的延时子函数 { uint i,j: fOr(_-0:i<k:j++) { for(j=0;j<l 140;j++) ) ) ,/========================== void main(void)II定义主函数 { ∥主函数开始 DDRB=0xff; //将PB端口设为输出 PORTB=0xff; //PB端口初始化输出11111111 DDRD=0xdf; //将PIND3设为输入 PORTD=0xff; //PD端口初始化输出11111111 MCUCR=0x08;//INT1为下降沿触发 GICR=0x80;//使能INT1中断 SREG=0x80; //使能总中断 while(1) //无限循环 { ∥无限循环语句开始 PORTB=0x00:∥PB端口输出00000000 delay—ms(500);//延时500mS PORTB=0xff;//PB端口输出11111111 delay_ms(500);//延时500mS ) ∥无限循环语句结束 ) ∥主函数结束 // #pragma interrupt—handler intl—isr:3#1 NT1中断 服务子函数 void intl isr(void) { for(cnt=0:cnt<5000 cnt++:) ∥蜂鸣器发声1 OS {BZ一1;delay—ms(2):BZ_0:) ) 维普资讯 http://www.cqvip.com
的报警声。 JTAG在线仿真或进行软件模拟仿真。仿真完成后,将 ac6.hex文件下载到AVR单片机综合试验板上。注意, 标示“LED”及“INT1”的双排针应插上短路块。我们看 在我的文档中新建一个ac6的文件夹。建立一个 ac6.pri的工程项目,最后建立源程序文件ac6 C。输入下 面的程序(程序1): 到,D1~D8发光管闪亮,间隔约O.5秒。按下INT1键 后,单片机进入中断,蜂鸣器发声10秒。 ac7.pri的工程项目,最后建立源程序文件ac7 C。输入下 面的程序(程序2). 编译通过后,可在AVR Studio集成开发环境中进行 编译通过后,可在AVR Studio集成开发环境中进行 INT0、INT1中断嵌套实验:平时8个LED闪烁, 点亮/熄灭时间约500ms。lNT1触发中断后,蜂鸣器发 出1O秒的报警声。在INT1的中断服务子函数中,再置 位总中断使能位I,这样INT1中断服务子函数中,即可 进行lNT0中断嵌套。当INT0触发中断时,进入INT0中 断服务子函数,将8个LED的一半熄灭。 在我的文档中新建一个ac7的文件夹。建立一个 (程序2) #include<ioml 6v.h>∥包含头文件 JTAG在线仿真或进行软件模拟仿真。仿真完成后,将 ac7.hex文件下载到AVR单片机综合试验板上进行实际 的中断操作。注意,标示“LED”、 “BEEP”及 “INT0”、“lNT1”的双排针应插上短路块。 { ∥无限循环语句开始 #define uchar unsigned char//变量类型的宏定义 #define uint unsigned int #define BZ—PORTB=0x00;#PB端口输出00000000 delayms(500);//延时500mS —O(PORTD=PORTD&O×df)∥定义蜂鸣 1(PORTD=PORTDlO×2O)∥定义蜂鸣器 PORTB=0xff;∥PB端口输出1 1 1 1 1 1 1 1 delayms(500);||延 500mS —器端口输出低电平 #define BZ) ) // “ ∥无限循环语句结束 ∥主函数结束 “ —端口输出高电平 uint cnt; ∥全局变量 //==:=========:====:=====:====: void delay—“ #pragma interrupthandler intOisr:2#I NTO中断服 ms(uint k) ∥定义毫秒级的延时子 务子函数 void intOisr(void) —函数 { { uint i,j: for(_=O j<k j++) PORTB:0x0f; ∥将8个LED的一半熄灭 delayms(2000);//延时2S { ) // “ “ ——for(j=0;j<l 1 4O:i++) “ #pragma interrupthandler intlisr:3//INT1中断服 务子函数 void intlisr(void) —,/:========:===:===::========= { SREG=0x80; void main(void)∥定义主函数 f ∥主函数开始 ∥在INTI中断中再 ∥蜂鸣器发声1OS 次使能总中断 for(cnt=O:cnt<5OOO cnt++) PORTB=0xff; ∥PB端口初始化输出1 1 1 1 1 1 1 1 DDRB:0xff; //将PB端口设为输出 PORTD=0xff; ∥PD端口初始化输出11111111 DDRD=0xf3;//将PIND2、3设为输入 MCUCR=0x0A;//INT0、1为下降沿触发 {BZ_1;delay—ms(2):BZ_O_) ) GICR=0xC0;∥使能INT0、1中断 SREG=0x80;∥使能总中断 while(1) ∥无限循环 电子世界2007年第2期31 维普资讯 http://www.cqvip.com
■—■■ 棼 I l — l两路防盗报警器实验:平时一个数码管熄灭。当盗 ac8.prj的工程项目,最后建立源程序文件ac8,C。输入下 情发生时自动显示“1”或“2”,同时一个LED点亮 面的程序(程序3):编译通过后,可将ac8.hex文件下载 (代表报警)。若两路同时产生盗情,则数码管每隔2秒 到AVR单片机综合试验板上进行实际的操作演示。注 轮流显示“1”、 “2”。直到值班人员按下复位按钮后才 意,标示“LED”、 “LEDMOD—DISP”、 “LED— 解除报警。 MOD—COM”及“INT0”、 “INT1”的双排针应插上短 在我的文档中新建一个ac8的文件夹。建立一个 路块。 (程序3) #include<iota1 6v.h> ∥包含头文件 ( ∥无限循环语句开始 #define uchar unsigned char //变量类型的宏定 if(alm_flag1=:1)//如果第1路产生盗情 义 {PORTA:SEG7…://数码管显示为1 #define uint unsigned int PORTC=Oxfe://点亮最右的数码管 ALM—ON;f报警器启动 uchar const SEG7[1 0]={0x3f,0x06,0x5b,∥共阴极数 delay_ms(2000);//延时2秒 码管O~9的字形码 ) Ox4f.0x66.0x6d.Ox7d.0x07,0x7f.0x6f}; If(aIm flag2==1)//如果第2路产生盗情 #define ALM一0N(P0RTB=PORTB&Oxfe)∥报警 (PORTA=SEG7[2];ff数码管显示为2 器启动 PORTC=0xfe;//点亮最右的数码管 uchar alm flag1,alm flag2;//第1、2路盗情标志 ALM—ON://报警器启动 //“““ “ “““ “ “ ““ delayms(2000);//延时2秒 void delay~ms(uint k)//定义毫秒级的延时子函数 ) { } ////无限循环语句结束 uint i,j: ) ////主函数结束 for(I-O:i<k:i++) // “““ “ “ “ “ { * for(j=0;j<11 4O j++) #pragma interrupt_handler intOisr:2∥fNT0中断服 务子函数 ) void intO—isr(void) ) { ,/=:=:==:=====:=::==:==:=====: aim flag1=1: ∥置第1路盗情标志为 void main(void)//定义主函数 1 { //主函数开始 ) DDRA=0xff; //将PA端口设为输出 // “ “ “““““ “ “ DDRC=0xff; //将PC端口设为输出 #pragma interrupthandler intl—isr:3//INT1中断服 PORTA=OxO0 ffPA端口初始化输出00000000 务子函数 PORTC=0xff: #PC端口初始化输出11111111 void intl—isr(void) PORTB=0xff: #PB端口初始化输出11111111 { DDRB=0xff; //将PB端口设为输出 almflag2=l: //置第2路盗情标志为1 PORTD=0xff: #PD端口初始化输出11111111 } DDRD=0xf3; //将PIND2、3设为输入 MCUCR=0x0A;//INT0、1为下降沿触发 GICR:0xC0;∥使能INT0、1中断 SREG=0x80;//使能总中断 while(1) ∥无限循环 编者附记:配合本文的邮购广告见62页。 32电子世界2007年第2期