[C] 各种按键模式的扫描 →→→→→进入此内容的聊天室

来自 , 2020-02-05, 写在 C, 查看 105 次.
URL http://www.code666.cn/view/6b5754d7
  1. #ifndef __KEY_H
  2. #define __KEY_H  
  3. #include "common.h"
  4.  
  5. //////////////////////////////////////////////////////////////////////////////////       
  6.  
  7. //按键IO端口定义
  8. #define KEY0            PFin(9)  
  9. #define KEY1            PFin(8)        
  10. #define KEY2            PFin(7)        
  11. #define KEY3      PFin(6)              
  12.  
  13.  
  14. //按键值定义
  15. #define KEY0_DATA         1
  16. #define KEY1_DATA         2
  17. #define KEY2_DATA         3
  18. #define KEY3_DATA   4
  19.  
  20. //变量声明
  21. extern u8   keydown_data;    //按键按下后就返回的值
  22. extern u8   keyup_data;      //按键抬起返回值
  23. extern u16  key_time;
  24. extern u8   key_tem;
  25.  
  26. //函数声明
  27. void KEY_Init(void);          //IO初始化
  28. void key_scan(u8 mode);                 //按键扫描函数   
  29.  
  30. #endif
  31. #include "key.h"
  32.  
  33. /*********************************************************************************
  34. **********************MCU启明 STM32F407应用开发板(高配版)*************************
  35. **********************************************************************************
  36. * 文件名称: key.c                                                                *
  37. * 文件简述:按键扫描程序                                                         *
  38. * 创建日期:2015.10.03                                                           *
  39. * 版    本:V1.0                                                                 *
  40. * 作    者:Clever                                                               *
  41. * 说    明:该按键扫描,包涵各种按键模式的扫描                                   *
  42. **********************************************************************************
  43. *********************************************************************************/
  44.  
  45. /**
  46. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~按键模式剖析~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  47. 一、按键返回值,即按键扫描结果值,分为以下几种情况
  48.                 1、按键按下未抬起时的返回值,对应代码中 keydown_data 变量的值
  49.                 2、按键按下抬起后才返回的值,对应代码中 keyup_data   变量的值
  50.                 3、按任意键有效,只需在程序中判断key_time>某个值,该值取决于执行一次扫描函数的
  51.                    时间长短,扫描函数时间长,相应这该值就小,反之亦然。
  52.                 4、需要长按一个键一段时间才执行相应的程序,就需要该键键值key_tem与key_time
  53.                    配合使用,即实现某个按键(key_tem)长按多久(key_time)后执行相应的程序
  54. 二、按键使用模式
  55.     1、单按:按键按下(一直按着)只返回一次有效按键值
  56.                 2、连按:按键一直按着每执行一次按键扫描函数就返回一次按键值
  57.                 3、void key_scan(u8 mode) 中 mode   0:单按   1:连按
  58. 三、按键使用注意事项;
  59.     1、当使用抬起返回值keyup_data时,按键的连按模式无效,因为键抬起才返回按键值,你
  60.                    按再久都没用,所以在使用keyup_data时,模式mode必须设置为0
  61.                 2、如果需要keydown_data与key_time配合构成长按,模式mode需设置为1,才可用
  62.                 3、如果需要keyup_data与key_time配合构成长按,就要对程序作出相应的改动,在函数的
  63.                    末尾,将 key_time=0; 改为 key_tem=0;就可以使用长按一个按键一段时间,等时间到
  64.                          并且按键抬起才执行相应的代码。不过这样改动,按任意键就失效了,因为按键抬起没
  65.                          把key_time清零,key_time一直有值。或者用户还是需要任意键有效就要自己在相应的
  66.                          代码中把key_time清零。这种长按配合使用在实际是很少用到的。
  67. **/
  68.  
  69. u8  keydown_data=0x00;    //按键按下后就返回的值
  70. u8  keyup_data=0x00;      //按键抬起返回值
  71. u16  key_time=0x00;       //按键按下之后的时间计数,该值乘以扫描一次按键函数的时间就等于按键按下的时间
  72.  
  73. u8  key_tem=0x00;         //长按的按键值与按键扫描程序过渡变量
  74. u8  key_bak=0x00;         //按键扫描程序过渡变量
  75.  
  76. //按键IO口初始化函数
  77. void KEY_Init(void)
  78. {
  79.         GPIO_InitTypeDef  GPIO_InitStructure;
  80.  
  81.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);    //使能GPIOF时钟
  82.  
  83.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9; //KEY0 KEY1 KEY2 KEY3对应引脚
  84.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;             //普通输入模式
  85.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;       //100M
  86.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;             //上拉
  87.   GPIO_Init(GPIOF, &GPIO_InitStructure);                   //初始化GPIOF6,7,8,9
  88. }
  89. /****************************************************************************
  90. * 名    称: void key_scan(u8 mode)
  91. * 功    能:按键扫描函数
  92. * 入口参数:mode:0:单按
  93.                   1: 连按
  94. * 返回参数:无
  95. * 说    明:响应优先级,KEY0>KEY1>KEY2>KEY3
  96. ****************************************************************************/
  97. void key_scan(u8 mode)
  98. {          
  99.          keyup_data=0;         //键抬起后按键值一次有效
  100.        
  101.         if(KEY0==0||KEY1==0||KEY2==0||KEY3==0)   //有键正按下
  102.         {
  103.                 if(KEY0==0)      key_tem=1;
  104.                 else if(KEY1==0) key_tem=2;
  105.                 else if(KEY2==0) key_tem=3;
  106.                 else if(KEY3==0) key_tem=4;
  107.                
  108.                   if (key_tem == key_bak)      //有键按下后第一次扫描不处理,与else配合第二次扫描有效,这样实现了去抖动
  109.                           {
  110.                                    key_time++;             //有键按下后执行一次扫描函数,该变量加1
  111.                                          keydown_data=key_tem;   //按键值赋予keydown_data
  112.                                        
  113.                                          if( (mode==0)&&(key_time>1) )//key_time>1按键值无效,这就是单按,如果mode为1就为连按
  114.                                             keydown_data=0;
  115.         }
  116.             else                             //去抖动      
  117.               {
  118.                        key_time=0;
  119.                        key_bak=key_tem;
  120.               }
  121.                
  122.         }
  123.         else       //键抬起
  124.                 {
  125.              if(key_time>2)            //按键抬起后返回一次按键值
  126.                 {
  127.                         keyup_data=key_tem;  //键抬起后按键值赋予keydown_data                                                         
  128.                 }
  129.                                 key_bak=0;               //要清零,不然下次执行扫描程序时按键的值跟上次按的值一样,就没有去抖动处理了
  130.               key_time=0;
  131.                                 keydown_data=0;        
  132.           }    
  133. }
  134.  

回复 "各种按键模式的扫描"

这儿你可以回复上面这条便签

captcha