关于51单片机中断标志的一个小问题

第一张图片:





第二张图片:




代码:

#include
     
     
      
      

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

unsigned char code LedChar[]={
	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 int cnt = 0;

void main()
{
	
	unsigned long sec = 0;
	

	ENLED = 0;
	ADDR3 = 1;
	TMOD = 0x01;
	TH0 = 0xFC;
	TL0 = 0x67;
	TR0 = 1;
	EA = 1;
	ET0 = 1;

	while(1)
	{
	   	if(cnt >= 1000)
		{
			cnt = 0;
			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];
		}		    
	}
}

 unsigned char i = 0; 
void InterruptTimer0()  interrupt 1		 
{
	TH0 = 0xFC;
	TL0 = 0x67;
	cnt++;
	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;
		default:break;
	}
}
     
     


此为数码管显示计数的程序,但笔者发现,当代码为第一张图片时候,当计数到30s时候,实际秒表是24s,而第二张图片加一个标志位时候确与实际一致。以下为笔者分析,有不足之处望前辈指点~
分析如下:
第一张图片程序实际上是有问题的,因为cnt是int型,也就是2个字节,51单片机是8位的,一次只能读写1个字节,所以当你判断cnt>=1000的时候是要执行好几条指令的,而如果刚判断了低字节还没来得及判断高字节,这时中断中cnt的值就变了,那就有可能导致判断错误。
也就是说假设当进行if (cnt>=1000)判断的时候,1ms到了进入中断cnt++可能cnt变成了1001或者更多,这样中断结束返回判断的时候cnt的值就不再是1000了,时间就变长了。
而第二张图片加了一个flag判断标志位,假设在满足了flag为1,if(flag==1)判断时,进入中断,可是cnt在中断时已经清0了,又是从1开始加(flag在这里始终为1),所以对中断完回去判断if,没有影响。

当然这里只是笔者的愚见,还请前辈多多指点~吐舌头



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

种瓜大爷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值