娄底职业技术学院
09电大一班
柳宇
C调的音调与频率的对应关系(HZ)
每分钟72拍音调(低)频率音调(中)频率音调(高)频率
1262152311046
2294258721175
3330365931318
4349469841397
5392578451568
6440688061760
7494798871967
以C调为例,其中低音“1”的频率最小,为262HZ,那么有f=1/T可知,“1”的振荡周期为
1/262=3.81ms
如果我们要发出这个频率,那么之要半个周期把电平取反一次即可。即3.81/2=1.905ms
将高电平变低电平,或者将低电平变高电平,就
可以发出262HZ这个频率了。
我们知道13为定时器,(工作方式0)的最大计数为2^13=8192个数,如果单片机使用的晶振为12MHZ,那么一个机器周期就为(1/12)*12=
1us
计满8192个数就需要8.192毫秒,已经大于3.81这个最大值。因此我们可以采用定时器工作方式0
(13位定时计数器模式)。
我们要像让单片机唱歌,那就得发出不同频率,我们采用中断的方式来将电平取反,从而得到一个频率,如果我们改变中断计数器的初
值,就可以改变每次中断的时间,这个中断的时间就是某个音调频率的半周期时间。每次中断我们都将IO脚输出的电平取反一次,因此我们只需要改变中断计数器的初值,就可以使单片机驱动喇叭发出不同的音调。这里我们使用定时器0
。
(高8位赋值)(低5位赋值)
定时器初值设定:TH0=(8192-C)/32
TL0=(8192-C)%32
相信大家都知道这里的高8位初值为什么要除以32,而不除以其他的数吧,很简单,低5位计满是多少?没错,就是32,高8位计一个数时,低5位就得计满32个数!低5位就得对32取余。
同理,如果是16位计数器装初值,高8位那就是除以2^8=256,低8位当然就是对2^8=256取余咯!
C中装的计数值的计数时间为振荡的半周器,半周期为1/2f所以
C=
[(1/2f)*10^6]/1=500000/f
秒
节拍控制:
我们以4/4拍的简谱为例,一分钟为72拍,那么每拍的时间
为60/72=0.83333秒
即833毫秒
1/2拍则为833/2ms1/4拍则为833/4ms半拍为833/2ms
取1/4拍为单位,即833/4=208.25ms下面以《星月神话》
为例编写C程序
这首歌曲本是D调的,但由于没有找到关于D调的资料,在这使用的是C调,如果要编写其他调的音乐,原理是一样的!
下面是C源程序:
#include sbitspeak=P1^0;//低音#definel1262#definel2294#definel3330#definel4349#definel5392#definel6440#definel7494 //中音#definez1523#definez2587#definez3659#definez4698#definez5784 #definez6880#definez7988 //高音#defineh11046#defineh21175#defineh31318#defineh41397#defineh51568#defineh61760#defineh71967 uintcodesz1[]=//本数组必须是整型的{ /*星月神话 金沙*/ z3,z2,z1,z2,z1,l7,//我的一生最美z1,l7,l6,l5,l5,//好的场景l6,z1,l7,l7,l5,l3,//就是遇见l3,0,0,z1,z2,//你 在人 z3,z2,z1,z2,z1,l7,//海茫茫中静静z1,l7,l6,l5,l5,//凝望着你 >256 l6,z3,l7,l7,z1,z2,//陌生又熟z1,z1,z1,z1,//悉l6,l6,z1,l7,z1,z2,//啊~z3,z3,z5,z3,z3,//~~~~~l6,l6,z1,l7,z1,z2,//啊~~~z1,z1,0,z1,z2,//~~尽管z3,z2,z1,z2,z1,l7,//呼吸着同一天z1,l7,l6,l5,l5,//空的气息l6,z1,l7,l7,z1,z2,//却无法拥抱z3,z3,z2,z2,z1,z2,//着你,如果z3,z2,z1,z2,z1,l7,//转换了时空身z1,l7,l6,l5,z1,l5,//份,和姓名但愿l6,z3,z1,l7,z1,z2,//认得你z1,z1,z1,z3,z5,//睛,千年z6,z6,z6,z5,z2,z5,//之后的你会z3,z1,z1,l6,l6,l6,l7,//在哪里,身边z1,z3,z2,z2,z5,z3,//有怎样风z3,z3,z3,z3,z5,//景?我们z6,z6,z6,z5,z2,z2,z5,//的故事并不z3,z1,z1,l6,l6,z3,z2,//算美丽,却如z1,z3,z2,z2,z3,l7,//此难以忘l6,//记 0xff,}; ucharcodesz2[]= { 4,2,2,4,2,2,//我的一生最美4,2,2,4,2,//好的场景4,2,2,4,2,2,//就是遇见4,0,0,2,2,// 你 在人 4,2,2,4,2,2,//海茫茫中静静4,2,2,4,2,//凝望着你4,2,2,4,2,2,//陌生又熟4,1,1,1,//悉 4,2,2,4,2,2,//啊~~~~4,2,2,4,1,//~~~~4,2,2,4,2,2,//啊~~4,1,0,2,2,//尽管 4,2,2,4,2,2,//呼吸着同一天4,2,2,4,1,//空的气息4,2,2,4,2,2,//却无法拥抱4,2,2,4,2,2,//着你如果 4,2,2,4,2,2,//转换了时空身4,2,2,4,2,2,//份和姓名,但愿4,2,2,4,2,2,//认得你眼4,1,1,2,2,//睛 千年 4,2,2,4,2,2,//之后的你会2,2,2,2,4,2,2,//在哪里,身边4,2,2,4,2,2,//有怎样风4,1,1,2,2,//景,我们4,2,2,2,2,2,2,//的故事并不2,2,2,2,4,2,2,//算美丽,却如4,2,2,4,2,2,//此难以忘4,//记 }; voiddelay(){ucharj;uinti; for(i=256;i>0;i--)for(j=255;j>0;j--);}voidmain() //208ms延时 { ucharb,y;EA=1;ET0=1;TR0=1; TMOD=0X00;//定时器工作方式0b=0; while(sz1[b]!=0xff){P0=sz1[b];lp:{ delay();delay();b++;gotolp;} c=500000/sz1[b];TH0=(8192-c)/32;TL0=(8192-c)%32;TR0=1; for(y=sz2[b];y>0;y--) delay(); if((sz1[b]==0)&&(sz1!=0xff)) TR0=0;b++;}speak=1;TR0=0;while(1);//停止} voidt0()interrupt1using1{ speak=~speak;TH0=(8192-c)/32;TL0=(8192-c)%32;} 电路图: 在实际制作时,图中的数码管可以用用流水灯代替,那样随着音乐的播放,流水灯的效果也会改变! 注意:如果当单片机不工作时,扬声器也应该停止工作,如图所示,在程序中应该使P1^0置为低,否则长时间的有电流通过扬声器,既会损坏扬声器,也会对反相器不利! 参考文献《单片机应用100例》王东锋王会良懂冠强编著 因篇幅问题不能全部显示,请点此查看更多更全内容