资源描述:
《基于c51单片机编写简单蜂鸣器音乐程序的方法》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、很多初学单片机的朋友会接触到如何使用蜂鸣器来编曲的的问题,今天用到蜂鸣器,就顺便写了这个帖子,希望能对一些初学的朋友能有些帮助。据我所知,声音的音调不同是因为声音的频率不同造成的。那么,就可以通过单片机发送不同频率的脉冲信号给蜂鸣器,来达到让蜂鸣器发出不同音调声音的目的。不同频率的脉冲信号就意外着每个脉冲之间必须有着不一样的时差,这可以通过延时或者定时计数器定时的方式来实现。定时计数器定时的方法是相对精确的,然而我们人耳对于声音在相位上的变化的感应是不敏感的,而且普通蜂鸣器在商业上的用途不是专门用来发音乐,误差较大,因此通过延时程序延时的方法往往也能
2、达到想要的目的。因此我认为,使一个蜂鸣器发出一定频率的程序是可以这样写的:首先是了解你要发出声音音调的频率。可以通过一张简单的表得知:从表中你可以计算出你要的音的周期,例如低1DO,为262hz,那么它的周期为1/262s也就是每次脉冲取反的中间延时半个周期即可。然后,编写一个能发相应频率声音的子程序。这个子程序中往往须包括以下二个部分:一,控制脉冲形成的代码,电平取反过程中含有相应的延时;二,控制脉冲持续时间的代码,持续的时间时候常常和音乐的拍子有相关性。最后在主程序中运行子程序,通过读rom里面的数组来达到连续播放各种不同音调的音的目的,这样听起
3、来就像一首曲子了。以下是我按以上方法编写的一个小程序:/***********************************************************************************************以下是本人编写的一段简单音乐程序,程序已经在板子上调试成功,水平有限,如有不正确的地方请多包涵*******************************************************************************************************/#inc
4、lude#include//内部包含延时函数_nop_();typedefunsignedcharuchar;typedefunsignedintuint;uintc;sbitspk=P2^0;//定义p2.0口为电平信号输出端uintcodemusic[]=//这是一个“童话”谱子的数组,与m_t()子程序中的十六进制数一一对应,0xff代表每次音乐的停顿,0x00表示音乐的结束{0x16,0x10,0x0d,0xff,0x0d,0x10,0x0d,0xff,0x0d,0x10,0x0d,0x10,0x0d,
5、0x07,0x01,0xff,0x01,0x0d,0x16,0x1c,0xff,0x1c,0x1c,0x16,0x07,0x07,0x10,0x0d,0xff,0x01,0x0d,0x16,0x1c,0xff,0x1c,0x1c,0x22,0x1c,0x16,0x10,0x0d,0x10,0x0d,0x07,0x01,0x00};//*//****************************************voiddelay_us(uinti)//延时nus的程序{ucharj;for(j=0;j
6、elay_ms(uintj)//延时nms的子程序{uinti;while(j--){for(i=0;i<128;i++);}}uintm_t(uinti)//*这是一个用来把音调与延时的时长一一对应的子程序{uintj,s;s=100000;switch(i)//*下面让不同音高的音调与各十六进制数相对应,例如其中“1“有6种音高可选择(不懂音乐,我自己的说法){/*1*/case0x01:j=s/262;break;case0x02:j=s/277;break;case0x03:j=s/523;break;case0x04:j=s/554;bre
7、ak;case0x05:j=s/1046;break;case0x06:j=s/1109;break;/*2*/case0x07:j=s/294;break;case0x08:j=s/311;break;case0x09:j=s/587;break;case0x0a:j=s/622;break;case0x0b:j=s/1175;break;case0x0c:j=s/1245;break;/*3*/case0x0d:j=s/330;break;case0x0e:j=s/659;break;case0x0f:j=s/1318;break;/*4*/ca
8、se0x10:j=s/349;break;case0x11:j=s/370;break;case0x12:j