第2章 蜂鸣器实验
第二章 蜂鸣器实验
1. 导入
上一章,我们介绍了 STM32F4 的 IO 口作为输出的使用,这一章,我们将通过另外一个例子讲述 STM32F4 的 IO 口作为输出的使用。 在本章中,我们将利用一个 IO 口来控制板载的有源蜂鸣器,实现蜂鸣器控制。
2. 蜂鸣器简介
探索者 STM32F4 开发板板载的蜂鸣器是电磁式的有源蜂鸣器:
这里的有源不是指电源的“源”,而是指有没有自带震荡电路,有源蜂鸣器自带了震荡电路,一通电就会发声;无源蜂鸣器则没有自带震荡电路,必须外部提供 2~5Khz 左右的方波驱动,才能发声。
前面我们已经对 STM32F4 的 IO 做了简单介绍,上一章,我们就是利用 STM32 的 IO 口直接驱动 LED 的,本章的蜂鸣器,我们能否直接用 STM32 的 IO 口驱动呢? 让我们来分析下: STM32F4 的单个 IO 最大可以提供 25mA 电流(来自数据手册),而蜂鸣器的驱动电流是 30mA左右,两者十分相近,但是全盘考虑, STM32F4 整个芯片的电流, 最大也就 150mA,如果用 IO 口直接驱动蜂鸣器,其他地方用电就得省着点了…所以,我们不用 STM32F4 的 IO 直接驱动蜂鸣器,而是通过三极管扩流后再驱动蜂鸣器,这样 STM32F4 的 IO 只需要提供不到 1mA 的电流就足够了。
3. 硬件设计
本章需要使用到的硬件有:
-
指示灯DS0
-
蜂鸣器
DS0 在上一章已有介绍,而蜂鸣器在硬件上也是直接连接好了的, 不需要经过任何设置,直接编写代码就可以了。 蜂鸣器的驱动信号连接在 STM32F4 的 PF8 上。
图中我们用到一个 NPN 三极管(S8050)来驱动蜂鸣器, R61 主要用于防止蜂鸣器的误发声。当 PF.8 输出高电平的时候,蜂鸣器将发声, 当 PF.8 输出低电平的时候,蜂鸣器停止发声。
4. 软件设计
4.1 编程目标
-
LED初始化
-
驱动蜂鸣器
4.2 代码分析
上一章我们与标准库进行了比较,这一章作为基础,我们详细分析HAL库函数
- LED宏定义
#ifndef _LED_H
#define _LED_H
#include "sys.h"
#define LED0 PFout(9) // LED0
#define LED1 PFout(10) // LED1
void LED_Init(void);
#endif
LED0
和 LED1
是宏定义,代表对特定引脚(PF9 和 PF10)的访问。PFout(n)
是一个宏,用于控制 GPIOF 的输出引脚。具体来说:
PFout(9)
会使能 GPIOF 的第 9 引脚的输出。PFout(10)
会使能 GPIOF 的第 10 引脚的输出。
这两个宏通常用来在程序中简化对 LED 的控制。
示例代码:
假设你有一个函数用于打开或关闭 LED:
void LED_Toggle(uint8_t led)
{
if(led == 0)
{
LED0 = !LED0; // 切换 LED0 的状态
}
else if(led == 1)
{
LED1 = !LED1; // 切换 LED1 的状态
}
}
如果你调用 LED_Toggle(0);
,它会切换 PF9 引脚的电平,从而改变连接到该引脚的 LED 的状态。同样,LED_Toggle(1);
切换 PF10 引脚的电平。
- LED初始化函数
#include "led.h"
// 初始化PB1为输出.并使能时钟
// LED IO初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOF_CLK_ENABLE(); // 开启GPIOF时钟
GPIO_Initure.Pin = GPIO_PIN_9|GPIO_PIN_10;// PF9,10
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
GPIO_Initure.Pull = GPIO_PULLUP; // 上拉
GPIO_Initure.Speed = GPIO_SPEED_HIGH; // 高速
HAL_GPIO_Init(GPIOF, &GPIO_Initure);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET); // PF9置1,默认初始化后灯灭
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_SET);// PF10置1,默认初始化后灯灭
}
-
#include "led.h"
包含自定义的头文件led.h
,用于引入 LED 控制相关的定义和声明。 -
void LED_Init(void)
LED_Init
函数用于初始化 LED 控制的相关 GPIO 引脚。 -
GPIO_InitTypeDef GPIO_Initure;
定义一个结构体GPIO_Initure
,用于配置 GPIO 引脚的参数。 -
__HAL_RCC_GPIOF_CLK_ENABLE();
使能 GPIOF 时钟。__HAL_RCC_GPIOF_CLK_ENABLE()
是一个宏,调用该宏会设置 RCC (时钟控制) 寄存器以开启 GPIOF 的时钟,确保对 GPIOF 的操作可以进行。 -
GPIO_Initure.Pin = GPIO_PIN_9 | GPIO_PIN_10;
配置要初始化的 GPIO 引脚为 PF9 和 PF10。GPIO_PIN_9
和GPIO_PIN_10
是 STM32 HAL 库定义的常量,表示第 9 和第 10 引脚。 -
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;
设置 GPIO 引脚为推挽输出模式 (GPIO_MODE_OUTPUT_PP
)。推挽输出模式可以提供强驱动能力,使引脚输出高电平或低电平。 -
GPIO_Initure.Pull = GPIO_PULLUP;
配置 GPIO 引脚上拉电阻 (GPIO_PULLUP
)。上拉电阻将引脚在未被驱动时保持在高电平状态。 -
GPIO_Initure.Speed = GPIO_SPEED_HIGH;
设置 GPIO 引脚的输出速度为高速 (GPIO_SPEED_HIGH
)。这意味着引脚能够以更高的频率进行电平切换。 -
HAL_GPIO_Init(GPIOF, &GPIO_Initure);
调用HAL_GPIO_Init()
函数来初始化 GPIOF 引脚。该函数接受两个参数:
GPIOF
:要初始化的 GPIO 端口。&GPIO_Initure
:指向GPIO_Initure
结构体的指针,包含了引脚配置的所有参数。
-
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET);
将 GPIOF 的第 9 引脚设置为高电平 (GPIO_PIN_SET
)。这会使连接到 PF9 的 LED 熄灭(假设 LED 是负逻辑)。 -
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_10, GPIO_PIN_SET);
将 GPIOF 的第 10 引脚设置为高电平 (GPIO_PIN_SET
)。这会使连接到 PF10 的 LED 熄灭。
- 蜂鸣器宏定义
#ifndef __BEEP_H
#define __BEEP_H
#include "sys.h"
//LED端口定义
#define BEEP PFout(8) // 蜂鸣器控制IO
void BEEP_Init(void); //初始化
#endif
定义了一个宏 BEEP
,用于控制蜂鸣器。PFout(8)
是一个宏或函数,通常用于访问 GPIO 端口 PF 的第 8 位。这个宏或函数会在 sys.h
或其他相关文件中定义。PFout(8)
可能是一个宏,用于设置或读取 GPIOF 的第 8 引脚的状态。
- 蜂鸣器初始化函数
#include "beep.h"
// 初始化PF8为输出.并使能时钟
// LED IO初始化
void BEEP_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOF_CLK_ENABLE(); //开启GPIOF时钟
GPIO_Initure.Pin = GPIO_PIN_8; // PF8
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;// 推挽输出
GPIO_Initure.Pull = GPIO_PULLUP; // 上拉
GPIO_Initure.Speed = GPIO_SPEED_HIGH; // 高速
HAL_GPIO_Init(GPIOF, &GPIO_Initure);
HAL_GPIO_WritePin(GPIOF,GPIO_PIN_8, GPIO_PIN_RESET); // 蜂鸣器对应引脚GPIOF8拉低,
}
这段代码初始化了 GPIOF 的第 8 引脚,以控制连接到该引脚的蜂鸣器。这里的配置包括:
-
使能 GPIOF 时钟:
__HAL_RCC_GPIOF_CLK_ENABLE()
用于启用 GPIOF 的时钟,使能后 GPIOF 引脚可以进行操作。 -
配置 GPIO 引脚:
GPIO_Initure.Pin = GPIO_PIN_8;
:设置要配置的引脚为 PF8。GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;
:将引脚配置为推挽输出模式,以便能驱动蜂鸣器。GPIO_Initure.Pull = GPIO_PULLUP;
:配置上拉电阻,保持引脚在空闲时为高电平。GPIO_Initure.Speed = GPIO_SPEED_HIGH;
:设置引脚为高速,以提高响应速度。
-
初始化引脚:
HAL_GPIO_Init(GPIOF, &GPIO_Initure);
将上述配置应用到 GPIOF 的第 8 引脚。 -
设置引脚状态:
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8, GPIO_PIN_RESET);
将 PF8 引脚拉低,初始状态下关闭蜂鸣器。
这样设置后,你可以通过改变 PF8 引脚的电平来控制蜂鸣器的开关。
- 主函数
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
int main(void)
{
HAL_Init(); // 初始化HAL库
Stm32_Clock_Init(336,8,2,7); // 设置时钟,168Mhz
delay_init(168); // 初始化延时函数
LED_Init(); // 初始化LED
BEEP_Init(); // 初始化蜂鸣器
while(1)
{
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_RESET); // DS0拉低,亮 等同LED0=0;
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8, GPIO_PIN_RESET); // BEEP引脚拉低,等同BEEP=0;
delay_ms(300); // 延时300ms
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET); // DS0拉高,灭 等同LED0=1;
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8, GPIO_PIN_SET); // BEEP引脚拉高,等同BEEP=1;
delay_ms(300);
}
}
-
初始化 HAL 库:
HAL_Init()
用于初始化 HAL 库,准备好硬件抽象层的功能。 -
设置时钟:
Stm32_Clock_Init(336, 8, 2, 7);
配置系统时钟为 168 MHz。这通常涉及设置 PLL(相位锁环)参数。 -
初始化延时函数:
delay_init(168);
设置延时函数所需的时钟频率。 -
初始化 LED 和蜂鸣器:
LED_Init()
和BEEP_Init()
分别用于初始化 LED 和蜂鸣器的 GPIO 引脚。 -
主循环:
- 点亮 LED 和蜂鸣器:将 PF9 和 PF8 引脚拉低,点亮 LED 和开启蜂鸣器。
- 延时:
delay_ms(300);
使系统等待 300 毫秒。 - 熄灭 LED 和蜂鸣器:将 PF9 和 PF8 引脚拉高,熄灭 LED 和关闭蜂鸣器。
- 再次延时:
delay_ms(300);
使系统再等待 300 毫秒。
5. 小结
前面的章节倒是很容易,本章我们主要学习的还是控制GPIO输出,无他-就一个函数而-HAL_GPIO_WritePin(),我们可以详细地说明一下:
HAL_GPIO_WritePin()
是 STM32 HAL 库中用于操作 GPIO(通用输入输出)引脚的一个函数。它用于设置指定 GPIO 引脚的电平状态(高或低)。这个函数的详细说明如下:
函数原型
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
参数说明
- GPIOx:
- 类型:
GPIO_TypeDef*
- 说明:指定要操作的 GPIO 端口。常见的端口包括
GPIOA
,GPIOB
,GPIOC
,GPIOD
,GPIOE
,GPIOF
, 等。
- GPIO_Pin:
- 类型:
uint16_t
- 说明:指定要操作的 GPIO 引脚。可以是一个引脚的掩码,如
GPIO_PIN_0
,GPIO_PIN_1
,GPIO_PIN_2
, 等。这些宏定义通常在 STM32 HAL 库的头文件中定义。
- PinState:
- 类型:
GPIO_PinState
- 说明:设置 GPIO 引脚的状态。可以是以下两种状态之一:
GPIO_PIN_RESET
:表示将引脚设置为低电平(0)。GPIO_PIN_SET
:表示将引脚设置为高电平(1)。
功能
HAL_GPIO_WritePin()
函数通过直接操作 GPIO 控制寄存器来设置引脚的电平状态。它会根据传入的 PinState
参数将指定的引脚设置为高电平或低电平。
示例
假设你要将 GPIOA
端口的第 5 号引脚设置为高电平,代码如下:
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
如果要将 GPIOB
端口的第 12 号引脚设置为低电平,代码如下:
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
应用场景
- 点亮/熄灭 LED:通常使用
HAL_GPIO_WritePin()
来控制 LED 的开关状态。 - 控制继电器:通过设置 GPIO 引脚来控制继电器的开关。
- 驱动其他外设:可以用于控制其他外设的开关状态,例如马达、蜂鸣器等。
通过这个函数,你可以灵活地操作 STM32 微控制器的 GPIO 引脚,以满足各种应用需求。
2024.9.27 第一次修订,后期不再维护