如果我写得好,请顶我一下,我将再接再厉
很多朋友喜欢搞一些声光的东西,因为能看到,能听到,比搞个什么通信滤波要好玩多了.好!我们就开始做个电子琴.甚至做一个简单的"MP3",呵呵,从简单开始.我们先做电子琴,下一节再做"MP3".
首先,因为是发声装置,我们得先了解发声的原理是什么,这有助于我们接下来的编程:
1.声音是由于物体震动产生的.
2.电流的变化通过线圈就可以使磁场发声变化.
上图是一个喇叭的工作原理.不知道大家看明白了没有.喇叭的电磁铁的电源是接到我们的发声电路上.当电路中的电路发生变化时,电磁铁的吸引力也发生变化.因此就会吸合铁皮.吸合铁皮的时候也带动了薄膜的运动.如果这个吸合过程非常的快.那么薄膜就会发生高频的震动.这个震动就会发出声音.
上面只是一个示意图.实际上的喇叭并不是磁铁吸音铁框的问题,铁框往往也会换成一个磁铁,不过是永磁铁,这样不但可以吸引,还可以排斥.声音幅度更大.
好了,总而言之一句话,就是来来回回的震动就会产生声音.
接下来,我们开始制作吧:电路相当的简单:
看到了吧,电路非常的简单.下面是四个键盘的按键开关.上面就是一个三极管的放大.有人说,我直接接到单片机上就不行.完全可以!我为什么说是个电流放大呢,就是要发生的功率大,声音大.如果你将蜂鸣器直接接到单片机的IO口上,当然是可以的.但是只是用来验证用的,声音太小,实际中是没有用处的.
不过,我可得提醒你:
你如果这样接,那就不对了.为什么?问题就在于,单片机的IO口的驱动能力是绝对有限的,你现在让它直接驱动一个功率比较大(比较LED而言)蜂鸣器,是比较吃力的.但是你却可以这样设计:
什么?没有发现有什么不同?呵呵,看看,蜂鸣器的电压方向变了.为什么这样做,这就是一个开发经验问题了:单片机的IO口吸收电流的能力要远远大于其提供电流的能力.所以不管是驱动蜂鸣器还是驱动LED发光二极管,都要做成低电平有效的这种形式,切实有效!
(本人的实验板,具备上述模块,其原理图和上述完全一致.有实验板的朋友可以接着往下做了)
好了,硬件连接OK了,我们赶紧开始我们的编程吧:
我先说说算法,要实现一定频率的震动,不就是将IO端口进行一定频率的开和关就是了.要进行一定频率的开和关,就必须有一个计数.在这里,定时计数器就比较合适了.自动重装载模式显然比较合适.我们来看看程序吧(鉴于c语言良好的可阅读性,我们先用c语言来编写):
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define SOUNDER P0_BIT2 //用宏定义端口,直观.如以后更改,方便
#define S1 P2_BIT4
#define S2 P2_BIT5
#define S3 P2_BIT6
#define S4 P2_BIT7
#define YES 0
#define NO 1
int YIN[7][2]; //定义一个音阶数组,存放计数器的计数初始值.
int Dir="3",i;
void TimerInit() //计数器初始化函数.
{
TMOD="0x21";
TL0=0;
TH0=0;
TH1=0xE8;
TL1=0xE8;
PCON=0x00;
TR0=1;
TR1=1;
SCON=0x50;
}
void main()
{
// 261 1 //低音叨 频率261
YIN[0][0]= (65536-10000/261/2*100)%256;
YIN[0][1]= (65536-10000/261/2*100)/256;
// 294 2
YIN[1][0]= (65536-10000/294/2*100)%256;
YIN[1][1]= (65536-10000/294/2*100)/256;
// 330 3
YIN[2][0]= (65536-10000/330/2*100)%256;
YIN[2][1]= (65536-10000/330/2*100)/256;
// 349 4
YIN[3][0]= (65536-10000/349/2*100)%256;
YIN[3][1]= (65536-10000/349/2*100)/256;
// 392 5
YIN[4][0]= (65536-10000/392/2*100)%256;
YIN[4][1]= (65536-10000/392/2*100)/256;
// 440 6
YIN[5][0]= (65536-10000/440/2*100)%256;
YIN[5][1]= (65536-10000/440/2*100)/256;
// 494 7
YIN[6][0]= (65536-10000/492/2*100)%256;
YIN[6][1]= (65536-10000/492/2*100)/256;
EA="1"; //开CPU中断
ET0=1; //开定时计数器中断
TimerInit(); //调用初始化计数器函数
for(;;){}
/////////////////////////////////////////////////////////////////////////////////////////////
void TimerOverFlow () interrupt 1 //定时器中段函数
{
if(S1= =YES)
{
SOUNDER=!SOUNDER;
TL0=YIN[0][0];
TH0=YIN[0][1];
}
if(S2= = YES)
{
SOUNDER=!SOUNDER;
TL0=YIN[1][0];
TH0=YIN[1][1];
}
if(S3= =YES)
{
SOUNDER=!SOUNDER;
TL0=YIN[2][0];
TH0=YIN[2][1];
}
if(S4= =YES)
{
SOUNDER=!SOUNDER;
TL0=YIN[3][0];
TH0=YIN[3][1];
}
// Clear the flag
TF0=0;
}
相信大家看得明白程序,很简单.下载到单片机上以后,按S1键,蜂鸣器发出低音1(叨)的声音.按S2发2(ruan)的声音...
用户1611830 2011-2-13 10:34
用户95687 2009-6-6 22:48