什么叫中断?
对于这个问题,我的理解是,单片机的功能其实并没有我们想象中的那么强大,不同于我们人类大脑的是,单片机在同一个时间只能完成一件事情。所以,单片机在同一个时间内是无法同时完成数码管的刷新和一个数的分离计算。
所谓中断,即在一个事情发生之后又发生另一件事情,这个时候,如果这个事情的优先级高的话,系统 优先处理更高优先级的一件事。
例如,你在看电视的时候,水烧开了,你就得先去冲水然后在回来看电视,冲水就是一个中断,而水开就是中断的原因,称为中断源。
51单片机的中断优先级只有两个。
作业:1.尝试修改程序,让我们的数码管只显示有效位,也就是高位的0不显示。
2.尝试写一个从999999开始倒计时的程序,并且改用定时器T1的中断来完成,通过写这个程序来掌握定时器和中断的应用。
参考答案
1.
#include
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char code tableChar[]=
{
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,
};
unsigned char divide[]={0,0,0,0,0,0};
unsigned char i=0;
signed int j=0;
unsigned long sec=0;
unsigned int cnt=0;
unsigned char light[]={0xdf,0xcf,0xc7,0xc3,0xc1,0xc0}; //有效位的真值表
void main()
{
TMOD=0x01;
TH0=0xfc; //setting 10ms
TL0=0x66;
TR0=1;
EA=1;
ET0=1;
while(1)
{
if(cnt>=1000)
{
cnt=0;
sec++;
divide[0]=sec%10;divide[1]=sec/10%10;divide[2]=sec/100%10;
divide[3]=sec/1000%10;divide[4]=sec/10000%10;divide[5]=sec/100000;
for(j=5;j>=0;j--)
{if(divide[j]>0) //用于计算数码管到有效位的地方
break;
}
}
}
}
void T0_Timer() interrupt 1
{
TH0=0xfc;
TL0=0x66;
cnt++;
wela=1;
P0=0xff;
switch(i)
{
case 0: P0=0xfe|light[j];wela=0;dula=1;P0=tableChar[divide[5]];dula=0;i++;break;//或运算用于关闭是零的数码管
case 1: P0=0xfd|light[j];wela=0;dula=1;P0=tableChar[divide[4]];dula=0;i++;break;
case 2: P0=0xfb|light[j];wela=0;dula=1;P0=tableChar[divide[3]];dula=0;i++;break;
case 3: P0=0xf7|light[j];wela=0;dula=1;P0=tableChar[divide[2]];dula=0;i++;break;
case 4: P0=0xef|light[j];wela=0;dula=1;P0=tableChar[divide[1]];dula=0;i++;break; //1101 1111
case 5: P0=0xdf|light[j];wela=0;dula=1;P0=tableChar[divide[0]];dula=0;i=0;break;
default:break;
}
}
2.
#include
sbit dula=P2^6;
sbit wela=P2^7;
unsigned long sec=999999;
unsigned int cnt=0;
unsigned char i=0;
unsigned char code tableChar[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,
};
unsigned char divide[]={0,0,0,0,0,0};
void main()
{
TMOD=0x01;
TH0=0xfc;
TL0=0x66;
TR0=1;
EA=1;
ET0=1;
while(1)
{
if(cnt>=1000)
{
cnt=0;
sec--;
divide[0]=sec%10;divide[1]=sec/10%10;divide[2]=sec/100%10;
divide[3]=sec/1000%10;divide[4]=sec/10000%10;divide[5]=sec/100000;
}
}
}
void T0_Timer() interrupt 1
{
TH0=0xfc;
TL0=0x66;
cnt++;
wela=1;
P0=0xff;
switch(i)
{
case 0: P0=0xfe;wela=0;dula=1;P0=tableChar[divide[5]];dula=0;i++;break;
case 1: P0=0xfd;wela=0;dula=1;P0=tableChar[divide[4]];dula=0;i++;break;
case 2: P0=0xfb;wela=0;dula=1;P0=tableChar[divide[3]];dula=0;i++;break;
case 3: P0=0xf7;wela=0;dula=1;P0=tableChar[divide[2]];dula=0;i++;break;
case 4: P0=0xef;wela=0;dula=1;P0=tableChar[divide[1]];dula=0;i++;break;
case 5: P0=0xdf;wela=0;dula=1;P0=tableChar[divide[0]];dula=0;i=0;break;
default:break;
}
}