#太原理工大学机器人团队#51单片机20天学习打卡——Day7

单片机中断系统

首先要明确一个概念,定时器是单片机模块的一个资源,确确实实存在的一个模块,而中断,只是单片机的一种运行机制。

1.定时器中断的应用

*****标准51单片机中控制中断的寄存器有两个,一个是中单使能寄存器,一个是中断优先级寄存器(当然现在一些增强型的51单片机可能不止这两个)。

​ 图1: IE——中断使能寄存器的位分配(地址0xA8,可位寻址)

76543210
符号EA_ET2ESET1EX1ET0EX0
复位值0_000000

​ 图2: IE——中断使能寄存器的位描述

符号描述
7EA总中断使能位
6__
5ET2定时器2中断使能
4ES串口中断使能
3ET1定时器1中断使能
2EX1外部中断1使能
1ET0定时器0中断使能
0EX0外部中断0使能

*中断使能寄存器IE的位0~5控制6哥中断使能,而第6位没用用到,第7位是总开关。

以下是数码管动态显示程序用中断实现的代码(加入消隐处理):

#include<reg52.h>
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;
unsigned char code Led Char[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
unsigned char LedBuff[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}       //数码管显示缓冲区
unsigned char i=0;          //动态扫描的索引
unsinged int cnt=0;         //记录T0中断次数
unsigned char flagls=0;     //1秒定时标志
void main()
{
unsigned long sec=0;        //记录经过的秒数
EA=1;                       //使能总中断
ENLED=0;
ADDR3=1;                    //因为需要动态改变数码管的位选,所以ADDR0~2不需要初始化了
TMOD=0x01;
TH0=0xFC;                   //定时1ms
TL0=0x67;
ET0=1;                      //使能T0中断
TR0=1;                      //启动T0
while(1)
{
if(flagls==1)               //判断1秒定时标志
{                      
flagls=0;                   //1秒定时标志清零
sec++;                      //秒计数自加1
//以下代码将sec按十进制从低到高依次提取并转为数码管显示字符
LedBuff[0]=LedChar[sec%10];
LedBuff[1]=LedChar[sec/10%10];
LedBuff[2]=LedChar[sec/100%10];
LedBuff[3]=LedChar[sec/1000%10];
LedBuff[4]=LedChar[sec/10000%10];
LedBuff[5]=LedChar[sec/100000%10];
}
}
}
/*定时器0中断服务函数*/
void interruptTimer0() interrupt 1
{
TH0=0xFC;                   
TL0=0x67;
cnt++;
if(cnt>=1000)            //中断1000次即一秒
{
cnt=0;                  //清零计数值以重新开始下一秒计时
flagls=1;               //设置1秒定时标志为1
}
//以下代码王城数码管的动态扫描刷新
P0=0xFF;               //显示消隐
switch(i)
{
case 0:ADDR2=0;ADDR1=0;ADDR0=0;i++;P0=LedBuff[0];break;
case 1:ADDR2=0;ADDR1=0;ADDR0=1;i++;P0=LedBuff[1];break;
case 2:ADDR2=0;ADDR1=1;ADDR0=0;i++;P0=LedBuff[2];break;
case 3:ADDR2=0;ADDR1=1;ADDR0=1;i++;P0=LedBuff[3];break;
case 4:ADDR2=1;ADDR1=0;ADDR0=0;i++;P0=LedBuff[4];break;
case 5:ADDR2=1;ADDR1=0;ADDR0=1;i=0;P0=LedBuff[5];break;
drfault:break;
}
}

*****代码中有两个函数,第一个是主函数,第二个是定义的中断函数。

​ 中断查询序列

中断函数编号中断名称中断标志位中断使能位中断向量地址默认优先级
0外部中断0IE0EX00x00031(最高)
1T0中断TF0ET00x000B2
2外部中断1IE1EX10x00133
3T1中断TF1ET10x001B4
4UART中断TI/RIES0x00235
5T2中断TF2/EXF2ET20x002B6

程序中就用到了第二行的中断使能位ET0,当ET0置1,并且它的中断标志位TF0变为1时,就是触发T0中断,这时候就会执行中断函数,单片机认出中断函数的编号1(如程序中interrupt 1),这样就找到了中断函数,然后系统开始调用中断函数,中断函数执行完成后程序又会跑到原来主函数中被中断的语句继续执行下面的程序,也就是回到主函数的while(1)函数中继续循环执行。这样就保证了动态显示间隔时固定的1ms,不会因为程序执行时间不一致的原因导致数码管显示的抖动了。

3.中断的优先级

​ IP——中断优先级积存的的位分配(地址0xB8,可位寻址)

76543210
符号__PT2PSPT1PX1PT0PX0
复位值__000000

​ IP——中断优先级的寄存器的位描述

符号描述
7_保留
6_保留
5PT2定时器2中断优先级控制位
4PS串口中断优先级控制位
3PT1定时器1中断优先级控制位
2PX1外部中断1中断优先级控制位
1PT0定时器0中断优先级控制位
0PX0外部中断0中断优先级控制位

*中断优先级有两种:抢占优先级,固有优先级。

*IP这个寄存器的每一位,表示对应终端的抢占优先级,每一位的复位值都是0,当把某一位的值设置为1时,这意味的优先级就比其他位高。

*抢占优先级的概念:优先级高的中断可以打断优先级低的中断的执行,从而形成嵌套。即处理完高优先级后再返回处理低优先级的中断。

*固有优先级不具有抢占的特性,即使在低优先级中断执行过程中又发生了高优先级的中断,那么高优先级的中断也只能等到低优先级的中断执行完后才能得到响应。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值