/*功能:實現按鍵計數,4位數碼管上顯示計數值, 實驗目的:按鍵穩定消抖,按鍵按下一次只執行一次操作,*/
單片機源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- typedef unsigned char uint8;
- #include<reg52.h>
- #include<intrins.h>
- typedef unsigned char uint8;
- typedef unsigned int uint16;
- typedef unsigned long uint32;
- sbit KEYGND=P3^4; //矩陣按鍵的一條列線,此程序將KEYGND=0,模擬出3個獨立按鍵的到地
- sbit K1 = P3^5;
- sbit K2 = P3^6;
- sbit K3 = P3^7;
- sbit LED = P1^7;
- uint8 code seg[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; //0-9段碼
- uint8 dis[4]={0,0,0,0};//位顯緩存
- uint16 count=0,ms;
- void KeyScan(void) //這里的松手檢測很好用,值得記住,在定時中斷函數中每20ms調用一次KeyScan(),非常完美,基本不會不影響其程序運行,
- { //按下只產生一次操作
- static bit KeyOnOff = 0; //這里一定要定義為靜態變量或者全局變量
- if(K1==0||K2==0||K3==0) // 判斷是否有按鍵按下
- {
- if(KeyOnOff == 0) // 自鎖變量
- {
- KeyOnOff = 1; // 屏蔽這句話,將沒有松手檢測,數字加的快
- if(K1==0) //按K1加數
- {
- count++;
- }
- if(K2==0) //按K2減數
- {
- count--;
- }
- if(K3==0) //按K3歸零
- {
- count=0;
- }
- }
- }
- else
- {
- KeyOnOff = 0; // 當沒有按鍵按下時 解鎖
- }
- }
- /*********************毫秒延時函數************************************/
- void delay1ms(unsigned char n)
- {
- unsigned char a,b,c;
- for(c=n;c>0;c--)
- for(b=102;b>0;b--)
- for(a=3;a>0;a--);
- }
- /**************************數據處理和刷新顯示函數*********************/
- void disp_count() //數碼管顯示函數
- {
- uint8 i=0;
- dis[0]=count%10; //計數器顯示用刷新函數
- dis[1]=count/10%10; //計數器顯示用刷新函數
- dis[2]=count/100%10; //計數器顯示用刷新函數
- dis[3]=count/1000%10; //計數器顯示用刷新函數
-
- if(dis[3]==0)
- {
- dis[3]=0x0a; //高位為零不顯示,
- if(dis[2]==0)
- {
- dis[2]=0x0a; //高位為零不顯示,
- if(dis[1]==0)
- {
- dis[1]=0x0a; //高位為零不顯示,
- }
- }
- }
- for (i=0;i<4;i++)
- {
- switch(i)
- {
- case 0: P0=0Xff; P2=0xfe;break; //這里的P0=0XFF的目的是消除鬼影
- case 1: P0=0Xff; P2=0xfd;break; //這里的P0=0XFF的目的是消除鬼影
- case 2: P0=0Xff; P2=0xfb;break; //這里的P0=0XFF的目的是消除鬼影
- case 3: P0=0Xff; P2=0xf7;break; //這里的P0=0XFF的目的是消除鬼影
- }
- P0=seg[dis[i]];
- delay1ms(1);
- }
- }
- /*************定時器初始化函數*************/
- void InitTimer0(void)
- {
- TMOD = 0x01;
- TH0 = 0xfc; //TH0=0xfc,TL0=0x66組合是1毫秒的初值
- TL0 = 0x66; //
- EA = 1;
- ET0 = 1;
- TR0 = 1;
- }
- /*****************************************主函數*******************************/
- void main()
- {
- P0=0xff; //4位數碼管段碼
- P2=0xff; //4位數碼管位碼
- KEYGND=0;
- InitTimer0(); //定時器初始化函數
- while(1)
- {
- disp_count(); //數碼管顯示函數
- delay1ms(1);
- }
- }
- /************************************INT0定時中斷函數****************************/
- void Timer0Interrupt(void) interrupt 1
- {
- TH0 = 0xfc;
- TL0 = 0x66;
- ms++;
- if(ms%20==0) //每20ms執行一次按鍵檢測
- {
- KeyScan();
- }
-
- }
復制代碼
|