蓝桥杯嵌入式16届 —— 按键模块
按键模块主要是注意短按、长按;
引脚状况
使用PA0、PB0、 PB1、PB2四个引脚;根据电路图可知:按下端口接地,所以我们要将端口设置成为上拉模式,只要按下即低电平;
STM32CubeMX
端口配置
配置定时器TIM6
因为单纯计数我便使用最基础的定时器
使能
代码部分
按键扫描有多种方法,我只用一种定时器扫描,在精不在多;
记住回调函数在哪找,就不用背它;
头文件
#ifndef _INTERRUPT_H_
#define _INTERRUPT_H_
#include "stm32g4xx_hal.h"
#include "stdbool.h"
#include "stdint.h"
#include "main.h"
struct key
{
bool key_status;//按键状态
uint8_t counts;//按键计数
bool shortsign;//短按
uint8_t key_time;//按键时长
bool longsign;//长按
};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
#endif
c文件部分
#include "interrupt.h"
#include "led.h"
#include "stdbool.h"
struct key key1[4]={0,0,0,0,0};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM6)
{
key1[0].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
key1[1].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key1[2].key_status = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key1[3].key_status = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(uint8_t i=0;i<4;i++)
{
switch(key1[i].counts)
{
case 0:
{
if(key1[i].key_status == 0)key1[i].counts =1;
}
break;
case 1: 使用case1消抖
{
if(key1[i].key_status ==0)
{
key1[i].counts =2;
key1[i].key_time =0;
}
else key1[i].counts =0;
}
break;
case 2:
{
if(key1[i].key_status== 0)
{
key1[i].key_time++;
}
if(key1[i].key_status== 1)
{
key1[i].shortsign=1;
key1[i].counts =0;
}
if(key1[i].key_status== 1 && key1[i].key_time > 70)
{
key1[i].longsign=1;
key1[i].counts =0;
}
}
break;
}
}
}
}
main文件
#include "interrupt.h"
extern struct key key1[];
int main(void)
{
HAL_TIM_Base_Start_IT(&htim6);
while (1)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
char text[30];
sprintf(text," no dwon");
LCD_DisplayStringLine(Line4,(uint8_t *)text);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(key1[0].shortsign==1)
{
sprintf(text," 0 dwon");
LCD_DisplayStringLine(Line5 ,(uint8_t *)text);
key1[0].shortsign = 0;
}
if(key1[0].longsign ==1)
{
sprintf(text," 1 dwon");
LCD_DisplayStringLine(Line5 ,(uint8_t *)text);
key1[0].longsign = 0;
}
}
}