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

2024-01-01 07:19:17

简介

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

电路原理图

按键电路原理图
在这里插入图片描述
按键与主芯片引脚原理图
在这里插入图片描述

其他知识

原理图分析

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

代码

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

参考

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

文章来源:https://blog.csdn.net/halo_hsuh/article/details/135321841
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。