普中STM32-PZ6806L开发板(HAL库函数实现-按键扫描)

简介

实现按键扫描, 实现四个按键按下控制灯的亮灭

电路原理图

按键电路原理图

按键与主芯片引脚原理图

其他知识

原理图分析

Key_UP按下会有高电平输入, 所以电路设置应该是默认低电平, 初始化为下拉输入

Key_Left/Right/Down按下会有低电平, 初始化为下拉输入

消除按键抖动

按键按下内部弹片会有抖动,引起检测多次触发信号, 需要进行延时防止抖动

实现步骤

创建项目

参考 普中STM32-PZ6806L开发板(STM32CubeMX创建项目并点亮LED灯)

初始化多个按键引脚

添加用户代码

key.h

c 复制代码
#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

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

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库函数实现-按键扫描) 点灯

代码

不需要下载, 基本代码上面都提供了

参考

普中STM32-PZ6806L开发板(HAL库函数实现-批量操作GPIO引脚实现跑马灯)

相关推荐
晶振厂家-晶发电子5 小时前
晶振在5G时代的角色:高精度时钟的核心支撑
单片机·嵌入式硬件·5g·晶振·电子元器件·晶振知识
F137298015575 小时前
WD5030A 芯片,12V降5V,输出电流12A,电路设计
stm32·单片机·嵌入式硬件·汽车·51单片机
小莞尔5 小时前
【51单片机】【protues仿真】基于51单片机的篮球计时计分器系统
c语言·stm32·单片机·嵌入式硬件·51单片机
三佛科技-187366133975 小时前
分享机械键盘MCU解决方案
单片机·嵌入式硬件·计算机外设
李永奉5 小时前
51单片机-使用IIC通信协议实现EEPROM模块教程
单片机·嵌入式硬件·51单片机
工大一只猿5 小时前
51单片机学习
嵌入式硬件·学习·51单片机
小莞尔5 小时前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
风_峰5 小时前
Ubuntu Linux SD卡分区操作
嵌入式硬件·ubuntu·fpga开发
bing_feilong6 小时前
STM32精准控制水流
单片机·嵌入式硬件
Hello_Embed13 小时前
STM32HAL 快速入门(二十):UART 中断改进 —— 环形缓冲区解决数据丢失
笔记·stm32·单片机·学习·嵌入式软件