OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 39|回复: 0

《STM32H562开发指南 V1.0 》第十三章 蜂鸣器实验

[复制链接]

1383

主题

1399

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
5900
金钱
5900
注册时间
2019-5-8
在线时间
1639 小时
发表于 13 小时前 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2026-8-4 09:27 编辑

第十三章 蜂鸣器实验

1)实验平台:正点原子Mini STM32H562开发板

2)章节摘自【正点原子】STM32H562开发指南 V1.0

3)购买链接: https://detail.tmall.com/item.htm?id=753606659612

4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/stm32/zdyz_stm32h562_mini.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)正点原子STM32开发板技术交流群:414052738


2.jpg

3.png

上一章,我们介绍了STM32H5的IO口作为输出的使用。本章,我们将通过另外一个例子继续讲述STM32H5的IO口作为输出的使用,不同的是本章讲的不是用IO口直接驱动器件,而是通过三极管间接驱动。我们将利用一个IO口来控制板载的有源蜂鸣器。
本章分为如下几个小节:
13.1 蜂鸣器简介
13.2 硬件设计
13.3 程序设计
13.4 下载验证


13.1 蜂鸣器简介
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。
Mini STM32H562开发板板载的蜂鸣器是电磁式的有源蜂鸣器,如图13.1.1所示:


第十三章 蜂鸣器实验352.png
图13.1.1 有源蜂鸣器

这里的有源不是指电源的 “源”,而是指有没有自带震荡电路,有源蜂鸣器自带了震荡电路,一通电就会发声;无源蜂鸣器则没有自带震荡电路,必须外部提供2~5Khz左右的方波驱动,才能发声。
上一章,我们利用STM32的IO口直接驱动RGB灯,本章的蜂鸣器,我们能否直接用STM32的IO口驱动呢?让我们来分析一下:STM32H5的单个IO最大可以提供20mA电流(来自数据手册),而蜂鸣器的驱动电流是30mA左右,所以不能直接驱动。而且全盘考虑,STM32H5整个芯片的电流也是有限的,如果用IO口直接驱动蜂鸣器,其它地方用电就得省着点了,所以我们不用STM32H5的IO直接驱动蜂鸣器,而是通过三极管扩流后再驱动蜂鸣器,这样STM32H5的IO只需要提供不到1mA的电流就足够了。
IO口使用虽然简单,但是和外部电路的匹配设计,还是要十分讲究的,考虑越多,设计就越可靠,可能出现的问题也就越少。


13.2 硬件设计

1. 例程功能
蜂鸣器每隔300ms响或者停一次。LED0每隔300ms亮或者灭一次。LED0亮的时候蜂鸣器不叫,而LED0熄灭的时候,蜂鸣器叫。

2. 硬件资源
1)LED灯
       LED0 - PB4(红)
2)蜂鸣器
       BEEP(PE0)

3. 原理图
蜂鸣器在硬件上是直接连接好了的,不需要经过任何设置,直接编写代码就可以了。蜂鸣器的驱动信号连接在STM32H5的PE0上。如图13.2.1所示:


第十三章 蜂鸣器实验975.png
图13.2.1 蜂鸣器与STM32H5连接原理图

图中我们用到一个NPN三极管(S8050)来驱动蜂鸣器,R20主要用于防止蜂鸣器的误发声。驱动信号通过R19和R20间的电压获得,芯片上电时默认电平为低电平,故上电时蜂鸣器不会直接响起。当PE0输出高电平的时候,蜂鸣器将发声,当PE0输出低电平的时候,蜂鸣器停止发声。

13.3 程序设计
本实验我们只是用到GPIO外设输出功能,关于HAL库的GPIO的API函数请看跑马灯实验的介绍。下面我们直接分析本实验的程序流程图。

13.3.1 程序流程图

第十三章 蜂鸣器实验1254.png
图13.3.1.1 蜂鸣器实验程序流程图

13.3.2 程序解析

1. 蜂鸣器驱动代码
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。蜂鸣器(BEEP)驱动源码包括两个文件:beep.c和beep.h。
下面我们先解析beep.h的程序,我们把它分两部分功能进行讲解。
由硬件设计小节,我们知道驱动蜂鸣器的三极管在硬件上连接到PE0,我们做了下面的引脚定义。

  1. /*****************************************************************************/
  2. /* 引脚 定义 */

  3. #define BEEP_GPIO_PORT                 GPIOE
  4. #define BEEP_GPIO_PIN                  GPIO_PIN_0
  5. /* PE口时钟使能 */
  6. #define BEEP_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)
  7. /*****************************************************************************/
复制代码
可以看到这样定义跟跑马灯实验的是类似。
为了后续对蜂鸣器进行便捷的操作,我们为蜂鸣器操作函数做了下面的定义。

  1. /* 蜂鸣器控制 */
  2. #define BEEP(x)   do{ x ? \
  3.                          HAL_GPIO_WritePin(BEEP_GPIO_PORT,
  4.      BEEP_GPIO_PIN, GPIO_PIN_SET) : \
  5.                          HAL_GPIO_WritePin(BEEP_GPIO_PORT,
  6. BEEP_GPIO_PIN, GPIO_PIN_RESET); \
  7.                      }while(0)

  8. /* 蜂鸣器取反控制 */
  9. #define BEEP_TOGGLE()  do{ HAL_GPIO_TogglePin(BEEP_GPIO_PORT,
  10. BEEP_GPIO_PIN); }while(0)  /* BEEP = !BEEP */
复制代码
BEEP(x)这个宏定义就是控制蜂鸣器的打开和关闭的。例如:如果要打开蜂鸣器,那么调用宏定义BEEP(1)即可,如果要关闭蜂鸣器,调用宏定义BEEP(0)即可。
BEEP_TOGGLE()是控制蜂鸣器进行翻转的。这里也利用HAL_GPIO_TogglePin函数实现IO口输出电平取反操作。
下面我们再解析beep.c的程序,这里只有一个函数beep_init,这是蜂鸣器的初始化函数,其定义如下:

  1. /**
  2. * @brief       初始化BEEP相关IO口, 并使能时钟
  3. * [url=home.php?mod=space&uid=271674]@param[/url]       无
  4. * @retval      无
  5. */
  6. void beep_init(void)
  7. {
  8.     GPIO_InitTypeDef gpio_init_struct;
  9.     BEEP_GPIO_CLK_ENABLE();                                       /* BEEP时钟使能 */

  10.     gpio_init_struct.Pin = BEEP_GPIO_PIN;                      /* 蜂鸣器引脚 */
  11.     gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;              /* 推挽输出 */
  12.     gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
  13.     gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM;          /* 中速 */
  14.     HAL_GPIO_Init(BEEP_GPIO_PORT, &gpio_init_struct);         /* 初始化蜂鸣器引脚 */

  15.     BEEP(0);                                                          /* 关闭蜂鸣器 */
  16. }
复制代码
对蜂鸣器的引脚设置为中速上拉的推挽输出。最后关闭关闭蜂鸣器,防止没有操作就响了。

2. main.c代码
在main.c里面编写如下代码:

  1. #include "./SYSTEM/sys/sys.h"
  2. #include "./SYSTEM/usart/usart.h"
  3. #include "./SYSTEM/delay/delay.h"
  4. #include "./BSP/LED/led.h"
  5. #include "./BSP/BEEP/beep.h"

  6. int main(void)
  7. {
  8.     HAL_Init();                                                  /* HAL库初始化 */
  9.     HAL_ICACHE_Enable();                                        /* 使能指令缓存 */
  10.     sys_stm32_clock_init(250, 4, 2, 2);                     /* 系统时钟初始化, 250Mhz */
  11.     delay_init(250);                                            /* 延时初始化 */
  12.     usart_init(115200);                                        /* 串口初始化 */
  13.     led_init();                                               /* LED初始化 */
  14.     beep_init();                                                /* 蜂鸣器初始化 */
  15.    
  16.     while(1)
  17.     {
  18.         LED0(0);
  19.         BEEP(0);
  20.         delay_ms(300);
  21.         LED0(1);
  22.         BEEP(1);
  23.         delay_ms(300);
  24.     }
  25. }
复制代码
首先是调用系统初始化函数。接下来,调用led_init来初始化LED灯,调用beep_init函数初始化蜂鸣器。最后在无限循环里面实现LED0和蜂鸣器间隔300ms交替闪烁和打开关闭一次。

13.4 下载验证
下载完之后,可以看到LED0亮的时候蜂鸣器不叫,而LED0熄灭的时候,蜂鸣器叫(因为他们的有效信号相反)。间隔为0.3秒左右,符合预期设计。
至此,本章的学习就结束了。通过本章,我们进一步学习IO作为输出的使用方法,同时巩固了前面知识的学习。希望大家在开发板上实际验证一下,从而加深印象。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

如发现本坛存在违规或侵权内容, 请点击这里发送邮件举报 (或致电020-38271790)。请提供侵权说明和联系方式。我们将及时审核依法处理,感谢配合。

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-8-4 23:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表