当单片机能唱出一个带有音长的音调,那么让它继续唱出一个曲谱应该不会变得困难。在本节我们就来实现这个任务。
首先我们把曲谱的信息编制成两个数组,一个是曲调的,另一个是每个曲调对应音长的。考虑到曲子播放完成后要结束,我们在曲调的数组末尾加上一个0作为结束字符。我们播放曲子的思路是从曲调数组中按先后顺序取音调值,然后把该音调对应的定时器初始值送到定时器寄存器,同时把对应的音长数据也送到音长控制变量里;开启两个定时器,在各自的中断服务程序完成对这个音调的播放;当一个音调播放结束,我们立一个标志位比如tone_off=1;在主程序的while(1)循环里根据这个标志位去取下一个音调和音长,如此循环工作,直到曲调取到的值是0,表示曲子播放结束。大家按照这个思路先作些设计和调试,然后结合本节的视频讲解做些总结和分析。
在程序设计中有一些细节大家要关注到,比如在播放一个曲调结束后要把tone_off标志位及时清零,以免影响下一个音调的播放等等。请大家按照这样的程序设计思路把曲谱补充完整,或者自己新找来你自己喜欢的一首歌的曲谱,编出它对应的音调和音长的数组,然后享受自己的音乐作品。为了不影响系统变量的容量,我们把数组定义为code类型,就在uchar后面插入一个code即可,这样这个数组就以ROM形式保存了,不占用RAM的容量。

形如:uchar code music[]={5,3,5,8,6,8,6,…………};
进一步地,大家在程序里输入多首歌曲,从而建成一个曲库,设计一个点唱机,能通过按键选择歌曲,也具备播放和暂停功能等等。请大家在课余尝试做一做。

