該計數器用於對按鍵次數的計算,比如滑鼠中的微按鈕或其它按鈕做QC測試用.該程序為彙編延時程序,用了取兩次定時中斷的鍵值做比較以達到簡單防抖動和取健值的目的.本計數器的計數範圍為0-999999,最大的頻率為50Hz. 該電路的主要核心電路是用AT89C51組成的按鍵取值電路,S3S4分別控制計數值的加減.3906控制數碼管使用的是共陽極. 程序如下: #include #define Key_UP P3_6 //上調 #define Key_DOWN P3_7 //下調 #define LED P0 #define LED1 P2_2 //LED控制 #define LED2 P2_3 //LED控制 #define LED3 P2_4 //LED控制 #define LED4 P2_5 //LED控制 #define LED5 P2_6 //LED控制 #define LED6 P2_7 //LED控制 unsigned char code LEDDis[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //共陽0-9的LED筆劃 static unsigned char bdata Key; //可位定址的狀態寄存器 sbit NewKeyUP = Key ^ 0; sbit NewKeyDOWN = Key ^ 1; sbit OldKeyUP = Key ^ 2; sbit OldKeyDOWN = Key ^ 3; static unsigned long data Count; static unsigned char LEDN[6]; void main(void) { void Delay_510(void); Count = 0; //初始化變數 Key = 0; EA = 1; //允許CPU中斷 ET0 = 1; //定時器0中斷打開 TMOD = 0x1; //設定時器0為模式1,16位模式 TH0=0xB1; TL0=0xDF; //設定時值為20000us(20ms) TR0 = 1; //開始定時 while(1); } //定時器0中斷外理中鍵掃描和顯示 void KeyAndDis_Time0(void) interrupt 1 using 2 { TH0=0xB1; TL0=0xDF; //設定時值為20000us(20ms) NewKeyUP = Key_UP; //取新的鍵值 NewKeyDOWN = Key_DOWN; if (!OldKeyUP && NewKeyUP) //鍵放開時,這裡的中斷為20ms左右(定時值非自動裝載所以多於20ms) Count++; if (!OldKeyDOWN && NewKeyDOWN) Count--; //這裡Conut為int 沒有做負數等處理,有需要自行加上 if (Count>999999) Count = 999999; LEDN[5]=Count/100000; LEDN[4] = (Count-100000*(long)LEDN[5])/10000; LEDN[3] = (Count-100000*(long)LEDN[5]-10000*(long)LEDN[4])/1000; LEDN[2] = (Count-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3])/100; LEDN[1] = (Count-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3]-100*(long)LEDN[2])/10; LEDN[0] = (Count-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3]-100*(long)LEDN[2]-10*(long)LEDN[1]); LED=LEDDis[LEDN[5]]; LED6 = 0; Delay_510(); LED6 = 1; LED=LEDDis[LEDN[4]]; LED5 = 0; Delay_510(); LED5 = 1; LED=LEDDis[LEDN[3]]; LED4 = 0; Delay_510(); LED4 = 1; LED=LEDDis[LEDN[2]]; LED3 = 0; Delay_510(); LED3 = 1; LED=LEDDis[LEDN[1]]; LED2 = 0; Delay_510(); LED2 = 1; LED=LEDDis[LEDN[0]]; LED1 = 0; Delay_510(); LED1 = 1; OldKeyUP = NewKeyUP; OldKeyDOWN = NewKeyDOWN; } void Delay_510(void) //延時510微秒 { #pragma asm MOV R0,#7DH MOV R1,#02H TSR1: DJNZ R0,TSR1 MOV R0,#7DH DJNZ R1,TSR1 #pragma endasm } (可以自行修改調整程序以適合自己的電路.) |