单片机
返回首页

51单片机 按键,键盘检测

2017-01-08 来源:eefocus

但凡做和51单片机有关的东西,我们组都会用到按键..... 迷之有缘

独立按键的原理很简单,没有按键按下时,全部为高电平,按下时接触地变为地电平,检测是否有低电平来检测按下动作。

矩阵键盘稍微复杂一点,分别检测行,检测列,以此来确定按键位置。

注意的是,按下时会有抖动,因为写程序时,需要消抖。常用的方式是延时函数消抖。


 1 /*        

 2             独立按键扫描基本程序 @L2  2016/08/03 

 3                                                     */

 4 #include

 5 #define GPIO_KEY P1   //按键与P1口相连

 6 void Delay10ms(unsigned int c);

 7 unsigned char Key_Scan();

 8 

 9 void main(void)

10 {

11     unsigned char keyNum;

12     while (1)

13     {    

14         keyNum = Key_Scan();  //扫描键盘

15 

16         switch (keyNum)

17         {

18             case(0xFE) :      //返回按键K1的数据                

19                 break;

20             case(0xFD) :      //返回按键K2的数据                

21                 break;

22             case(0xFB) :      //返回按键K3的数据            

23                 break;

24             case(0xF7) :      //返回按键K4的数据

25                 break;

26             case(0xEF) :      //返回按键K5的数据

27                 break;

28             case(0xDF) :      //返回按键K6的数据

29                 break;

30             case(0xBF) :      //返回按键K7的数据

31                 break;

32             case(0x7F) :      //返回按键K8的数据

33                 break;

34             default:

35                 break;

36         }

37 

38 

39     }                

40 }

41 

42 

43 unsigned char Key_Scan()

44 {

45     unsigned char keyValue = 0 , i; //保存键值

46 

47     //--检测按键--//

48     if (GPIO_KEY != 0xFF)        //检测按键是否按下          若只连接P10~P13四个按键,则改为(GPIO_KEY | 0xF0)!= 0xFF;等等

49     {

50         Delay10ms(1);    //消除抖动

51 

52         if (GPIO_KEY != 0xFF)    //再次检测按键是否按下

53         {

54             keyValue = GPIO_KEY;

55             i = 0;

56             while ((i<50) && (GPIO_KEY != 0xFF))     //检测按键是否松开

57             {

58                 Delay10ms(1);

59                 i++;

60             }

61         }

62     }

63 

64     return keyValue; 

65 }

66 

67 

68 

69 void Delay10ms(unsigned int c) 

70 {

71     unsigned char a, b;

72     for (;c>0;c--)

73     {

74         for (b=38;b>0;b--)

75         {

76             for (a=130;a>0;a--);

77         }

78            

79     }       

80 }


检测原理类似,检测该按键对应IO口是否为低电平

 1 /*

 2           矩阵键盘4X4,数码管显示键值  @L2 2016/08/03

 3                                                             */    

 4 #include

 5 #define GPIO_DIG P1        

 6 #define GPIO_KEY P0

 7 

 8 unsigned char code DIG_CODE[17]={

 9 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

10 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

11 

12 unsigned char KeyValue;

13 void Delay10ms(unsigned int c);

14 void KeyDown();    

15 

16 void main(void)

17 {

18     while(1)

19     {

20         KeyDown();

21         GPIO_DIG = ~DIG_CODE[KeyValue];

22     }                

23 }

24 

25 void KeyDown(void)

26 {

27     char a = 0;

28     GPIO_KEY=0x0f;        // XXXX XXXX 四行四列

29     if(GPIO_KEY!=0x0f)  //读取按键是否按下

30     {

31         Delay10ms(1);  //消抖

32         if(GPIO_KEY!=0x0f)//再次检测键盘是否按下

33         {

34             

35             //测试行

36             GPIO_KEY=0XF0;

37             switch(GPIO_KEY)

38             {

39                 case(0X70):    KeyValue=0;break;           //0111 第一列有按下

40                 case(0XB0):    KeyValue=4;break;           //1011 第二列有按下

41                 case(0XD0):   KeyValue=8;break;           //1101 第三列有按下

42                 case(0XE0):    KeyValue=12;break;           //1110 第四列有按下

43             }

44             //测试行

45             GPIO_KEY=0X0F;         //给列IO口置低电平

46             switch(GPIO_KEY)

47             {

48                 case(0X07):    KeyValue=KeyValue;break;        // 0111 第一行有按下

49                 case(0X0B):    KeyValue=KeyValue+1;break;      // 1011 第二行有按下

50                 case(0X0D):   KeyValue=KeyValue+2;break;      // 1101 第三行有按下

51                 case(0X0E):    KeyValue=KeyValue+3;break;      // 1110 第四行有按下

52             }

53             while((a<50) && (GPIO_KEY!=0xf0))     //检测按键松手检测

54             {

55                 Delay10ms(1);

56                 a++;

57             }

58         }

59     }

60 }

61 

62 

63 void Delay10ms(unsigned int c)  

64 {

65     unsigned char a, b;

66     for (;c>0;c--)

67     {

68         for (b=38;b>0;b--)

69         {

70             for (a=130;a>0;a--);

71         }          

72     }       

73 }


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • 如何构建一个触摸传感器电路

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章