打印
[STM32F3]

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

[复制链接]
644|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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
#ifndef   __SCAN_KEY_H__
#define  __SCAN_KEY_H__

#include "gpio.h"
#include "tim.h"

#define KEY_ON 0
#define KEY_OFF 1

#define delay_ms(x) HAL_Delay(x)

//KEY控制的引脚
#define KEY0_GPIO_Port  GPIOE
#define KEY0_Pin        GPIO_PIN_4
#define KEY0_IN()                         HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)


uint8_t scan_key(void);

#endif



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

uint16_t key_time = 0;

void Scan_key_Init(void)
{
        
}

uint8_t scan_key(void)
{
                /*
                                值key_return如下:
                                1---------单击
                                2---------双击
                                3---------长按
                */
                static unsigned char key_state=0;                           //按键状态
                static unsigned char state=0;
                static unsigned char time,time1,time2;   
                static unsigned char key_up_flag=0;                           //按键弹起标志位
                static unsigned char key_return;
               
        if(KEY0_IN() == KEY_ON)        //按键按下消抖
        {
                delay_ms(10);
                if(KEY0_IN() == KEY_ON)
                {
                        HAL_TIM_Base_Start_IT(&htim7); //打开TIM7中断
                        key_state=0;
                }
        }
        else
        {
                delay_ms(10);                                                //按键松开消抖
                if(KEY0_IN() == KEY_OFF)
                {
                        //HAL_TIM_Base_Stop_IT(&htim7); //打开TIM7中断
                        key_state=1;
                        key_up_flag=0;
                }
        }
        
        //这里主要防止,按键在识别长按后,又会执行一遍单击操作
        if((state==0)&&(key_state==0)&&(key_up_flag==0))        
        {
                state=1;
                time=key_time;                                       //记录按键按下的时间为多少,做标记
        }        
        
        if(state==1)
        {
                 time1=key_time;
                 time2=time1-time;                                 //计算按键按下时长
                 
                 if(time2>50)                                    //长按判断
                 {
                        state=2;
                 }
                 
                 if(key_state==1)                                //按键弹起
           {
              state=3;
              time=key_time;                                  //标志什么时间按键弹起的
           }
        }
        
                if(state==2)                                         //长按
                {
                                        state=0;                                     //重置状态
                                        key_up_flag=1;
                                        key_return=3;
                }
               
                if((state==3)&&(key_up_flag==0))
          {
               time1=key_time;
               time2=time1-time;                          //计算按键弹起后时间
                if(time2>6)                                //判断按键弹起后的时间,超过300ms,则说明为单击
                    {
                      state=0;
                    key_return=1;
                  }   
              else    if(key_state==0)                     //按键弹起后,300ms内又有按键按下
                 {
                      state=4;
                 }
           }
           if(state==4)
          {
                  if(key_state==1)                        //按键弹起
                  {
                     state=0;
                    key_return=2;
                   }
          }
         
     return key_return;
        
}


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
                if (htim->Instance  == TIM7)
                {
                                key_time++;
                                LED_R_TOG();
//                                if(key_time == 1000)
//                                {
//                                        key_time=0;
//                                        LED_G_TOG();
//                                }
                        
                }
}

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


BSP_USART.c
#include "BSP_USART.h"

void BSP_USART_Init(void)
{

}

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

int _write(int fd, char *ptr, int len)
{         
        HAL_UART_Transmit(&huart1,(uint8_t *)ptr,len,10000);
        return (len);
}



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

int _read (int fd, char *ptr, int len)
{
        *ptr=0X00;
        HAL_UART_Receive(&huart1,(uint8_t *)ptr,1,10000);
        return 1;
}


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



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



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

89

帖子

1

粉丝