【stm32】hal库学习笔记-GPIO按键控制LED和蜂鸣器(超详细!)

【stm32】hal库学习笔记-GPIO按键控制LED和蜂鸣器

注:本学习笔记基于stm32f4系列
使用的开发板为正点原子stmf407ZGT6探索者开发板

GPIO引脚使用时,可输入或输出数字信号

例如:

检测按键输入信号(Read_Pin)输出信号(Write_Pin)

输出信号点亮或熄灭LED

硬件特点

GPIO引脚内部结构图

GPIO状态

  • 输入浮空状态:上拉下拉电阻均不使用(复位时状态)
  • 输入上拉状态:只使用上拉电阻-引脚外部无输入时读到的电平为高电平
  • 输入下拉状态:只使用下拉电阻-引脚外部无输入时读到的电平为低电平
  • 模拟状态:不使用任何内部的上拉下拉电阻-用于ADC输入/DAC输出引脚
  • 开漏输出(Output Open Drain)
  • 推挽输出 :输出1时引脚为高电平,输出0时引脚为低电平
    若要增强引脚的输出驱动能力,则可使用上拉-如GPIO输出高电平点亮LED
  • 复用功能推挽
  • 复用功能开漏

涉及到的函数

重要函数

c 复制代码
HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

按键控制LED

LED部分原理图

按键部分原理图

实现功能:

按下KEY0时,使LED1的输出翻转

按下KEY1时,使LED2的输出翻转

按下KEY2时,使LED1与LED2的状态都翻转

MCU图形化配置

连接按键的引脚选择GPIO_Input

连接LED的引脚选择GPIO_Output

并设置相应的用户标签

  • KEY0,KEY1,KEY2配置为上拉(Pull-up)
  • PF9,PF10设置为推挽输出(Output Push Pull)
  • 调试引脚设为串行调试引脚WSD
  • 在RCC里将HSE改为晶振

    在时钟树界面
  • 将HSE改为8MHz
  • 主锁相环选择HSE作为时钟源
  • 设置HCLK为168

代码部分

编写驱动程序

keyled.c

c 复制代码
#include "keyled.h"
//编写函数扫描被按下的按键
KEYS ScanPressedKey(uint32_t timeout)
{
	uint32_t tickstart = HAL_GetTick();
	const uint32_t btnDelay = 20;//延时时间
	while (1)
	{
#ifdef KeyRight_Pin
		if (HAL_GPIO_ReadPin(Key0_GPIO_Port, Key0_Pin) == GPIO_PIN_RESET)
		{
			HAL_Delay(btnDelay);//延时消除前抖动
			if (HAL_GPIO_ReadPin(Key0_GPIO_Port, Key0_Pin) == GPIO_PIN_RESET)
				return KEY_0;
		}
#endif
#ifdef KeyDown_Pin
		if (HAL_GPIO_ReadPin(Key1_GPIO_Port, Key1_Pin) == GPIO_PIN_RESET)
		{
			HAL_Delay(btnDelay);
			if (HAL_GPIO_ReadPin(Key1_GPIO_Port, Key1_Pin) == GPIO_PIN_RESET)
				return KEY_1;
		}
#endif
#ifdef KeyLeft_Pin
		if (HAL_GPIO_ReadPin(Key2_GPIO_Port, Key2_Pin) == GPIO_PIN_RESET)
		{
			HAL_Delay(btnDelay);
			if (HAL_GPIO_ReadPin(Key2_GPIO_Port, Key2_Pin) == GPIO_PIN_RESET)
				return KEY_2;
		}
#endif
#ifdef KeyUp_Pin
		if (HAL_GPIO_ReadPin(KeyUp_GPIO_Port, KeyUp_Pin) == GPIO_PIN_SET)
		{
			HAL_Delay(btnDelay);
			if (HAL_GPIO_ReadPin(KeyUp_GPIO_Port, KeyUp_Pin) == GPIO_PIN_SET)
				return KEY_UP;
		}
#endif
		if (timeout != KEY_WAIT_ALWAYS) {
			if ((HAL_GetTick() - tickstart) > timeout)
				break;
		}
	}
	return KEY_NONE;
}//若没有按键被按下,超时后跳出循环

keyled.h

c 复制代码
#include "main.h"
//创建枚举类型
typedef enum {
	KEY_NONE = 0,
	KEY_1,
	KEY_2,
	KEY_UP,
	KEY_NONE
} KEYS;
//定义参数-表示一直等待按键按下
#define KEY_WAIT_ALWAYS		0

KEYS ScanPressedKey(uint32_t timeout);
//LED1的宏定义函数
#ifdef	LED1_Pin
	#define LED1_Toggle()	HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin)//实现翻转
	#define LED1_OFF()		HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET)//实现打开
	#define LED1_ON()		HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET)//实现关闭
#endif
//LED2的宏定义函数
#ifdef	LED2_Pin
	#define LED2_Toggle()	HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin)
	#define LED2_OFF()		HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET)
	#define LED2_ON()		HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET)
#endif
//蜂鸣器的宏定义函数
#ifdef	Buzzer_Pin
	#define Buzzer_Toggle()	HAL_GPIO_TogglePin(Buzzer_GPIO_Port, Buzzer_Pin)
	#define Buzzer_ON()		HAL_GPIO_WritePin(Buzzer_GPIO_Port, Buzzer_Pin, GPIO_PIN_SET)
	#define Buzzer_OFF()	HAL_GPIO_WritePin(Buzzer_GPIO_Port, Buzzer_Pin, GPIO_PIN_RESET)
#endif
应用驱动程序


编写主程序
c 复制代码
  while (1)
  {
	  KEYS curKey=ScanPressedKey(KEY_WAIT_ALWAYS);
	  switch (curKey)
	  {
	  case KEY_0:
	  	  LED1_Toggle();
	  	  break;
	  case KEY_1:
	  	  LED2_Toggle();
	  	  break;
	  case KEY_2:
	  	  LED1_Toggle();
	  	  LED2_Toggle();
	  	  break;
	  case KEY_UP:
	  	  Buzzer_Toggle();
	  	  break;
	  default:
		  break;
	  }
	  HAL_Delay(200);//消除按键弹起时的的抖动影响

按键控制蜂鸣器

有源蜂鸣器原理图

有源蜂鸣器是指自带了震荡电路的蜂鸣器,这种蜂鸣器一接上电就会自己震荡发声。而如

果是无源蜂鸣器,则需要外加一定频率(2~5Khz)的驱动信号,才会发声。

图中 Q4 是用来扩流,R65 则是一个下拉电阻,避免 MCU 复位的时候,蜂鸣器可能发声的

现象。BEEP 信号直接连接在 MCU 的 PF8 上面,PF8 可以做 PWM 输出,可使用 PWM 来控制蜂鸣器实现"唱歌"。

实现功能:

按下KEY_UP按键时,蜂鸣器输出翻转

MCU图形化配置

连接蜂鸣器的引脚选择GPIO_Output

并设置相应的用户标签

  • KEY_UP配置为下拉(Pull-down)
  • PF8设置为下拉推挽输出(Output Push Pull)
  • 将初始状态改为High(防止一复位蜂鸣器就响)
  • 最大输出频率-若为无源蜂鸣器则改为High,有源滤波器都可

成果演示

上键翻转蜂鸣器状态

KEY0翻转红灯,KEY1翻转绿灯

KEY2同时翻转两个灯状态

相关推荐
QT 小鲜肉18 分钟前
【孙子兵法之上篇】001. 孙子兵法·计篇深度解析与现代应用
笔记·读书·孙子兵法
小曹要微笑2 小时前
STM32F7 时钟树简讲(快速入门)
c语言·stm32·单片机·嵌入式硬件·算法
XINVRY-FPGA2 小时前
XCVP1802-2MSILSVC4072 AMD Xilinx Versal Premium Adaptive SoC FPGA
人工智能·嵌入式硬件·fpga开发·数据挖掘·云计算·硬件工程·fpga
沐欣工作室_lvyiyi2 小时前
家用按摩椅控制系统设计(论文+源码)
单片机·物联网·毕业设计·按摩椅控制系统
二川bro3 小时前
多模态AI开发:Python实现跨模态学习
人工智能·python·学习
love530love3 小时前
【笔记】ComfUI RIFEInterpolation 节点缺失问题(cupy CUDA 安装)解决方案
人工智能·windows·笔记·python·插件·comfyui
石像鬼₧魂石3 小时前
Netcat,网络瑞士军刀(新手学习备用)
学习
愚戏师3 小时前
MySQL 数据导出
数据库·笔记·mysql
摇滚侠3 小时前
2025最新 SpringCloud 教程,教程简介,笔记01
笔记·spring cloud