分享一個剛開始學51時的一個矩陣鍵盤掃描程序
算法還是比較簡單的,供初學者學習
單片機源程序如下:- <span style="line-height: 1.5;">//此程序可以實現短按鍵、長按鍵、組合鍵三種操作。雙擊按鍵操作還未實現,要進一步研究</span>
- //
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar flag;
- uchar key;
- bit key_flag;
- bit time_10ms_ok=0;
- bit time_2ms_ok=0;
- sbit dula=P2^6; //段選信號的鎖存器控制
- sbit wela=P2^7; //位選信號的鎖存器控
- uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
- 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- uchar code wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
- //數碼管各位的碼表
- void delay(unsigned int i)
- {
- unsigned int m,n;
- for(m=i;m>0;m--)
- for(n=90;n>0;n--);
- }
- void display(uchar a,b,c,d,e,f)
- {
- P0=table[a];
- dula=1;
- dula=0;
- P0=wei[0];
- wela=1;
- wela=0;
- delay(5);
- P0=table[b];
- dula=1;
- dula=0;
- P0=wei[1];
- wela=1;
- wela=0;
- delay(5);
- P0=table[c];
- dula=1;
- dula=0;
- P0=wei[2];
- wela=1;
- wela=0;
- delay(5);
- P0=table[d];
- dula=1;
- dula=0;
- P0=wei[3];
- wela=1;
- wela=0;
- delay(5);
- P0=table[e];
- dula=1;
- dula=0;
- P0=wei[4];
- wela=1;
- wela=0;
- delay(5);
- P0=table[f];
- dula=1;
- dula=0;
- P0=wei[5];
- wela=1;
- wela=0;
- delay(5);
- }
- void InitTimer0(void)
- {
- TMOD = 0x01;
- TH0 = 0xFC;//延時1ms,請在中斷處理函數中,重新裝入該數值。
- TL0 = 0x6;
- TR0=1;
- EA = 1;
- ET0 = 1;
- }
- void Timer0Interrupt(void) interrupt 1
- {
- TH0 = 0xFC;//延時1ms,請在中斷處理函數中,重新裝入該數值。
- TL0 = 0x6;
- flag++;
- if(flag==10)
- {flag=0;
- time_10ms_ok=1;}
- if(flag%2==0)
- time_2ms_ok=1;
- }
- uchar KeyRead( void )
- {
- uchar ReadData; // 讀按鍵的實時值
- static uchar i; //長按鍵按下時間計數
- static uchar trg,cont,cont1; //按鍵按下時的狀態,trg用來描述短按鍵,cont用來描述長按鍵
- P3=0x0f;
- ReadData=P3;
- P3=0xf0;
- ReadData=(ReadData | P3)^0xff;
- //if...else; 語句作用 是當第一次按鍵按下時,退出按鍵掃描程序,
- //一來可以實現消抖,二來可以防止第一次按下按鍵時,程序剛好執行到按鍵掃描程序的中間部分,造成結果不準確
- if(ReadData==cont1)
- {
- trg = ReadData & (ReadData ^ cont);
- cont = ReadData;
- }
- else
- {
- cont1=ReadData;
- return;
- }
- if(cont) //長按鍵計時
- {
- i++;
- }
- else //按鍵釋放時
- {
- i=0;
- return;
- }
- switch(trg)
- {
- case 0x11: key=0;key_flag=1; break;
- case 0x21: key=1;key_flag=1; break;
- case 0x41: key=2;key_flag=1; break;
- case 0x61: key=8;key_flag=1; break; //1和2同時按下組成的組合鍵
- case 0x81: key=3;key_flag=1; break;
- case 0x12: key=4;key_flag=1; break;
- case 0x22: key=5;key_flag=1; break;
- case 0x42: key=6;key_flag=1; break;
- case 0x82: key=7;key_flag=1; break;
- case 0x14: key=8;key_flag=1; break;
- case 0x24: key=9;key_flag=1; break;
- case 0x44: key=10;key_flag=1; break;
- case 0x84: key=11;key_flag=1; break;
- case 0x18: key=12;key_flag=1; break;
- case 0x28: key=13;key_flag=1; break;
- case 0x48: key=14;key_flag=1; break;
- case 0x88: key=15;key_flag=1; break;
- }
- if(i==100)
- {
- i=90;
- switch(cont)
- {
- case 0x11: key++;key_flag=1; break;
- case 0x21: key++;;key_flag=1; break;
- case 0x41: key++;;key_flag=1; break;
- case 0x81: key++;;key_flag=1; break;
- case 0x12: key++;;key_flag=1; break;
- case 0x22: key++;;key_flag=1; break;
- case 0x42: key++;;key_flag=1; break;
- case 0x82: key++;;key_flag=1; break;
- case 0x14: key++;;key_flag=1; break;
- case 0x24: key++;;key_flag=1; break;
- case 0x44: key++;;key_flag=1; break;
- case 0x84: key++;;key_flag=1; break;
- case 0x18: key++;;key_flag=1; break;
- case 0x28: key++;;key_flag=1; break;
- case 0x48: key++;;key_flag=1; break;
- case 0x88: key++;;key_flag=1; break;
- }
- }
- return key;
- }
- void main(void)
- {
- uchar a,b,c,d,e,f;
- InitTimer0();
- while(1)
- {
- if(key_flag )
- {
- key_flag=0;
- f=e;
- e=d;
- d=c;
- c=b;
- b=a;
- a=key;
- }
- if(time_10ms_ok)
- {
- time_10ms_ok=0;
- KeyRead();
- }
- display(a,b,c,d,e,f);
- }
- }
復制代碼
|