单片机演奏音乐一般说来,单片机演奏音乐基本都是单音频率,它不包含相应幅度的谐波频率,也就是说不能象电子琴那样能奏出多种音色的声音。因此单片机奏乐只需弄清楚两个概念即可,也就是“音调”和“节拍”。音调表示一个音符唱多高的频率,节拍表示一个音符唱多长的时间。在音乐中所谓“音调”,其实就是我们常说的“音高”。在音乐中常把五线谱中央C上方的A音定为标准音高,其频率f=440Hz。当两个声音信号的频率相差一倍时,也即f2=2f1时,则称f2比f1高一个倍频程,在音乐中1与.1(1前面的点应在1的上面),2与.2……正好相差一个倍频程,在音乐学中称它相差一个八度音。在一个八度音内,有12个半音。以1—i八音区为例,12个半音是:1—#1、#1—2、2—#2、#2—3、3—4、4—#4,#4—5、5一#5、#5—6、6—#6、#6—7、7—i。其中“#”表示半音,用于升高或降低半个音。这12个音阶的分度基本上是以对数关系来划分的。如果我们只要知道了这十二个音符的音高,也就是其基本音调的频率,我们就可根据倍频程的关系得到其他音符基本音调的频率。知道了一个音符的频率后,常采用的方法就是通过一个延时程序,延时对应频率周期的二分之一周期(即t=1/2f)后,将单片机上连接蜂鸣器的I/O(P3.7)口来回取反,或者说来回清零,置位,从而让蜂鸣器发出声音,为了让单片机发出不同频率的声音,我们只需将不同的延时时间值t赋给延时程序即可实现。例:我门以440Hz的声音频率来计算,其对应的时间t=1/2f=1/2*440=1136us但在实际程序中常采用查表的方式来取的t值,而为了节约存储器空间则将t值以字节来进行存储,由于大部分t值都大于256。所以,需将t值除以一个常数(t/x)使其小于256。那么,在查表取得t值后就要再乘上该常数后再赋给延时程序。以下为常用音符对应的频率和二分之一周期值t:低音音符频率Hz周期/2周期/2/20中音音符频率Hz周期/2周期/2/20126219080x5f15239560x2f1#27718040x5a1#5539040x2d229317060x5525868540x2a2#31116080x502#6218060x28332915200x4c36587600x26434914360x4746977180x244#37013520x434#7396760x22539212760x3f57836380x205#41512040x3c5#8306020x1e644011360x3868795680x1c6#46610720x356#9315360x1b749410120x3279875060x19高音音符频率Hz周期/2周期/2/20110454780x17注:在音符的底部加一点表示低音,在音符的顶部加一点表示高音。表中的20为方便查表而除以的一个常数。1#11064520x16211714260x152#12414020x14313163800x13413933580x124#14763400x11515633200x105#16583020x0f617552840x0e6#18602680x0d719712540x0c一首乐曲的每一个音符除了频率之外,还会有不同的节拍,确定节拍的方法有以下几种:1.在一张乐谱中,我们经常会看到这样的表达式,等等,这里1=C,1=G表示乐谱的曲调,和我们前面所谈的音调有很大的关联,就是用来表示节拍的。以为例加以说明,它表示乐谱中以四分音符为节拍,每一小结有三拍。比如:其中1、2为一拍,3、4、5为一拍,6为一拍共三拍。1、2的时长为四分音符的一半,即为八分音符长,3、4的时长为八分音符的一半,即为十六分音符长,5的时长为四分音符的一半,即为八分音符长,6的时长为四分音符长。那么一拍到底该唱多长呢?一般说来,如果乐曲没有特殊说明,一拍的时长大约为400—500ms。我们以一拍的时长为400ms为例,则当以四分音符为一节拍时,四分音符的时长就为400ms,八分音符(即1/2拍)的时长就为200ms,十六分音符(1/4拍)的时长就为100ms。2.若知道了一首歌曲的每分钟的节拍数,也可求出每一节拍的时间。以每分钟94拍为例:一拍的时间=60/94=0.64s=640ms节拍时间S节拍时间1/40.161/20.323/40.4810.641又1/40.801又1/20.961又3/41.1221.282又1/41.442又1/21.602又3/41.7631.923又1/42.083又1/22.243又3/42.4042.56当知道了每一节拍的时长后,就可利用单片机的定时器产生一个基准时间,比如说以10ms的时长为基本延时时间,那么,对于一个音符,如果它为1/4拍100ms的时长,则只需调用10次延时程序,如果它为2/4拍200ms,则只需调用20次延时程序,如果它为1拍400ms,则只需调用40次延时程序,依次类推。在简谱中,1、2、3、4、5、6、7这七个基本音符,不仅表示音的高低,而且还是表示时值长短的基本单位,称为四分音符,其他音符均是在四分音符的基础上,用加记短横线-和附点·表示。1.单纯音符在简谱中,如果音符时值的长短用短横线-表示,就称为单纯音符。单纯音符除四分音符外,有以下两种形式:⑴在基本音符右侧加记一条短横线,表示增长一个四分音符的时值。这类加记在音符右侧、使音符时值增长的短横线,称为增时线。增时线越多,音符的时值越长。⑵在基本音符下方加记一条短横线,表示缩短原音符时值的一半。这类加记在音符下方、使音符时值缩短的短横线,称为减时线。减时线越多,音符的时值越短。单纯音符的名称以全音符为标准而定。如:全音符的二分之一称为二分音符,全音符的四分之一称为四分音符,其余类推。常见的单纯音符的名称、写法及时值长短列表如下:从上表可以看出,相邻两种音符之间的时值比例为2∶1。现将单纯音符之间的时值比例列表(如右图)2.附点音符在简谱中,加记在单纯音符的右侧的.使音符时值增长的小圆点·,称为附点.加记附点的音符称为附点音符。附点本身并无一定的长短,其长短由前面的单纯音符来决定。附点的意义在于增长原音符时值的一半,常用于四分音符和小于四分音符的各种音符之后。例如:附点四分音符:附点八分音符:附点十六分音符:在简谱中,大于四分音符的单纯音符通常不加记附点,而用增时线来表示。例如;附点二分音符:不用表示。带有两个附点的单纯音符称为复附点音符,第二个附点表示增长第一个附点时值的一半,即音符时值的四分之-。例如:复附点常用于器乐曲中,在歌曲中很少使用。通过上面关于一个音符音调和节拍的确定方法,我们就可以在单片机上实现演奏音乐了。具体的实现方法为:将乐谱中的每个音符的音调及节拍变换成相应的音调参数和节拍参数,将他们做成数据表格,存放在存储器中,通过程序取出一个音符的相关参数,播放该音符,该音符唱完后,接着取出下一个音符的相关参数……,如此直到播放完毕最后一个音符,根据需要也可循环不停地播放整个乐曲。另外,对于乐曲中的休止符,一般用FFH表示,乐曲结束音符用00H来表示。例:程序1:/*歌曲选择时应按住设置间3秒以上,然后按上或下键进行选择,然后再按设置键退出*/#includereg52.hsbitspek=P3^7;//声音输出端sbitset=P3^2;//设定及退出键,按奇数次为设定功能;偶数次为退出功能sbitup=P3^1;//上一曲sbitdown=P3^0;//下一曲bitflag1,flag2;//按键扫描标志位,新键值标志位unsignedcharf_t,n,i,key,k_max;//音符频率对应的二分之一周期值,节拍常数值,查表用计数器,键值,最大键值unsignedchar*p_music;//指向音乐数据数组的指针voidtimer_ms(unsignedchartim);//毫秒级延时函数声明voidtimer_us(unsignedchart);//微秒级延时函数voidkey_scan(void);//按键扫描函数voidkey_manage();//键值处理函数//格式为:频率常数,节拍常数,频率常数,节拍常数unsignedcharcodemusic_table1[]={0x18,0x30,0x1c,0x10,0x20,0x40,0x1c,0x10,0x18,0x10,0x20,0x10,0x1c,0x10,0x18,0x40,0x1c,0x20,0x20,0x20,0x1c,0x20,0x18,0x20,0x20,0x80,0xff,0x20,0x30,0x1c,0x10,0x18,0x20,0x15,0x20,0x1c,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2b,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0xff,0x20,0x20,0x1c,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2b,0x20,0x30,0x20,0x2b,0x40,0x20,0x20,0x1c,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2b,0x20,0x30,0x20,0x2b,0x40,0x20,0x30,0x1c,0x10,0x18,0x20,0x15,0x20,0x1c,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2b,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0x20,0x30,0x1c,0x10,0x20,0x10,0x1c,0x10,0x20,0x20,0x26,0x20,0x2b,0x20,0x30,0x20,0x2b,0x40,0x20,0x15,0x1f,0x05,0x20,0x10,0x1c,0x10,0x20,0x20,0x26,0x20,0x2b,0x20,0x30,0x20,0x2b,0x40,0x20,0x30,0x1c,0x10,0x18,0x20,0x15,0x20,0x1c,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2b,0x20,0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,0x1c,0x10,0x18,0x40,0x1c,0x20,0x20,0x20,0x26,0x40,0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,0x80,0x00};//八月桂花香unsignedcharcodemusic_table2[]={0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x2