關於51微控制器中斷標誌的一個小問題
阿新 • • 發佈:2018-12-27
第一張圖片:
第二張圖片:
程式碼:
此為數碼管顯示計數的程式,但筆者發現,當代碼為第一張圖片時候,當計數到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,沒有影響。 當然這裡只是筆者的愚見,還請前輩多多指點~#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; } }