实现按键扫描, 实现四个按键按下控制灯的亮灭
按键电路原理图
按键与主芯片引脚原理图
Key_UP按下会有高电平输入, 所以电路设置应该是默认低电平, 初始化为下拉输入
Key_Left/Right/Down按下会有低电平, 初始化为下拉输入
按键按下内部弹片会有抖动,引起检测多次触发信号, 需要进行延时防止抖动
参考 普中STM32-PZ6806L开发板(STM32CubeMX创建项目并点亮LED灯)
key.h
#ifndef __KEY_H__
#define __KEY_H__
#include "stm32f1xx_hal.h"
typedef enum
{
KEY_PRESSED,
KEY_NORMAL,
} KEY_Status;
typedef struct
{
GPIO_TypeDef *GPIOx;
uint16_t GPIO_Pin;
GPIO_PinState PressedState;
void (*KeyPressedCallback)(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
}KEY_Info;
KEY_Status KEY_CheckStatus(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PressedState);
void KEY_KeysForeachAction(KEY_Info *keys, uint8_t size);
#endif //__KEY_H__
key.c
#include "key.h"
KEY_Status KEY_CheckStatus(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PressedState)
{
if ( PressedState == HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) )
{
HAL_Delay(100);
if ( PressedState == HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) )
{
return KEY_PRESSED;
}
}
return KEY_NORMAL;
}
void KEY_KeysForeachAction(KEY_Info *keys, uint8_t size)
{
while (1)
{
for (int i = 0; i < size; ++i)
{
if ( KEY_PRESSED == KEY_CheckStatus(keys[i].GPIOx, keys[i].GPIO_Pin, keys[i].PressedState) )
{
keys[i].KeyPressedCallback(keys[i].GPIOx, keys[i].GPIO_Pin);
break;
}
}
}
}
main.c
void onKeyPress( GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
if ( KEY_UP_GPIO_Port == GPIOx && KEY_UP_Pin == GPIO_Pin)
{
LED_LightControl(LED1, LED_ON);
}
else if (KEY_DOWN_GPIO_Port == GPIOx && KEY_DOWN_Pin == GPIO_Pin)
{
LED_LightControl(LED1, LED_OFF);
}
else if (KEY_LEFT_GPIO_Port == GPIOx && KEY_LEFT_Pin == GPIO_Pin)
{
LED_LightControl(LED2, LED_ON);
}
else if (KEY_RIGHT_GPIO_Port == GPIOx && KEY_RIGHT_Pin == GPIO_Pin)
{
LED_LightControl(LED2, LED_OFF);
}
}
int main()
{
KEY_Info infos[4] =
{
{ KEY_UP_GPIO_Port, KEY_UP_Pin, GPIO_PIN_SET, onKeyPress},
{ KEY_DOWN_GPIO_Port, KEY_DOWN_Pin, GPIO_PIN_RESET, onKeyPress},
{ KEY_LEFT_GPIO_Port, KEY_LEFT_Pin, GPIO_PIN_RESET, onKeyPress},
{ KEY_RIGHT_GPIO_Port, KEY_RIGHT_Pin, GPIO_PIN_RESET, onKeyPress},
};
...
while(1)
{
KEY_KeysForeachAction((KEY_Info*)infos, sizeof(infos)/sizeof(KEY_Info));
}
...
}
普中STM32-PZ6806L开发板(HAL库函数实现-按键扫描) 点灯