51单片机对电磁式蜂鸣器的驱动

控制/MCU

1882人已加入

描述

首先应该了解一下蜂鸣器音乐播放的原理,在这里我只讲一下电磁式蜂鸣器驱动原理(还有一种是压电式蜂鸣器):

电磁式蜂鸣器驱动原理:

蜂鸣器发声原理是电流通过电磁线圈,使电磁圈产生磁场来驱动振动膜发声的。因此需要一定的电流才能驱动它,而单片机I/O引脚输出的电压较小。单片机输出的TTLK电平基本驱动不了蜂鸣器,因需要增加一个放大电路。这里用三极管作为放大电路。下面是原理图:

51单片机

我这里的J8端是跟芯片的P1^5端口相连,当P1^5输出高电平时,三极管截止,蜂鸣器不发声,反之,输出低电平时,蜂鸣器发声。

而要驱动蜂鸣器能像唱歌一样的发声,其实只要使蜂鸣器发出频率和持续时间不同的声音即可。周期等于频率的倒数,所以可以通过频率知道这段的时间,所以可以通过调用延时函数或者定时器实现,同样的发声的持续时间也可以通过延时函数实现,所以让蜂鸣器唱歌最关键的就是知道要延长多少时间!

用单片机来演奏音乐,,只要搞清楚两个概念就好了,分别是“音调”和“节拍”。

音调表示一个音符该唱的频率。

节拍表示一个音符该唱多少时间。

这里有两种方法来实现该功能:

(1)查表法

这个方法复杂的地方在于你要找出每个音符相对应的频率(根据音符;频率对照表找),然后根据公式转换为相应的时间(取半周期),然后通过延时函数实现。最后编程实现。

先上代码好了:

1/***************************************************2实验名称:用蜂鸣器播放生日快乐歌3实验说明:不使用定时器中断,所有频率完全用延时实现4实验时间:2014/12/55***************************************************/67#include8#defineucharunsignedchar9#defineuintunsignedint1011sbitBEEP=P1^5;//蜂鸣器接芯片的P1^5端口1213/*生日快乐歌的音符频率表,不同频率由不同的延时来决定音符频率明显大于数组里面的值,但是因为是8位寄15存器,所以最多只能放511,但是有的频率大于511,所以只能在延时函数中乘上相应的值来接近实际乐谱频率*/17ucharcodeSONG_TONE[]=18{212,212,190,212,159,169,212,212,190,212,142,159,212,19212,106,126,159,169,190,119,119,126,159,142,159,0};2021//生日快乐歌节拍表,节拍决定每个音符的演奏长短,只是取个系数,并非准确的值22ucharcodeSONG_LONG[]=23{9,3,12,12,12,24,9,3,12,12,12,24,9,243,12,12,12,12,12,9,3,12,12,12,24,0};2526//延时27voidDelayMS(uintx)28{29uchart;30while(x--)31for(t=0;t《120;t++);32}3334//播放函数35voidPlayMusic()36{37uinti=0,j,k;38while(SONG_LONG[i]!=0“|SONG_TONE[i]!=0)39{40/*播放各个音符,SONG_LONG为拍子长度,一个节拍大概为400ms-500ms,这里的节拍又受下面一个音符的影响,所以只能根据大概的来取值*/41for(j=0;j整个流程是这样的:首先根据生日快乐歌的乐谱将各个音调转换为相应的频率。比如:左边是生日快乐歌乐谱,右边是音符频率转换表

51单片机

51单片机

这里先来了解一下乐谱的一点知识,左边乐谱数字下面有点说明是低音,没点说明就是普通的,数字上面有点就是高音,而5的低音就是4.5,高音是5.5,其他音符也是相应的道理。乐谱的左上方有写“1=F”,而一般的乐谱都是C调,就是“1=C”,注意,乐谱里面的1234567(哆啦咪发索拉西多)相对应的不是ABCDEFG而是CDEFGAB!所以这里规定是F调的话,那么就说明2就要唱G,3要唱A,……7要唱E,所以这里的低音5对应的应该是低音的1.5!!!!就是所谓的要相应的左移或者右移。如果还是不明白的话,看下面:1原本对应的应该是C,4原本应该对应的是F,对吧?然后现在1对应的变成F了,就相当于对应了4,对吧?那么1.5对应的是什么?4.5咯!那2对应的是什么?5呗!那么好了咯,低音5是4.5,是不是就是等于1.5?所以半周期就是1803μs。至于为什么是根据半周期算,那是因为单片机是通过循环对蜂鸣器接的端口置位,复位来使发声的,所以就是半周期。因为我用的是无源的蜂鸣器,有源的蜂鸣器就是全周期了。然后就是按照上述道理,一个个转换,并用延时函数实现,因为每个音符的转换频率都不一样,要么使用多个延时函数一个个实现准确的音调频率,但是这样太烦,而且单片机本身就不是专门弄来唱歌的。我们不应该为难他们,所以自己将就一下就算了。所以延时函数为了适应每个音调都有差不多的频率,这个就靠自己计算了,而且不同的歌那个值还不一样,所以这就是这个问题的难点。接下来的就是那个唱多久的问题,一般的歌曲默认的一个节拍是400ms-500ms。同样的看乐谱左上方,它有写“3/4”,意思是以四分音符为节拍,每一个小结有三拍。而在每个数字下面有一条横线,那时间就是那个节拍的时间乘上0.5,有两条就乘上0.25,三条就乘以0.125。。。音乐的基本知识就别为难我了,我是个音乐白痴。。所以我就这么理解了。。哈哈哈哈哈~而至于节拍转换为频率,也是有相应的表的,见下:

51单片机

同样的也是通过延时函数来实现,当然也是会有误差的。而至于延时函数怎么写,见[51单片机学习笔记ONE]编程思想的话挺简单的,就是先将音符频率和所要唱的时间转换好,放到两个数组里面。然后在主程序里面,通过延时达到相应频率,唱完一遍,停一会,接着唱就好了。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分