大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正是如此,才有了借助头条平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思设计的教学课件分享出来,如果您正是一名单片机爱好者或是一名同行,欢迎点赞+关注,各位的支持是本人持续输出的动力,多谢多谢!#30天学会STM32##STM32单片机##单片机#
本章我们延续上一章闪烁灯的主题,通过STM32的IO口来控制开发板上的有源蜂鸣器,实现发声控制。通过本章的学习,你将进一步了解STM32的IO口作为输出口使用的方法。
【学习目标】
蜂鸣器是一种一体化结构的电子讯响器,采用直流供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机等电子产品中作发声器件。蜂鸣器按构造方式的不同,可分为电磁式蜂鸣器和压电式蜂鸣器;按其驱动方式的不同,可分为有源蜂鸣器和无源蜂鸣器。我们开发板上的蜂鸣器是电磁式的有源蜂鸣器,如图1所示。
图1 开发板上的有源蜂鸣器
这里的有源或无源不是指电源的“源”,而是指有没有自带振荡源。有源蜂鸣器内部自带了振荡电路,一通电就会发声,声音频率固定;无源蜂鸣器则没有自带振荡电路,必须外部提供2~5kHz左右的方波驱动,才能发声,音调也会随驱动信号的频率变化而改变。
1.2 蜂鸣器的驱动电路
上一章,我们利用STM32的IO口去直接驱动LED。本章的蜂鸣器,是否也能直接驱动呢?让我们来简单分析下:STM32F1的单个IO最大可以提供25mA电流(来自数据手册),而蜂鸣器的驱动电流大概是30mA,两者十分相近,但是全盘考虑,STM32F1整个芯片的电流,最大也就150mA,如果用IO口直接驱动蜂鸣器,其他地方用电就得省着点了。因此,在开发板的电路设计上,是将IO口信号通过三极管扩流后再驱动蜂鸣器,如图2所示,这样只需要提供不到1mA的电流就足够了。
图2 蜂鸣器与STM32连接原理图
从上图可知,蜂鸣器的驱动信号连接在STM32的PB3引脚上,用一个NPN三极管Q7来驱动蜂鸣器,R55主要用于防止蜂鸣器的误发声。当PB3输出高电平的时候,蜂鸣器发声;当PB3输出低电平的时,蜂鸣器停止发声。由此可见,IO口使用虽然简单,但是和外部电路的匹配设计,还是十分讲究的,考虑越多,设计就越可靠,可能出现的问题也就越少。
二、蜂鸣器编程实践2.1 任务描述
实验现象很简单,我们让开发板上的蜂鸣器发出“嘀”…“嘀”的间隔声。这个实验的目的在于进一步熟悉IO口的使用,如果大家明白了上面蜂鸣器的发声原理,就会发现这个实验的控制方式跟上一章的闪烁灯如出一辙,也是“高电平—延时—低电平—延时”的循环套路。然而,PB3这个引脚跟其他IO口相比有点特殊,我们对它初始化的时候还有一些附加操作,详见下面的代码分析。。
2.2 工程文件清单
按照上一章对工程文件的管理,控制一类新的硬件就增加一对与之匹配的驱动文件,即图3中的beep.c和beep.h。
图3 蜂鸣器工程文件
2.3 工程代码剖析
为了突出源码的功能细节和满足排版要求,这里对源码进行了必要的分割处理。连续且完整的源码请阅读本实验配套的工程。
1. beep.h源码剖析
和上一章控制LED类似,代码清单1里定义了两个宏:BEEP_ON()和BEEP_OFF(),用来实现向PB3输出高电平和低电平的操作,这样既简化了书写,还能见名知意。此外,头文件里肯定少不了函数声明,这里只有一个蜂鸣器端口初始化的函数。
代码清单1 beep.h文件源码
2. beep.c源码剖析
如代码清单2所示,该文件只有一个Beep_Init()函数,完成对蜂鸣器IO口的初始化。
代码清单2 beep.c文件源码
大家应该看到了,上面的初始化跟上一章的LED端口初始化相比,还是有点不一样的。STM32F10x系列的MCU复位后,PA13/14/15 以及 PB3/4默认配置为JTAG功能。但是,这里的PB3并非JTAG调试引脚,于是就有了第35行中的调用GPIO_PinRemapConfig()这个引脚重映射库函数,而参数GPIO_Remap_SWJ_JTAGDisable的意思是禁用JTAG调禁模式,使能SW调试模式。由于SW调试模式并不使用PB3引脚,这样我们就即保障了程序可以正常地下载和调试,又可以用PB3作为普通IO口控制蜂鸣器了。