单片机教材第5章外部中断及应用Word下载.docx
《单片机教材第5章外部中断及应用Word下载.docx》由会员分享,可在线阅读,更多相关《单片机教材第5章外部中断及应用Word下载.docx(16页珍藏版)》请在冰豆网上搜索。
对此,CPU必须作出快速响应和及时处理。
这种实时处理功能只能靠中断技术才能实现。
3.实现故障的及时发现
计算机在运行过程中,常会突然发生一些事先无法预料的故障。
如:
硬件故障、运算错误及程序故障等。
有了中断技术、计算机就能对这些故障及时发现并进行自行处理。
4.实现人机联系
人要想对运行的计算机进行干预,必须先通过键盘发出中断请求,在获得了机器准许后,方可进行。
中断技术使得人们可以随时进行人机联系,而不用先停机处理,然后在重新开机。
随着计算机软硬技术的发展,中断技术也在不断发展之中,其功能也会更加丰富。
在现代计算机的发展中,中断已成为评价计算机整体性能的一项重要指标。
通过以上两节的介绍,我们可以给中断下一个定义:
中断是指计算机暂时停止原程序执行转而为外部设备服务(即执行中断服务程序),并在服务完后自动返回原程序执行的过程。
5.1.3中断源
中断由中断源产生,中断源在需要时可以向CPU提出“中断请求”。
当CPU响应中断请求后,就会自动转入该中断源的中断服务程序执行。
中断源不同,中断服务程序的功能也不同。
引起中断的原因,或能发生中断申请的来源,称为中断源。
通常,中断源有以下几种:
▪外部设备中断源
▪控制对象中断源
▪故障中断源
▪定时脉冲中断源
▪为调试程序而设置的中断源
5.1.4中断的检测与中断的响应条件
中断源产生的中断请求是随机发生无法预料的。
因此,CPU必须不断的检测中断输入线上的中断请求信号,而且相邻两次检测不能相隔太长,否则会影响响应中断的时效。
通常CPU总是在每条指令的最后状态对中断请求进行一次检测。
因此,中断源产生中断请求到它被CPU检测到它的存在,一般不会超过一条指令的时间。
CPU检测到了中断请求,并非就立即响应。
单片机的中断响应是有条件的,现总结分析如下:
1.设置中断请求触发器
每一个中断源,要能发出中断请求信号,且这个信号能保持着,直到CPU响应这个中断后,才可清除中断请求。
2.设置中断屏蔽触发器
实际应用系统中往往有多个中断源,每一个中断源的中断请求是否能发送至CPU,由各自的“中断屏蔽”触发器(或称为中断允许触发器)决定。
只有当此触发器为“1”时,中断请求才能被送出至CPU。
3.总中断是开放的
在CPU内部有一个中断允许触发器。
只有当其为“1”时,(即中断开放时)CPU才能响应中断;
若其为0(即中断关闭),即使有中断请求,CPU也不响应。
该触发器的状态可由指令设置,称为总中断开关。
4.CPU在现行指令结束后响应中断
在开中断情况下,若外设有中断请求,CPU也并不是立即响应,只有当正在执行的指令运行至最后一个机器周期的最后一个状态时,CPU才采样中断请求信号线。
若发现有中断请求,则把内部的中断锁存器置“1”(同时关闭其他中断请求),然后下一个机器周期不进入取指周期,而进入中断周期,执行中断服务程序。
其时序流程图如图5-1。
5.1.5CPU对中断的响应
当满足上述条件后,CPU就响应中断,转入中断周期,CPU做以下几件事:
1.
关中断(在不允许其他中断打扰时)
CPU响应中断后,发出中断响应信号的同时,内部自动的实现关中断。
2.保留断点
CPU响应中断前,保留被中断程序的地址,以备中断处理完毕后,能返回主程序。
3.保护现场
为了使中断处理程序不影响主程序的运行,故要把断点处的有关的各个寄存器的内容和标志位的状态,推入堆栈保护起来(现场保护大多由中断程序完成)。
4.给出中断入口,转入相应的中断服务程序
大多数单片机是采用矢量中断(向量中断)的方式,提供中断服务程序的入口地址的。
5.恢复现场
中断服务完成后,把所保存的各个内部寄存器的内容和标志位的状态,从堆栈弹出,送回CPU中的原来位置(此步,由中断服务程序完成)。
6.开中断与返回
在中断服务程序的最后,要开中断(以便CPU能响应新的中断请求)和安排一条返回指令,运行就恢复到主程序。
上述过程可用图5-2的流程图表示。
5.1.6中断服务程序的转入
当CPU响应中断时,在关中断和保留断点后,一个十分重要的问题是如何转到中断服务程序的入口。
矢量中断就是解决上述问题的方法之一。
矢量中断的解决方案是,在程序存储器的适当位置(通常是在程序存储器的起始处)开辟一组特殊单元(例如,ATmege16的一组特殊程序存储器单元为0000H~002FH),作为中断源的中断地址(中断向量)区。
中断响应后按中断种类,CPU自动生成一条跳转指令,从而跳转到各自中断区的首地址去执行程序。
因此,在中断地址区中理应存放对应中断的中断服务程序。
一般情况下,中断地址区预留给中断服务程序的空间非常少(例如,ATmega16只有2个字节)几乎不可能存放一个完整的中断服务程序,所以通常在中断地址区各中断的首地址处存放一条无条件转移指令,以便中断响应后通过中断地址区,再转到中断服务程序的实际入口地址去。
5.1.7ATmega16的中断系统
1.中断源
ATmega16有20个中断源(若包括复位则为21个)。
每个中断源在程序空间都有一个独立的中断向量,所有的中断事件都有自己的使能位(中断屏蔽开关)。
当使能位置位,且I(总中断开关,状态寄存器SREG中的第7位)也置位的情况下,中断可以发生。
ATmega16复位后,程序空间的最低位置自动定义为复位及中断向量。
完整的中断表见表5-1。
在中断向量表中,处于低地址的中断具有高的优先级,所以,RESET具有最高的优先级。
表5-1复位与中断向量
向量号
程序地址
来源
中断定义
1
$0000
RESET
外部引脚,上电复位和看门狗复位
2
$0002
INT0
外部中断0
3
$0004
INT1
外部中断1
4
$0006
TIMER2COMP
T/C2比较匹配
5
$0008
TIMER2OVF
T/C2溢出
6
$000A
TIMER1CAPT
T/C1捕获事件
7
$000C
TIMER1COMPA
T/C1比较匹配A
8
$001E
TIMER1COMPAB
T/C1比较匹配B
9
$0010
TIMER1OVF
T/C1溢出
10
$0012
T/C0溢出
11
$0014
SPI,STC
SPI串行传输完成
12
$0016
USART,RXC
USART,Rx完成
13
$0018
USART,UDRE
USART数据寄存器空
14
$001A
USART,TXC
USART,Tx完成
15
$001C
ADC
ADC转换完成
16
EE_RDY
E2PROM准备好
17
$0020
ANA_COMP
模拟比较
18
$0022
TWI
I2C串行口
19
$0024
INT2
外部中断2
20
$0026
TIMER0COMP
T/C0比较匹配
21
$0028
SPM_RDY
写程序存储器准备好
注:
(1)当BOOTRST熔丝位被编程时,器件在复位后将跳到引导载入区的起始地址处开始执行(出厂时BOOTRST熔丝位为“1”,未被编程)。
(2)当GICR寄存器的IVSEL位置“1”时,中断向量表将移到引导载入区的头部,每个中断向量的地址是该向量在向量表中的地址加上引导载入区的起始地址值。
2.中断处理
ATmega16有1个T/C中断屏蔽寄存器TIMSK,1个通用中断控制寄存器GICR。
TIMSK、GICR分别使能和屏蔽定时器中断、外部中断源中断。
其他中断源的使能与屏蔽,由相应的外设控制寄存器控制。
当系统响应一个中断后,会自动将全局中断使能位I(状态寄存器SREG中的第7位)清0,此时后续中断的响应被屏蔽。
用户可以在中断服务程序中对I置位,从而开放中断。
中断服务程序中执行返回指令后,I重新置位。
当程序计数器指向实际中断向量,开始执行相应的中断服务程序时,硬件自动清除对应的中断标志。
一些中断标志位也可以通过软件写“1”清除。
当一个符合条件的中断发生后(建立相应的中断标志),如果相应的中断使能位为“0”,则中断标志位被挂起,并一直保持到该中断被响应或被软件清为“0”。
如果全局中断标志I被清0,则所有的中断都不会被执行,直到I置位,然后被挂起的各个中断按中断优先级依次中断,或被软件清为“0”。
3.中断响应时间
所谓中断响应时间是指从查询中断请求标志位到转向中断区入口地址所需的时钟周期数。
ATmega16中断响应时间最少为4个时钟周期。
ATmega16中断返回也需4个时钟周期。
在一般应用情况下,中断响应的长短通常无须考虑。
只有在精确定时的应用场合,才需要知道中断响应时间,以保证精确的定时控制。
特别要注意的是,AVR在响应中断及中断返回时,并不会对状态寄存器SREG自动进行保护和恢复操作,因此,状态寄存器SREG的中断保护与恢复必须由用户软件完成。
5.2ATmega16的外部中断
5.2.1外部中断源
ATmega16有3个外部中断源,分别对应PD2、PD3和PB2,如下表5-2所示。
表5-2外部中断源
管脚
外部中断源
PD2
INT0(外部中断0输入)
PD3
INT1(外部中断1输入)
PB2
INT2(外部中断2输入)
5.2.2外部中断的控制
ATmega16的外部中断用户是可编程的。
所以,我们首先介绍有关外部中断的控制寄存器。
▪状态寄存器SREG(StatusRegister)
位76543210
位名称
读/写r/wr/wr/wr/wr/wr/wr/wr/w
初始值00000000
位7(I):
全局中断使能
置位(置“1”)时使全局中断使能(允许)。
单独的中断使能由各自独立控制寄存器所控制。
如果I清“0”,则不论单独中断标志置位与否,都不会产生中断。
一旦系统响应中断,I位由硬件自动清“0”;
而当执行RETI(中断返回)指令时,I位由硬件自动置“1”,从而允许系统再次响应下一个中断的请求。
I在系统复位时清“0”。
在CodeVisionAVRC开发系统中,用函数#asm(“sei”)设置全局中断使能。
位6(T):
位拷贝存储
位5(H):
半进位标志
位4(S):
符号位
位3(V):
溢出标志位
位2(N):
负数标志位
位1(Z):
零标志位
位0(C):
进位标志位
位6~位0,在C语言编程时由系统管理,在此不作介绍。
状态寄存器SREG在进入中断和退出中断时并不自动进行存储和恢复,这项工作由软件完成。
▪通用中断控制寄存器GICR
读/写r/wr/wr/wrrrrr
位7—5——INT1、INT0、INT2:
外部中断INT1、INT0和INT2请求使能位
当INT0-INT2的某一位被置“1”,且SREG.7=1时,对应的外部中断允许中断。
外部中断INT0、INT1允许用户编程为上升沿、下降沿、上升/下降沿或低电平触发;
INT2允许用户编程为上升沿或下降沿触发。
INT0-INT2外部中断所对应的引脚,即使被定义为输出,中断请求仍可产生。
在C语言编程时,通用中断控制寄存器GICR中的对应位,可通过编程向导进行定义。
▪MCU控制寄存器MCUCR
位名称
位3~0(ISC11-ISC00):
外部中断INT1、INT0中断方式控制位
MCUCR中的低4位,定义INT0、INT1中断的边沿或低电平触发,如表5-3所示。
表5-3INT0-INT1检测控制
ISCX1
ISCX0
描述
低电平触发中断
下降沿和上升沿均触发中断
下降沿触发中断
上升沿触发中断
在C语言编程时,MCU控制寄存器MCUCR中的对应位,可通过编程向导进行定义。
▪MCU控制和状态寄存器MCUCSR
读/写r/wr/wrr/wr/wr/wr/wr/w
位6(ISC2):
外部中断INT2中断方式控制位
当ISC2清“0”时,INT2引脚上的一个下降沿将触发中断;
当ISC2置“1”时,INT2引脚上的一个上升沿将触发中断。
▪通用中断标志寄存器GIFR
位7、6、5(INTF1、INTF0、INTF2):
外部中断INT0-INT2的中断标志
当INT0-INT2引脚有事件触发中断请求时,对应的INTF0-INTF2置位(置“1”)。
如果中断允许,CPU将跳转到相应的中断地址。
中断服务程序执行后,对应的标志位被清“0”。
另外,INTF0-INTF2标志也可以通过对其写“1”来清除。
若INT0、INT1被定义为低电平触发时,INTF0、INTF1始终被清“0”。
5.3外部中断应用
5.3.1应用课题:
设计一段程序,用于统计外部INT0的中断次数。
INT0的输入引脚为PD2。
将PD7设计成方波输出信号源,连接到PD2引脚,信号的上升源引发INT0外部中断,每中断一次计数器加1,数码显示器的值加1。
硬件连接电路如图5-3所示。
由7219控制的8位数码显示器模块,通过SPI接口与MEGA16连接,用来显示计数值。
主程序的工作是在PC2引脚发送方波信号,本例每2秒钟输出一个方波。
INT0中断服务程序,记录方波数量,并显示。
主函数由我们自己编写主任务。
我们还要把数码显示模块的显示文件spi_7219.C添加进来。
这个文件包含7219芯片的接口驱动函数spi_xie(charjicunqi,charmingling),初始化函数spi_7219c()、和参数显示函数xunce(charbianhao,intcanshu,chardianwei)。
1.d:
\cvavr\spi_7219.c文件:
(此文件的程序在后面的章节中有详细的介绍,在此只需按原样输入,不必读懂)
/*********************************************
实验项目:
7219控制的8段数码显示
单片机:
MEGA16
晶振:
4.000000MHz
连线:
PB--7219X,LCDH--7219H,LCDD--7219D
*********************************************/
#include<
mega16.h>
#defineucharunsignedchar
voidspi_xie(uchari,ucharj)
{
DDRB=0xBF;
//选通7219
SPCR=0x5e;
//SPI设置
PORTB=PORTB&
0xEF;
//load_7219=0;
SPDR=i;
while(SPSR.7==0);
//等待SPI发送完
SPDR=j;
PORTB=PORTB|0x10;
//load_7219=1;
结束对7219的传送
}
voidspi_7219c()//7219初始化
spi_xie(0x0b,0x07);
//显示8位
spi_xie(0x0a,0x02);
//亮度调节
spi_xie(0x09,0xff);
//每位BCD输入
spi_xie(0x0c,0x01);
//工作状态
spi_xie(0x0f,0x00);
//非测试
/*多参数显示,前两位显示参数编号,后6位显示整型参数,小数点设在第n+1位*/
voidxunce_7219(uchari,inty,ucharn)
//把i送到显示器的第一、二位,把y送到第三至八位,n为小数点所在位
{ucharlcd[8];
ucharj;
n=n&
7;
lcd[0]=i/10;
lcd[1]=i%10;
if((y&
0x8000)==0)lcd[2]=15;
//符号处理
else{y=~y+1;
lcd[2]=10;
}
lcd[3]=(uchar)(y/10000%10);
lcd[4]=(uchar)(y/1000%10);
lcd[5]=(uchar)(y/100%10);
lcd[6]=(uchar)(y/10%10);
lcd[7]=(uchar)(y%10);
for(j=0;
j<
8;
j++)
{if(n==j)lcd[j]=lcd[j]+0x80;
//加入小数点
spi_xie(j+1,lcd[j]);
//送显示数据到7219
2.主任务文件
#include<
delay.h>
#include"
d:
\cvavr\spi_7219.c"
intx;
//外部中断INT0的中断服务程序
interrupt[EXT_INT0]voidext_int0_isr(void)
x++;
xunce_7219(0,x,7);
voidmain(void)
{
DDRD=0xF0;
//PD口输出,PD.7输出方波,作外部中断信号
GICR=0x40;
MCUCR=0x02;
MCUCSR=0x00;
GIFR=0x40;
SREG=0x80;
//开中断
spi_7219c();
//显示芯片初始化
delay_ms(20);
xunce_7219(0,0,7);
while
(1)
{
PORTD.7=!
PORTD.7;
//输出方波,作为外部中断信号
delay_ms(500);
};
5.3.2实验指导
读懂上述程序的自编部分及外部中断初始化函数。
实验时可改变主函数中的延时时间,也可去掉命令行:
PORTD.7=!
观察结果,找出原因。
练习
1、在ATmega16的DIP封装中INT1的输入引脚是哪一个?
2、编写一程序,当INT1中断时,改变ATmega16的DIP封装中36号引脚的状态。