仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif (113.18 KB, 下載次數(shù): 44)
下載附件
2024-1-2 21:55 上傳
51hei截圖_20240102162101.png (330.69 KB, 下載次數(shù): 35)
下載附件
2024-1-2 16:21 上傳
單片機源程序如下:
- #include<reg52.h>
- sbit KEY1 = P3^0; //計次
- sbit KEY2 = P3^1; //從快到慢顯示計次數(shù)
- sbit KEY3 = P3^2; //復位
- sbit KEY4 = P3^3; //啟停秒表
- unsigned char code LedChar[] = { //數(shù)碼管顯示字符轉(zhuǎn)換表
- 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
- 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
- };
- unsigned char LedBuff[6] = { //數(shù)碼管顯示緩沖區(qū)
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
- };
- unsigned char KeySta[4] = {1,1,1,1}; //當前按鍵狀態(tài)
- unsigned char T0RH = 0;
- unsigned char T0RL = 0;
- // static unsigned char Dec[10] = 0;
- // static unsigned int Int[10] = 0;
- bit kd = 0;
- bit lk = 1;
- bit stopwatchRefresh = 1;
- bit stopwatchRunning = 0;
- unsigned char DecimalPart = 0;
- unsigned int IntegerPart = 0;
- void ConfigTimer0(unsigned int ms);
- void stopwatchDisplay();
- void KeyDriver();
- void main()
- {
- EA = 1;
- ConfigTimer0(2);
- while(1)
- {
- if(stopwatchRefresh)
- {
- stopwatchRefresh = 0;
- stopwatchDisplay();
- }
- KeyDriver();
- }
- }
- void ConfigTimer0(unsigned int ms)
- {
- unsigned long tmp;
-
- tmp = 11059200/12;
- tmp = (tmp*ms)/1000;
- tmp = 65536 - tmp;
- tmp +=18; //定時誤差補償
-
- T0RH = (unsigned char)(tmp>>8);
- T0RL = (unsigned char)tmp;
- TMOD &=0xf0;
- TMOD |=0X01;
- TH0 = T0RH;
- TL0 = T0RL;
- ET0 = 1;
- TR0 = 1;
- }
- void stopwatchDisplay()
- {
- signed char i;
- unsigned char buf[4];
- LedBuff[0] = LedChar[DecimalPart%10];
- LedBuff[1] = LedChar[DecimalPart/10];
- buf[0] = IntegerPart%10;
- buf[1] = IntegerPart/10%10;
- buf[2] = IntegerPart/100%10;
- buf[3] = IntegerPart/1000%10;
- for(i=3;i>=1;i--)
- {
- if(buf[i]==0)
- {
- LedBuff[i+2]=0xFF;
- }else break;
- }
- for(;i>=0;i--)
- {
- LedBuff[i+2] = LedChar[buf[i]];
- }
- LedBuff[2] &=0x7f;
- }
- void Stopwatchjc()
- {
- signed char i;
- unsigned char buf[4];
- static unsigned char Dec[10] = 0;
- static unsigned int Int[10] = 0;
- static char cnt = 0;
- static char cnt1 = 0;
- Dec[cnt] = DecimalPart;
- Int[cnt] = IntegerPart;
- cnt++;
- if(kd == 1)
- {
- LedBuff[0] = LedChar[Dec[cnt1]%10];
- LedBuff[1] = LedChar[Dec[cnt1]/10];
- buf[0] = Int[cnt1]%10;
- buf[1] = Int[cnt1]/10%10;
- buf[2] = Int[cnt1]/100%10;
- buf[3] = Int[cnt1]/1000%10;
- for(i=3;i>=1;i--)
- {
- if(buf[i]==0)
- {
- LedBuff[i+2]=0xFF;
- }else break;
- }
- for(;i>=0;i--)
- {
- LedBuff[i+2] = LedChar[buf[i]];
- }
- LedBuff[2] &=0x7f;
-
- cnt1++;
-
-
- }
-
- }
- void Stopwatchsy()
- {
- stopwatchRunning = 0;
- kd = 1;
- stopwatchRefresh = 1;
- }
- void StopwatchAction()
- {
- stopwatchRunning = ~stopwatchRunning;
- }
- void StopwatchReset()
- {
- stopwatchRunning = 0;
- lk = 0;
-
- DecimalPart = 0;
- IntegerPart = 0;
- stopwatchRefresh = 1;
- }
- void KeyDriver() //按鍵驅(qū)動函數(shù)
- {
- static unsigned char backup[4] = {1,1,1,1}; //按鍵值備份,保存前一次的掃描值
- unsigned char i;
- for(i=0;i<4;i++)
- {
- if (KeySta[i] != backup[i]) //當前值與前次值不相等說明此時按鍵有動作
- {
- if (backup[i] == 0) //如果前次值為0,則說明當前是彈起動作
- {
- if(i==0)
- Stopwatchjc(); //計次
- else if(i==1)
- Stopwatchsy(); //從快到慢
- else if(i==2) //復位
- StopwatchReset();
- else if(i==3) //啟停秒表
- StopwatchAction();
-
- }
- backup[i] = KeySta[i]; //更新備份為當前值,以備進行下次比較
- }
- }
- }
- void LedScan()
- {
- static unsigned char i=0;
- P0 = 0xFF;
- switch(i) //每過1ms從低到高位刷新一個數(shù)碼管
- {
- case 0:P2=0x01;i++; P0= LedBuff[0]; break;
- case 1:P2=0x02;i++; P0= LedBuff[1]; break;
- case 2:P2=0x04;i++; P0= LedBuff[2]; break;
- case 3:P2=0x08;i++; P0= LedBuff[3]; break;
- case 4:P2=0x10;i++; P0= LedBuff[4]; break;
- case 5:P2=0x20;i=0; P0= LedBuff[5]; break;
- default :break;
- }
- }
- void KeyScan()
- {
- static unsigned char keybuf[4] ={ 0xFF,0xFF,0xFF,0xFF}; //掃描緩沖區(qū),保存一段時間內(nèi)的掃描值
- static unsigned char i=0;
- keybuf[0] = (keybuf[0]<<1) | KEY1; //緩沖區(qū)左移一位,并將當前掃描值移入最低位
- keybuf[1] = (keybuf[1]<<1) | KEY2; //緩沖區(qū)左移一位,并將當前掃描值移入最低位
- keybuf[2] = (keybuf[2]<<1) | KEY3; //緩沖區(qū)左移一位,并將當前掃描值移入最低位
- keybuf[3] = (keybuf[3]<<1) | KEY4; //緩沖區(qū)左移一位,并將當前掃描值移入最低位
- for(i=0;i<4;i++)
- {
- if (keybuf [i] == 0x00)
- { //連續(xù)8次掃描值都為0,即16ms內(nèi)都只檢測到按下狀態(tài)時,可認為按鍵已按下
- KeySta[i] = 0;
- }
- else if (keybuf[i] == 0xFF)
- { //連續(xù)8次掃描值都為1,即16ms內(nèi)都只檢測到彈起狀態(tài)時,可認為按鍵已彈起
- KeySta[i] = 1;
- }
- else
- {} //其它情況則說明按鍵狀態(tài)尚未穩(wěn)定,則不對KeySta變量值進行更新
- }
- }
- void StowatchCount()
- {
- if(stopwatchRunning)
- {
- DecimalPart++;
- if(DecimalPart>=100)
- {
- DecimalPart=0;
- IntegerPart++;
- if(IntegerPart>=100) // 10000
- {
- IntegerPart=0;
- }
- }
- stopwatchRefresh=1;
- }
- }
- void InterruptTimer0() interrupt 1
- {
- static unsigned char ter10ms = 0;
- TH0 = T0RH; //重新加載重載值
- TL0 = T0RL;
- LedScan(); //數(shù)碼管掃描顯示
- KeyScan(); //按鍵掃描
- ter10ms++;
- if (ter10ms>=5)
- {
- ter10ms = 0;
- StowatchCount();
- }
- }
復制代碼
仿真程序:
秒表記次+數(shù)碼管+51+按鍵.7z
(63.29 KB, 下載次數(shù): 31)
2024-1-2 21:56 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|