单片机之中断篇
中断的概念日常生活的中断现象举例中断是指在突发事件到来时先中止当前正在进行的工作,转而去处理突发事件。待处理完成后,再返回到原先被中止的工作处,继续进行随后的工作。中断的一般概念中断响应过程:由中断管理系统处理突发事件的过程;中断源:中断管理系统能够处理的突发事件;中断请求:中断源向CPU提出的处理请求;中断函数:针对中断源和中断请求提供的服务函数;中断嵌套:在中断服务过程中执行更高级别的中断服务
目录
1、中断的概念
日常生活的中断现象举例
中断是指在突发事件到来时先中止当前正在进行的工作,转而去处理突发事件。待处理完成后,再返回到原先被中止的工作处,继续进行随后的工作。
中断的一般概念
中断响应过程:由中断管理系统处理突发事件的过程;
中断源:中断管理系统能够处理的突发事件;
中断请求:中断源向CPU提出的处理请求;
中断函数:针对中断源和中断请求提供的服务函数;
中断嵌套:在中断服务过程中执行更高级别的中断服务。
中断过程与调用一般函数过程的相似性: 两者都需要保护断点,都可实现多级嵌套等。
中断过程与调用一般函数过程的差异性:
1、前者是程序设计者事先安排的(断点位置是明确的),而后者却是系统根据工作环境随机决定的(断点位置是随机的)。
2、主函数与一般函数之间具有主从关系,而主函数与中断函数之间则是平行关系(中断函数只能被系统调用);
3、一般函数调用是纯粹软件处理过程,而中断函数调用却是需要软、硬件配合才能完成的过程。
中断实现的功能:
1、分时操作:CPU可以使多个外设同时工作,并分时为各外设提供服务,从而大大提高了CPU的利用率和输入/输出的速度。
2、实时处理:当计算机用于实时控制时,请求CPU提供服务是随机发生的。有了中断系统,CPU就可以立即响应并加以处理。
3、故障处理:当计算机运行中出现如电源断电、存储器校验出错、运算溢出等错误时,CPU可及时转去执行故障处理程序,减小或消除故障产生的影响。
实例1 单片机开关状态检测
要求:若有按键压下→D1状态反转。
利用查询法编程如下:
#include<reg51.h>
sbit p1_0=P1^0;
sbit p3_2=P3^2;
main(){
p1_0=0;
while(1){
if(p3_2==0)p1_0=!p1_0;
}
}
利用中断法编程如下:
#include<reg51.h>
sbit p1_0=P1^0;
int0_srv() interrupt 0{
p1_0=!p1_0;
}
main(){
IT0=1;
IE=0x81;
while(1);
}
运行结果如下:
2、中断控制系统
2.1 中断系统的结构
1、中断源
中断源数量和种类越多,MCU处理突发事件的能力就越强。
80C51单片机共有5种中断源。
2、中断请求标志
当中断信号出现时,单片机中某些寄存器位(中断请求标志位)可被硬件置1。
CPU通过定期查看中断请求标志位是否为1,便可知道有无中断请求。
2.2 中断控制
中断系统的组成
中断信号分别沿5条水平路径由左向右进行传送。
其中,TCON、SCON、IE、IP是相关SFR。
1、TCON寄存器
定时/计数器的控制寄存器(Timer/Counter Control Register),字节地址为88H,可位寻址。
【注意】 51单片机复位后,TCON初值为0——默认没有上述中断请求,默认采用电平触发方式。
2、SCON寄存器
串口控制寄存器(Serial control register),字节地址为98H,可位寻址。
【注意】TI和RI虽然是2个中断请求标志位,但在SCON之后经或门电路合成为1个信息,统一接受中断管理。
3、IE寄存器
中断允许寄存器(Interrupt Enable Register),字节地址为A8H,可位寻址。
【注意】禁止中断并不能阻止中断请求标志值的硬件刷新;
单片机复位后,IE的初值为0——默认为整体禁止中断。
4、IP 寄存器
中断优先级寄存器(Interrupt Priority Registers),字节地址为B8H,可位寻址。
优先级原则:
1)高级中断请求可以打断正在执行的低级中断;
2)同级或低级中断请求不能打断正在执行的中断;
3)同级中断源同时提出请求时按自然优先级响应:
INT0→ T0 → INT1→T1→TI/RI
4)单片机复位时,IP初值为0——默认所有中断源均为低级中断。
中断嵌套演示
功能:
#include"reg51.h"
char led_mod[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示字模
sbit D1=P3^0;
void delay(unsigned int time){ //延时
unsigned char j ;
for(j=255;time>0;time--)
for(;j>0;j--);
}
key0() interrupt 0{ //K0中断函数
unsigned char i;
D1=IE0; //IE0状态输出_
for(i=0;i<=9;i++){ //字 符0-9循环1圈
P2=led_mod[i];
delay (35000) ;
}P2=0x40; //结束符“一”
}
key1() interrupt 2 { //K1中断函数
unsigned char i;
for(i=0;i<=9;i++){ //字符0-9循环1圈
D1=IE0; //IE0状态输出
P1=led_mod[i];
delay (35000) ;
}P1=0x40; //结束符“一”
}
void main(){
unsigned char i;
TCON = 0x05; //脉冲触发方式
PX0=0;PX1=1; //INT1优先
D1=0;P1=P2=0x40; //输出初值
IE=0x85; //开中断
while(1){
for(i=0;i<=9;i++){ //字 符0-9无限循环
P0=led_mod[i];
delay(35000);
}}}
仿真运行图如下:
中断标志汇总
中断管理寄存器汇总
3、中断处理过程
中断处理包括中断请求、中断响应、中断服务、中断返回等环节。
1、中断响应
CPU响应中断的基本条件为:
(1)有中断源发出中断请求;
(2)中断总允许位EA=1,即CPU开中断;
(3)申请中断的中断源的中断允许位为1。
CPU响应中断后的操作过程:
1.中断优先级查询,阻止后来的同级或低级中断请求。
2.保护断点,即把程序计数器PC的内容压入堆栈保存。
3.清除中断请求标志位。
4.调用中断函数并开始运行。
5.返回断点继续运行。
【注意】除中断函数运行是软件方式外,其余中断处理过程都是由单片机硬件自动完成的。
2、响应时间
Ø从查询中断请求标志到执行中断函数第一条语句所经历的时间,称为中断响应时间。
ØCPU在每个机器周期的S6期间查询每个中断请求的标志位。
Ø中断响应时间 = 1个查询机器周期 + 2个调用中断函数周期= 3个机器周期,这也是对中断请求做出响应所需的最短时间。
3、中断撤销
1.定时/计数器中断:硬件自动撤销
2.外部中断:脉冲触发:自动
3.电平触发:外加电路
4.串口中断:软件撤销
4、中断服务函数
C51中断函数的声明格式:
void 函数名 (void) interrupt n [using m]
interrupt n,表示是关于中断源n的中断服务函数;
using m,表示该中断函数将使用第m组工作寄存器。缺省为当前工作寄存器组。
【注意】1、中断服务函数既没有返回值,也没有调用参数; 2、中断服务函数只能由系统调用,不能被其他函数调用。
4、中断编程及应用
重新认识实例1的程序
#include<reg51.h>
sbit p1_0=P1^0;
int0_srv() interrupt 0{
p1_0=!p1_0;
}
main(){
IT0=1;
IE=0x81;
while(1);
}
【注意】中断允许设置也可采用位变量实现,即EX0=1,EA=1;
实例2 将第4章实例3改用中断方式实现
问题:
查询法需占用大量CPU机时,如何降低按键检测开销?
中断法——有键闭合时才检测键盘(获取闭合键号)
硬件更改:
①增加一个4输入与门器件U3→行线分接输入端,输出端接P3.2(INT0);②键盘连线改接在P2口。
软件更改:
①主函数中进行中断初始化,中断函数中查找闭合键号并刷新LED显示;
②每次中断返回前都应将列电平置为全低,行电平置为全高,为下次中断做准备 。
#include<reg51.h>
char led_mod[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,//1ed字模
0x7f,0x6f,0x77,0x7c,0x58,0x5e,0x79,0x71};
char key_buf[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d, //键值
0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};
void getKey() interrupt 0{ //中 断函数
char key_scan[]={0xef,0xdf,0xbf,0x7f}; //键扫描码
char i=0,j=0;
for(i=0;i<4;i++){
P2= key_scan[i]; //输出扫描码
for(j=0;j<16;j++){
if(key_buf[j]==P2){ //读键值,并判断键号
P0=led_mod[j]; //显示闭合键键号”
break;
}
}
}
P2=0x0f; //为下次中断做准备
}
void main(void){
P0=0x00; //开机黑屏
IT0=1; //脉冲触发
EX0=1; //INT0允许
EA=1; //总中断允许
P2 = 0x0f; //为首次中断做准备,列线全为0,行线全为1
while(1); //模拟其他程序功能
}
仿真运行图如下:
实例3 将第4章实例2改用中断方式实现
问题:当CPU运行于LED循环环节时,将因不能及时检测按键状态,而使按键操作不灵敏。
硬件改动:增加一只4输入与门电路,使按键闭合电平作为外部中断信号。
软件改动:将标志位修改功能放在中断函数中进行。
#include<reg51.h>
char led[]={0xfe,0xfd,0xfb,0xf7};//LED花样数据
bit dir=0,run=0; //全局变量
void delay (unsigned int time); //键控中断函数
key() interrupt 0 {
switch(P0 & 0x0f){ //修改标志位状态
case 0x0e:run=1;break;
case 0x0d:run=0,dir=0;break;
case 0x0b:dir=1;break;
case 0x07:dir=0;break;
}}
void main(){
char i;
IT0=1;EX0=1;EA=1;//边沿触发、INT0允许、 总中断允许
while(1){
if(run)
if(dir) //若run=dir=1,自上而下流动
for(i=0;i<=3;i++){
P2=led[i];
delay(200);
}
else //若run=1,dir=0, 自下而上流动
for(i=3;i>=0;i--) {
P2=led[i];
delay(200);
}
else P2=0xff; //若run=0,灯全灭
}}
void delay(unsigned int time){
unsigned int j = 0;
for(;time>0;time--)
for(j=0;j<125;j++);
}
运行效果——按键动作灵敏度明显增强
本篇小结
1、中断是指在突发事件到来时先中止当前正在进行的工作,转而去处理突发事件。待处理完成后,再返回到原先被中止的工作处,继续进行随后的工作。
2、中断的核心问题包括,51单片机的中断源、中断控制寄存器、中断处理过程。
3、C51中断函数的声明格式为:void 函数名 (void) interrupt n [using m]
更多推荐
所有评论(0)