我们知道,蜂鸣器可分为有源蜂鸣器和无源蜂鸣器,有源蜂鸣器内置了频率发生电路,因此其通电就能够发出声音,但是其频率是固定的,而无源蜂鸣器内部没有频率发生电路,需要外界给予频率,因此适用于单片机控制使其发出不同的音调频率。在这一点有源蜂鸣器是做不到的。现在就利用无源蜂鸣器播放不同的音乐。
无源蜂鸣器的原理图:
蜂鸣器发声原理是电流通过电磁线圈,使电磁圈产生磁场来驱动振动膜发声的。因此需要一定的电流才能驱动它,而单片机I/O引脚输出的电压较小。单片机输出的TTL电平基本驱动不了蜂鸣器,因需要增加一个放大电路。这里用三极管作为放大电路。
由原理图分析知:通过控制晶体三极管的导通和截止就可以控制蜂鸣器的开关,因此通过控制GPIO_PB5引脚的高低电平的变化就可以控制三极管的导通截止。但是需要注意的是,在使用无源蜂鸣器时,单纯地给它高电平是不能使其导通的,这反而会时蜂鸣器中的项圈持续发热,长时间甚至可能损坏蜂鸣器,因此我们必须保证在空闲的状态下引脚的电平是高电平,使三极管截止。原理图中加入了上拉电阻正是防止在空闲状态下损坏蜂鸣器。
那么蜂鸣器能够发出不同的声音的原理是通过PWM波来驱动实现的,通过调节PWM波的频率就可以输出不同的声音。即引脚高低电平的变化,来产生频率一定的方波进而驱动蜂鸣器,而通过延时长度就可控制其节奏。假设要产生1kHz的频率,即每秒产生1000个振动周期,也就是一个频率周期就是1000us,所以通过控制方波高低电平的占空比就可以发出1kHz的音调频率。
软件实现:
基于STM32固件库函数控制蜂鸣器播放音乐
部分主要程序:
第一个枚举用于定义各个音阶对应的频率值,这样封装的目的是可以让简谱数组更易维护,接下来就是定义的简谱数组,只要按照简谱结构编写数组,就可以让单片机弹奏你的音乐。该数组有三部分组成,第一部分就是音调,第二部分就是数字表示的延时节奏,最后是两个 0,用于告诉单片机,此时演奏完毕,退出演奏循环。用两个 0 的目 的是,如果简谱是一个节奏对应一个延时的话,那么它是偶数个演奏单元,所以会用到最后 一个零,如果是奇数个演奏单元,就用到第一个 0 来标识结束。结束状态的控制也可以通过for循环控制。
通过下载调试最后能够达到很好的效果,如果想要达到更佳的效果可以通过调试延时长度达到自己想要的效果。