你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

单片机蜂鸣器的应用

[复制链接]
gaosmile 发布时间:2020-10-2 09:12

有源蜂鸣器与无源蜂鸣器的区别

这里的“源”不是指电源,而是指震荡源。

内部自带震荡源的为有源蜂鸣器,给电就能响,但是响的频率是固定的,即响的声音是固定的。

内部没有震荡源的为无源蜂鸣器,给直流电不能响,需要提供一定频率的脉冲信号才能够有响声,而且声音随着频率的变化而变化。

所以我们要想实现蜂鸣器演奏音乐的话,只能选用无源蜂鸣器。

单片机驱动蜂鸣器发声原理

单片机上面使用的蜂鸣器一般都是无源电磁式的蜂鸣器。它由外壳、振动膜片、磁铁、电磁线圈、及振荡器等组成。

接通电源后,电流通过电磁线圈,致使电磁线圈工作产生磁场,振动膜片在磁铁以及电磁线圈的相互作用下,周期性地振动发出一定频率的声音。

单片机IO引脚输出的电流较小,单片机输出的TTL电平基本上驱动不了蜂鸣器,因此需要设计一个电流放大的电路,具体实现如下图所示。

有源蜂鸣器和无源蜂鸣器的驱动电路是一样的,都是如上图所示。

有源蜂鸣器,只需要改变Buzzer(PB9)引脚的高低电平即可控制蜂鸣器。

当Buzzer引脚为低电平的时候,三极管导通,蜂鸣器响;

当Buzzer引脚为高电平的时候,三极管截止,蜂鸣器不响。

注意此处使用的蜂鸣器为3.3V的蜂鸣器。

无源蜂鸣器,Buzzer引脚要提供一个脉冲信号才能响。下面封装了一个输入参数为频率的无源蜂鸣器驱动函数。

频率的倒数即是时间,此处计算的是T/2的时间,由于1秒钟是1000000us,所以一半即500000,所以下面的延时时间为:

time = 500000/((u32)frq);

具体实现如下所示:

void Sound(u16 frq){ u32 time; if(frq != 1000) { time = 500000/((u32)frq); BEEP = 0; delay_us(time); BEEP = 1; delay_us(time); }else delay_us(1000);}

当单片机用于演奏歌曲时,只需搞清楚两个概念即可,也就是“音符(音调)”和“节拍”。音调表示一个音符该唱的频率,节拍表示一个音符该唱多长的时间。

有了上面函数,我们即可以驱动无源蜂鸣器按照一定的频率发声了,那么我们如何知道某个音的频率呢?

音符

我们查阅网上资料,可以得到如下音符和频率的对应关系:

音符
频率(Hz)
低1 DO262
#1 DO#277
低2 RE294
#2 RE#311
低3 MI330
低4 FA349
#4 FA#370
低5 SO392
#5 SO#415
低6 LA440
#6466
低7 SI494
中1 DO523
#1 DO#554
......

由于钢琴的中央C基频约为261.63Hz,唱“DO”。根据国际标准,相邻的半个音(即钢琴相邻键)的基频相差2^(1/12)倍。

经过计算,我们能得到 #1 DO# 的频率为277。

以此类推,我们能够求出表格中每个音对应的频率,大家可以验证一下上面表格中的数据是否有这样的规律。

钢琴一个八度的12个琴键可以表示为如下形式:

DO  DO#  RE  RE#  MI  FA  FA#  SO  SO#  LA  LA#  SI

其中“#”表示比该音符高半个音的黑键。

按照上面的关系,我们可以得出:升一个八度其频率将翻番。

比如上面表格中的低1 DO和中1 DO的频率就是翻番的。

所以我们想发出低1 DO的音的话,可以调用如下函数:

Sound(262);

节拍

有了音符,也就是知道了这个音怎么发音,那么要想写出一个乐谱,还要知道,这个音发多长时间,这就引出了节拍的概念。

在一张乐谱中,我们经常会看到这样的表达式,如1=C(4/4)、1=G(3/4)... ...等等,这里1=C(4/4)、1=G(3/4)表示乐谱的曲调。

比如:3/4就是乐谱中,以四分音符为节拍,每一小节有三拍。

每一拍的时长是多少秒没有规定,一般在乐谱的前面会写到类似于:

表示该曲子每分钟要弹奏出96个四分音符。

我们一般以四分音符为一拍,一般说来,如果乐曲没有特殊说明,一拍的时长大约为400-500ms。

上图中,其中 1、2为一拍,3、4、5为一拍,6为一拍共三拍。

1、2的时长为四分音符的一半,即为8分音符长;

3、4的时长为八分音符的一半,即为十六分音符长;

5的时长为四分音符的一半,即为八分音符长;

6的时长为四分音符长。

由上面的关系,我们就可以随便找到一个简谱,如果1拍为0.4秒,那么1/4拍是0.1秒,只要设定延迟时间就可求得节拍的时间。然后按照上面的关系写出程序中的乐谱。

精准延时的实现,可以参考今天的另外一篇网文《STM32中精确延时函数的实现》,在我公众号中也可以找到。

比如在我老婆的协助之下,写出了《你笑起来真好看》的乐谱如下:

整个乐谱转译加调整,一共耗时一个半小时,看在如此辛苦的份上,大家赏个三连吧。

u8 music[]={ 5,10,10,5,5,9,9,16,8,8,8,9,10,5,5,16, //想去远方的山川,想去海边看海鸥 6,8,8,6,5,10,10,16,9,8,8,6,9,16, //不管风雨有多少,有你就足够 5,10,10,5,5,9,9,16,8,8,8,6,5,10,10,16, //喜欢看你的嘴角,喜欢看你的眉梢 6,11,11,6,5,10,10,16,9,8,8,6,8,16, //白云挂在那蓝天,像你的微笑 5,12,5,5,12,5,9,16,8,6,8,8,8,10,12,16, //你笑起来真好看,像春天的花一样! 8,6,8,8,8,13,12,10,9,8,6,8,8,10,9,16, //把所有的烦恼,所有的忧愁,统统都吹散 5,12,5,5,12,5,9,16,8,6,8,8,13,12,16, //你笑起来真好看,像夏天的阳光      8,8,8,13,12,10,9,8,6,8,8,9,8,16,         //整个世界全部的时光,美得像画卷。            };

上面数组的数字是MusicalNote数组的索引,进而可以求得该音符的频率:

// 低7 1 2 3 4 5 6 7 中1 中2 中3 中4 中5 中6 中7 高1 不发音 uc16 MusicalNote[] = {247,262,294,330,349,392,440,494,523,587,659,698,784,880,988,1046,1000};

u8 time[] = { 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, //想去远方的山川,想去海边看海鸥 4,4,4,4,4,4,4,4,4,4,4,4,8,4, //不管风雨有多少,有你就足够 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, //喜欢看你的嘴角,喜欢看你的眉梢 4,4,4,4,4,4,4,4,4,4,4,4,8,4, //白云挂在那蓝天,像你的微笑 4,4,2,2,4,4,4,4,4,4,2,2,4,4,8,4, //你笑起来真好看,像春天的花一样! 4,4,2,2,4,4,4,4,4,4,4,4,4,4,8,4, //把所有的烦恼,所有的忧愁,统统都吹散 4,4,2,2,4,4,4,4,4,4,4,4,4,8,4, //你笑起来真好看,像夏天的阳光 4,4,4,4,4,4,4,4,4,4,4,4,8,4, //整个世界全部的时光,美得像画卷。 };

数组time中的数字代表music数组中每个音的节拍(响的时间),其中4代表一个四分音符,即一拍,本程序中为400ms,8代表一个二分音符,代表两拍,即800ms;2代表一个八分音符,1/2拍,即耗时200ms。

这次的应用明显有一个问题,就是整个播放音乐的过程中是一个死循环,效率很低,播放过程中很难打断。

由于今天重点介绍的是蜂鸣器的应用,所以先这样,下次咱们再换一种实现方式。


收藏 评论0 发布时间:2020-10-2 09:12

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版