之前的代码用Delay(xms)延时,是阻塞性延时,程序会卡住20ms,还有while写检测按键松手一般会卡个500ms,这样程序会慢很多。
用定时器写按键就不会出现上面的问题
1. //定时器0初始化模板 //1毫秒@11.0592MHz 2. void Timer0_Init(void) //1毫秒@11.0592MHz 3. { 4. TMOD &= 0xF0; //设置定时器模式 5. TMOD |= 0x01; //设置定时器模式 6. TL0 = 0x66; //设置定时初值 7. TH0 = 0xFC; //设置定时初值 8. TF0 = 0; //清除TF0标志 9. TR0 = 1; //定时器0开始计时 10. ET0=1; 11. EA=1; 12. PT0=0; 13. }
1. void Timer0_Routine() interrupt 1 //定时器0的中断函数 2. { 3. static unsigned int T0Count,anjian; 4. 5. TL0 = 0x66; //设置定时初值 6. TH0 = 0xFC; //设置定时初值 7. T0Count++;anjian++; 8. if(anjian>=10)//10ms扫描一次按键 9. { 10. KeyScan(); 11. anjian=0;//清零 12. } 13. 14. if(T0Count>=1000) 15. { 16. //1000ms=1s,每一秒 17. T0Count=0; 18. } 19. 20. }
KeyScan(); 是要写的按键扫描函数,10ms一个中断扫描一次按键,不会影响主程序
模块化定时器扫描独立按键
1. #include <REGX52.H> 2. #include "KeyTimer0.h" 3. 4. unsigned char KeyNum; 5. 6. 7. //---------------------------------- 8. //对外获取按键值函数(外部调用的函数) 9. unsigned char GetKey_Num(){ 10. unsigned char t; 11. t = KeyNum; 12. KeyNum = 0; 13. return t;//返回t 14. }//KeyNum每次清零,还想要得到KeyNum的数值党返回值,所以新建一个变量t 15. //----------------------------------------- 16. 17. unsigned char GetKeyNum()//获取键码函数(内部调用) 18. { 19. unsigned char Key=0; 20. if(P3_1==0) Key=1;//按下Key代表键码,松手是Key = 0 21. if(P3_0==0) Key=2; 22. if(P3_2==0) Key=3; 23. if(P3_3==0) Key=4; 24. 25. return Key;//返回键码数值 26. } 27. //----------------------------------------------- 28. 29. void KeyScan(){ 30. static unsigned char nowKey,lastKey,K1count,K2count,K3count,K4count; 31. lastKey = nowKey; 32. 33. 34. nowKey = GetKeyNum();//获取按键值 35. 36. //按下&&抬起 有时间差10ms扫描,直到松手 37. 38. if(lastKey == 1 && nowKey == 1){K1count++;} 39. if(lastKey == 2 && nowKey == 2){K2count++;} 40. if(lastKey == 3 && nowKey == 3){K3count++;} 41. if(lastKey == 4 && nowKey == 4){K4count++;} 42. 43. if(K1count>=10 && K1count<=100 && nowKey==0) {KeyNum = 1;K1count=0;} //100ms-1s,短按 44. else if(K1count>100 && nowKey==0) {KeyNum = 11;K1count=0;} //大于1s,长按 45. if(K2count>=10 && K2count<=100 && nowKey==0) {KeyNum = 2;K2count=0;} 46. else if(K2count>100 && nowKey==0) {KeyNum = 22;K2count=0;} 47. if(K3count>=10 && K3count<=100 && nowKey==0) {KeyNum = 3;K3count=0;} 48. else if(K3count>100 && nowKey==0) {KeyNum = 33;K3count=0;} 49. if(K4count>=10 && K4count<=100 && nowKey==0) {KeyNum = 4;K4count=0;} 50. else if(K4count>100 && nowKey==0) {KeyNum = 44;K4count=0;} 51. }
每10ms扫描一次键码值,按下某按键1是K1count每10ms自加1,然后判断K1count在10-100(100ms-1s)之间且按键松开,认为是短按,记录当前键码值KeyNum = 1;
如果K1count大于100(大于1s)且按键松开,认为短按 ,记录键码数值KeyNum=11;
然后写一下主函数,测试一下短按与长按
1. #include <REGX52.H> 2. #include "Timer0.h" 3. #include "KeyTimer0.h" 4. 5. unsigned char Key_Value; 6. 7. void main() 8. { 9. Timer0_Init(); 10. while(1) 11. { 12. Key_Value = GetKey_Num(); 13. 14. if(Key_Value == 4) 15. P2_0=~P2_0; 16. if(Key_Value == 44) 17. P2_2=~P2_2; 18. } 19. 20. }