Author: Manba Cople
专业:IOT
说明:记录和输出学习内容
问题
最近在给小伙伴培训单片机中断时,小伙伴写了一段中断的代码(代码如下),出现每次执行完中断都会卡在中断程序中,无法恢复主程序。
#include<reg51.h>
unsigned char code table[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned int k,i=0,j=0;;
void LedFlash();
void delayms(uint xms)
{
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void InitINT0()
{
EA=1;
EX0=1;
IT0=1;
}
void ServeINT0() interrupt 0
{
LedFlash();
}
void LedFlash()
{
unsigned char m=0;
for(m=0;m<5;m++)
{
P1=0xf0;
delayms(100);
P1=0x0f;
delayms(100); //500*5*2=5s
}
}
void main()
{
InitINT0();
while(1)
{
for(k=0;k<=7;k++)
{
P1=table[k];
delayms(100); //8*500=4000
}
}
}
思考
出现这个问题的原因:是中断函数中的内容执行的时间超出了主程序执行的时间。但是,当我把delayms的时间调短后仍会出现卡住的现象。存在的另一个原因是delayms函数中变量的初始化问题,在该程序中,作者是将delayms的i、j变量定义为了全局变量,所以每次调用是i、j的初始值都是在原来的基础上累加的,所以整体的效果就是延时的时间较长,所以进入中断后无法恢复主程序。
修改
修改delayms函数中的变量定义位置即可。
void delayms(uint xms)
{
unsigned int i=0, j=0;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
进阶
在检查错误过程中,我是设置一个中断标志变量flag,每次中断来了执行flag=1,然后在主程序中根据flag的值判断是否执行原本应在中断中执行的程序,代码如下:
void ServeINT0() interrupt 0
{
flag = 1;
}
...
void main()
{
InitINT0();
while(1)
{
for(k=0;k<=7;k++)
{
P1=table[k];
delayms(100); //8*500=4000
}
if(flag==1)
{
LedFlash();
flag=0;
}
}
}
注意!!! 这样写同样会出现延时不准确的现象,所以delayms函数还是需要修改。
声明
以上理解均为本人自己理解,若有错误恳请指正,谢谢!