我把程序改了下,可是按鍵時只有第一次按下有作用,有時復位鍵有作用,我懷疑是按鍵消抖作用需要時間太長,和掃描形成了時間差,您覺得是不是有這樣的可能。普中的板子是會在長按按鍵一段時間后自動取消置高電平的嗎?- #include <reg52.h>
- #include <intrins.h>
- typedef unsigned char u8;
- typedef unsigned int u16;
- typedef unsigned long u32;
- sbit LS = P2; //38譯碼器引腳編號,選擇數碼管
- sbit number = P0; //發送轉換表(段碼)
- sbit key1 = P3^1; //復位
- sbit key2 = P3^0; //開始/暫停
- sbit key3 = P3^2; //
- sbit key4 = P3^3; //
- u8 code smgduan[17] = {
- 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
- 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
- };//數碼管轉換表
- u8 LedBuff[8] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- } ;//數碼管緩沖區
- u8 KeySt[4] = {
- 1, 1, 1, 1
- };//按鍵電平狀態儲存區
- bit StopwatchRunning = 0; //秒表是否運行(確定是否暫停)
- bit StopwatchRefresh = 1; //秒表是否要刷新
- u8 mseconds = 0; //計數毫秒部分
- u8 seconds = 0; //計數秒部分
- u8 minutes = 0; //計數分鐘部分
- u8 T0RH = 0; //T0重裝高位
- u8 T0RL = 0; //T0重裝低位
- void ConfigTimer0(u16 ms); //配置定時器
- void StopwatchDisplay(); //顯示函數(數字分割顯示)
- void KeyDriver(); //檢測按鍵,執行指令(主函數中調用)
- void LedScan();
- void KeyScan();
- void main()
- {
- EA = 1; //打開總中斷
- ConfigTimer0(2); //定時器2ms
- while(1)
- {
- if(StopwatchRefresh) //是否更新數碼管顯示
- {
- StopwatchRefresh = 0;
- StopwatchDisplay();
- }
- LedScan();
- KeyScan();
- KeyDriver(); //調用按鍵驅動
- }
- }
- /*函數部分*/
- void ConfigTimer0(u16 ms)//配置定時器
- {
- u32 tmp;
-
- tmp = 11059260 / 12;
- tmp = (tmp * ms) / 1000;
- tmp = 65536 - tmp;
- tmp += 18; //時間補償
- T0RH = (u8)(tmp >> 8);
- T0RL = (u8)tmp;
- TMOD &= 0XF0; //僅改變后四位(置零)
- TMOD |= 0X01;
- TH0 = T0RH;
- TL0 = T0RL;
- ET0 = 1;
- TR0 = 1;
- }
- void StopwatchDisplay()//顯示函數(數字分割顯示)
- {
- signed char i;
- u8 buf[2]; u8 minbuf[2];
- LedBuff[0] = smgduan[mseconds % 10]; //毫秒轉換
- LedBuff[1] = smgduan[mseconds / 10];
- buf[1] = seconds % 10;
- buf[2] = (seconds / 10) % 10;
- minbuf[1] = (minutes) % 10;
- minbuf[2] = (minutes / 10) % 10;
- for(i = 1; i < 3; i ++) //秒位數字轉換0
- {
- if(buf[i] == 0)
- {
- LedBuff[i + 2] = 0X00;
- }
- else break;
- }
- for(i = 1; i < 3; i ++) //分位數字轉換0
- {
- if(minbuf[i] == 0)
- {
- LedBuff[i + 5] = 0X00;
- }
- else break;
- }
- for(i = 1 ; i < 3; i ++) //秒和分位數字轉換
- {
- LedBuff[i + 2] = smgduan[buf[i]];
- LedBuff[i + 5] = smgduan[minbuf[i]];
- }
- LedBuff[2] = 0X40; //"-"符號顯示
- LedBuff[5] = 0x40;
- }
- void StopwatchAction()//秒表的啟動與暫停
- {
- if (StopwatchRunning) //已啟動則停止
- StopwatchRunning = 0;
- else //未啟動則啟動
- StopwatchRunning = 1;
- }
- void StopwatchReset()//秒表復位
- {
- StopwatchRunning = 0;
- mseconds = 0;
- seconds = 0;
- minutes = 0;
- StopwatchRefresh = 1;
- }
- void KeyDriver()//檢測按鍵,執行指令(主函數中調用)
- {
- static u8 i;
- static u8 backup[4] = {1, 1, 1 , 1};//鍵值對比樣本
- for(i = 0; i < 4; i ++)
- {
- if(backup[i] != KeySt[i])
- {
- if(backup[i] != 0)
- {
- if(i == 0)
- {
- StopwatchReset(); //重置
- }
- else if(i == 1)
- {
- StopwatchAction(); //開始/暫停
- }
- }
- else if(i == 1)
- {
- StopwatchAction(); //開始/暫停
- }
- backup[i] = KeySt[i]; //刷新備份,作為下次判定樣本
- }
- }
- }
- void KeyScan()//按鍵掃描
- {
- u8 i = 0;
- static u8 keybuf[4] = {
- 0xFF, 0xFF, 0xFF, 0xFF
- };
- keybuf[0] = (keybuf[0] << 1) | key1; //鍵值輸入,8次分位輸入,消抖
- keybuf[1] = (keybuf[1] << 1) | key2;
- keybuf[2] = (keybuf[2] << 1) | key3;
- keybuf[3] = (keybuf[3] << 1) | key4;
- for(i = 0; i < 4; i ++)
- {
- if(keybuf[i] == 0X00)
- {
- KeySt[i] = 0;
- }
- else if(keybuf == 0XFF)
- {
- KeySt[i] = 1;
- }
- }
- }
- void LedScan()//數碼管掃描
- {
- u8 i = 0;
- for( ; i < 8; i ++)
- {
- P2 = (P2 & 0XE3) | (i << 2);
- P0 = LedBuff[i];
- _nop_(); //延時兩個機器周期
- _nop_();
- P0 = 0x00;
- }
- }
- void StopwatchCount()//秒數統計
- {
- if(StopwatchRunning)
- {
- mseconds ++;
- if(mseconds >= 100)
- {
- mseconds = 0;
- seconds ++;
- if(seconds >= 60)
- {
- seconds = 0;
- minutes ++;
- }
- if(minutes >= 60)
- {
- minutes = 0;
- }
- }
- StopwatchRefresh = 1; //提醒刷新
- }
- }
- void InterruptTimer0() interrupt 1 //中斷函數
- {
- static u8 tmr10ms = 0;
-
- TH0 = T0RH;
- TL0 = T0RL;
- tmr10ms ++;
- if(tmr10ms >= 5) //10ms記一次數
- {
- tmr10ms = 0;
- StopwatchCount();
- }
- }
復制代碼 |