[STM32F3] VSCODE STM32 裸机之按键识别篇---单击---双击----长按

[复制链接]
 楼主| zero949079783 发表于 2022-5-28 21:50 | 显示全部楼层 |阅读模式
本帖最后由 zero949079783 于 2022-5-28 22:11 编辑

开发环境:VSCODE(gcc编译链)+STM32CubeMX(也可以使用HUAWEI-LiteOS-Studio) 。
代码:Scan_key 链接:https://pan.baidu.com/s/1uXfIR0GFQOBZPl1NfQP08w  
提取码:6b0c

Scan_key.h
  1. #ifndef   __SCAN_KEY_H__
  2. #define  __SCAN_KEY_H__

  3. #include "gpio.h"
  4. #include "tim.h"

  5. #define KEY_ON 0
  6. #define KEY_OFF 1

  7. #define delay_ms(x) HAL_Delay(x)

  8. //KEY控制的引脚
  9. #define KEY0_GPIO_Port  GPIOE
  10. #define KEY0_Pin        GPIO_PIN_4
  11. #define KEY0_IN()                         HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)


  12. uint8_t scan_key(void);

  13. #endif



Scan_key.c
  1. #include "Scan_key.h"
  2. #include "led.h"

  3. uint16_t key_time = 0;

  4. void Scan_key_Init(void)
  5. {
  6.         
  7. }

  8. uint8_t scan_key(void)
  9. {
  10.                 /*
  11.                                 值key_return如下:
  12.                                 1---------单击
  13.                                 2---------双击
  14.                                 3---------长按
  15.                 */
  16.                 static unsigned char key_state=0;                           //按键状态
  17.                 static unsigned char state=0;
  18.                 static unsigned char time,time1,time2;   
  19.                 static unsigned char key_up_flag=0;                           //按键弹起标志位
  20.                 static unsigned char key_return;
  21.                
  22.         if(KEY0_IN() == KEY_ON)        //按键按下消抖
  23.         {
  24.                 delay_ms(10);
  25.                 if(KEY0_IN() == KEY_ON)
  26.                 {
  27.                         HAL_TIM_Base_Start_IT(&htim7); //打开TIM7中断
  28.                         key_state=0;
  29.                 }
  30.         }
  31.         else
  32.         {
  33.                 delay_ms(10);                                                //按键松开消抖
  34.                 if(KEY0_IN() == KEY_OFF)
  35.                 {
  36.                         //HAL_TIM_Base_Stop_IT(&htim7); //打开TIM7中断
  37.                         key_state=1;
  38.                         key_up_flag=0;
  39.                 }
  40.         }
  41.         
  42.         //这里主要防止,按键在识别长按后,又会执行一遍单击操作
  43.         if((state==0)&&(key_state==0)&&(key_up_flag==0))        
  44.         {
  45.                 state=1;
  46.                 time=key_time;                                       //记录按键按下的时间为多少,做标记
  47.         }        
  48.         
  49.         if(state==1)
  50.         {
  51.                  time1=key_time;
  52.                  time2=time1-time;                                 //计算按键按下时长
  53.                  
  54.                  if(time2>50)                                    //长按判断
  55.                  {
  56.                         state=2;
  57.                  }
  58.                  
  59.                  if(key_state==1)                                //按键弹起
  60.            {
  61.               state=3;
  62.               time=key_time;                                  //标志什么时间按键弹起的
  63.            }
  64.         }
  65.         
  66.                 if(state==2)                                         //长按
  67.                 {
  68.                                         state=0;                                     //重置状态
  69.                                         key_up_flag=1;
  70.                                         key_return=3;
  71.                 }
  72.                
  73.                 if((state==3)&&(key_up_flag==0))
  74.           {
  75.                time1=key_time;
  76.                time2=time1-time;                          //计算按键弹起后时间
  77.                 if(time2>6)                                //判断按键弹起后的时间,超过300ms,则说明为单击
  78.                     {
  79.                       state=0;
  80.                     key_return=1;
  81.                   }   
  82.               else    if(key_state==0)                     //按键弹起后,300ms内又有按键按下
  83.                  {
  84.                       state=4;
  85.                  }
  86.            }
  87.            if(state==4)
  88.           {
  89.                   if(key_state==1)                        //按键弹起
  90.                   {
  91.                      state=0;
  92.                     key_return=2;
  93.                    }
  94.           }
  95.          
  96.      return key_return;
  97.         
  98. }


  99. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  100. {
  101.                 if (htim->Instance  == TIM7)
  102.                 {
  103.                                 key_time++;
  104.                                 LED_R_TOG();
  105. //                                if(key_time == 1000)
  106. //                                {
  107. //                                        key_time=0;
  108. //                                        LED_G_TOG();
  109. //                                }
  110.                         
  111.                 }
  112. }

main.c
  1.                   if(scan_key() == 1)
  2.                                 printf("scan_key() = %d\r\n",scan_key());
  3.                  else if(scan_key() == 2)
  4.                                                 printf("scan_key() = %d\r\n",scan_key());
  5.                  else if(scan_key() == 3)
  6.                                                 printf("scan_key() = %d\r\n",scan_key());


BSP_USART.c
  1. #include "BSP_USART.h"

  2. void BSP_USART_Init(void)
  3. {

  4. }

  5. //重定向c库函数printf到串口,重定向后可使用printf函数(GCC)

  6. int _write(int fd, char *ptr, int len)
  7. {         
  8.         HAL_UART_Transmit(&huart1,(uint8_t *)ptr,len,10000);
  9.         return (len);
  10. }



  11. ////重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数(GCC)

  12. int _read (int fd, char *ptr, int len)
  13. {
  14.         *ptr=0X00;
  15.         HAL_UART_Receive(&huart1,(uint8_t *)ptr,1,10000);
  16.         return 1;
  17. }


  1. ///重定向c库函数printf到串口,重定向后可使用printf函数(KEIL)
  2. //重定义fputc函数
  3. int fputc(int ch, FILE *f)
  4. {         
  5.         HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,10000);
  6.         return (ch);
  7. }



  8. ///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数(KEIL)
  9. int fgetc(FILE *f)
  10. {
  11.         int ch;
  12.         HAL_UART_Receive(&huart1,(uint8_t *)&ch,1,10000);
  13.         return (ch);
  14. }



您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

91

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部

33

主题

91

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部