|
AT89C51制作的簡單計數(shù)器
作者:大俠 明浩 原載:磁動力電子論壇
|
網(wǎng)上好友大俠畫了一個計數(shù)器的電路圖讓我?guī)兔憘€軟件,抽空寫了一個。他做好了電路我就把程序給他燒寫實驗,稍微修改后達到他的要求。
圖中可以看到本制作的主要核心電路是用AT89C51組成的按鍵取值電路,S3S4分別控制計數(shù)值的加減。數(shù)碼管使用的是共陽極通過3906控制。
這個計數(shù)器主要用于對鍵的按鍵次數(shù)計數(shù),用于鼠標中的微按鈕或其它按鈕做QC測試用。所以在軟件中用了取兩次定時中斷的鍵值做比較以達到簡單防抖動和取健值的目的。讀者朋友可以自行修改程序以適合自己的電路。本計數(shù)器的計數(shù)范圍為0-999999,最大的頻率為50Hz,當然這些參數(shù)都可以根據(jù)需要調(diào)整。程序使用的是匯編延時程序,可以改用C寫,沒有任何關(guān)系只是我偷懶從舊的程序中拷過來用。
 |
| 原理圖(點擊看大圖) |
 |
| 實驗板 |
#include <AT89X51.H> #define Key_UP P3_6 //上調(diào) #define Key_DOWN P3_7 //下調(diào) #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; //可位尋址的狀態(tài)寄存器 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; //設(shè)定時器0為模式1,16位模式 TH0=0xB1; TL0=0xDF; //設(shè)定時值為20000us(20ms) TR0 = 1; //開始定時 while(1); }
//定時器0中斷外理中鍵掃描和顯示 void KeyAndDis_Time0(void) interrupt 1 using 2 { TH0=0xB1; TL0=0xDF; //設(shè)定時值為20000us(20ms)
NewKeyUP = Key_UP; //取新的鍵值 NewKeyDOWN = Key_DOWN;
if (!OldKeyUP && NewKeyUP) //鍵放開時,這里的中斷為20ms左右(定時值非自動裝載所以多于20ms) Count++; if (!OldKeyDOWN && NewKeyDOWN) Count--; //這里Conut為int 沒有做負數(shù)等處理,有需要自行加上 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 }
|