【51单片机学习过程记录】11 中断之外部中断的应用

来源:互联网 发布:哪个网络电话软件好 编辑:程序博客网 时间:2024/04/29 19:45

声明:【51单片机学习过程记录】全是我自己学习、实践所记录的过程,我只是菜鸟,所有论点和观点仅代表我个人,不能确定是这个技术的真理。我的目的是学习和有可能成为可以向别人分享的经验,因此有错误我会虚心接受,并认真改正。


1了解外部中断


从programmer's guid中可以看到上文,和外部中断相关的描述:

就是说对于外部中断,INT0和INT1必须设置为1,且根据 是电平触发  或者是  沿边触发  去设置TCON寄存器中相关的位 IT0 和 IT1。



再从TCON寄存器中和外部中断相关位看到:

IE1   外部中断1沿边标志位。 当外部中断跳变被检测后,由硬件设置,当中断被处理后也是由硬件清除。

IT1  外部中断1中断类型选择位。如果选择   下降沿触发中断,则软件设置该位为 1 ,设置为 0 则是  低电平触发。

IE0和IT0一样。


2 实现代码:

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int


sbit int0=P3^2;
sbit int1=P3^3;
sbit duan=P2^6;
sbit wei=P2^7;
uchar i,j;interflag;

uchar code note0[]={0x79,0x76,0x6,0x37,0x31,0x3f};
uchar code note1[]={0x79,0x76,0x6,0x37,0x31,0x6};
uchar code guwei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};


void delay()
{

 uint x,y;

for(x=1;x>0;x--)

for(y=210;y>0;y--);

}


void displayex0()
{

TR0=1; //启动显示函数后,开启定时器0
while(interflag!=2)//未产生 定时计数器0 的中断时,显示数码管内容
{
for(i=0;i<6;i++)
{
P0=guwei[i];
wei=1;
wei=0;
P0=note0[i];
duan=1;
duan=0;
delay();//数码管动态显示中起到消影作用的延时。
}
}
P0=0xff;//定时计数器0设定的时间到后,数码管不再显示
wei=1;
wei=0;
}


void displayex1()
{

TR0=1;
while(interflag!=2)
{
for(i=0;i<6;i++)
{
P0=guwei[i];
wei=1;
wei=0;
P0=note1[i];
duan=1;
duan=0;
delay();
}
}
P0=0xff;
wei=1;
wei=0;
}


void main()
{


EA=1;//IE register,enable external interrupts

EX1=1;
EX0=1;
IT1=0;//TCON register,low level triggers interrupt
IT0=0;
int0=1;
int1=1;

ET0=1;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=0;


j=0;


while(1)//主函数等待外部中断
{
if(interflag==1)displayex0();//外部中断0产生,调用显示函数0
if(interflag==3)displayex1();//外部中断1产生,调用显示函数1
}
}


void exinterrupt0() interrupt 0
{

delay();
if(int0==0)
{
while(!int0); //若外部中断0产生,interflag=1
interflag=1;
}
}


void timer0() interrupt 1
{

TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
j++;
if(j==60) //20时为1s,这里设定数码管显示的时间为3s。
{
j=0;
interflag=2;
TR0=0;
}
}


void exinterrupt1() interrupt 2
{

delay();
if(int1==0)
{
while(!int1);
interflag=3;//若外部中断1产生,interflag=3。
}
}


3代码分析

为代码中的注释。

4应用小结

一篇篇文章到此,应该是继续记录中断的,所以一次把两个外部中断都用上。

因此应用思路是自己想的,就是:

开启两个外部中断,然后按下中断按键,在数码管显示exint0或者exint1。

数码管采取动态显示。

因为数码管动态显示需要一段时间,所以我加入了 定时计数器0  去设定数码管显示的时间。

调试中出现问题需要注意的地方:

1,数码管显示的时间是有限的,因此  定时计数器0 开启后,显示结束后需要关闭定时计数器,以及关闭数码管,即不作显示。

2,前文记录中有讲述过数码管的动态显示,但是和此文有区别,一个是显示的位数不同,第二个是这里显示是有时间限定,到时间后数码管会熄灭,其中出现需要消影的操作。   简单说,这里加入了  数码管动态显示  中 消影 的操作

P0=guwei[i];
wei=1;
wei=0;
P0=note1[i];
duan=1;
duan=0;
delay();

其实就是添加了delay()延时函数进行消影,且延时的时间需要调整得合理些,稍微长一点。


最后,此应用代码是我自己的思路实现,未优化或者考虑其他方法实现,因此,代码中有不合理或者多余地方请见谅。


0 0
原创粉丝点击