本帖最后由 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);
}
|