前几天带儿子逛商场,儿子看上一款音乐盒,小小的一个东西要几十块钱,感觉很不划算……于是带他吃了一顿比萨,很快他就忘了这回事啦(与儿子斗其乐无穷),回来以后,孩子又把这事记起来了,感情还是对音乐盒念念不忘啊,作为一名学习电子设计的小学生,正好借这个机会练练手,给孩子做一款独一无二的遥控音乐盒。
遥控这个东西实现手段很多,红外、蓝牙、wifi……做这玩意太复杂啦,咱们的主要目的是做音乐盒啊,于是花了8块从万能的某宝上买了一款【2262/2272四路无线遥控套件】(还包邮哦)
先用面包板搭一下,可是音乐从哪弄呢?当然从黑坛里搜啊。
记得很早之前在群里看到一位群友写过一篇【51单片机音乐盒1602显示 Proteus仿真程序】,地址为:
http://www.51hei.com/bbs/dpj-183341-1.html
可是……
可是……
可是看到一大段乐谱,我头直接就大了,这得需要多少单片机空间啊,咱的STC89才4K程序空间,本着写单片机要节约每一个字节的原则,我对这段乐谱进行了改造!!!压缩它,弄死它!原乐谱如下:
//《烟花易冷》unsigned char code song1[]={ 5,2,1, 3,2,1, 2,2,2, 2,2,4, 3,2,1, 1,2,1, 2,2,1, 3,2,4, 5,2,1, 3,2,1, 2,2,2, 2,2,2, 5,1,1, 3,2,1, 4,2,1, 3,2,4, 3,2,1, 3,2,1, 7,2,1, 3,2,1, 2,2,2, 1,2,1, 7,1,1, 1,2,1, 2,2,1, 3,2,1, 6,2,3, 6,1,1, 1,2,1, 3,2,1, 2,2,1, 6,1,1, 1,2,1, 7,1,1, 5,1,1, 6,1,6, 5,2,1, 3,2,1, 2,2,2, 2,2,1, 2,2,1, 3,2,1, 1,2,1, 2,2,1, 3,2,4, 5,2,1, 3,2,1, 2,2,2, 2,2,1, 2,2,1, 5,1,1, 3,2,1, 4,2,1, 3,2,4, 3,2,1, 3,2,1, 7,2,3, 3,2,1, 2,2,2, 1,2,1, 7,1,1, 1,2,1, 2,2,1, 3,2,1, 6,2,3, 6,1,1, 1,2,1, 3,2,1, 2,2,1, 6,1,1, 1,2,1, 7,1,2, 5,1,2, 6,1,6, 0,0,0 }; //《发如雪》 unsigned char code song2[]={ 5,1,1, 2,2,1, 3,2,2, 2,2,1, 3,2,1, 5,2,1, 6,2,1, 5,2,3, 1,2,1, 2,2,1, 3,2,1, 6,2,1, 5,2,1, 3,2,1, 5,2,3, 5,2,1, 6,2,1, 1,3,2, 6,2,1, 5,2,1, 3,2,1, 5,2,1, 3,2,2, 1,2,1, 2,2,1, 3,2,1, 1,2,1, 6,1,1, 3,2,1, 2,2,1, 5,1,1, 2,2,1, 3,2,2, 2,2,1, 3,2,1, 5,2,1, 6,2,1, 5,2,3, 1,2,1, 2,2,1, 3,2,1, 6,2,1, 5,2,3, 5,2,1, 6,2,1, 1,3,2, 6,2,1, 5,2,1, 3,2,1, 5,2,1, 3,2,2, 1,2,1, 6,1,1, 3,2,1, 2,2,1, 1,2,1, 6,1,1, 1,2,1, 2,2,1, 2,2,1, 1,2,4, 0,0,0 }; //《简单爱》 unsigned char code song3[]={ 5,1,1, 1,2,1, 2,2,1, 3,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1, 5,2,1, 4,2,1, 3,2,1, 2,2,3, 5,1,1, 1,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1, 5,2,1, 6,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2, 1,2,1, 6,1,1, 2,2,1, 2,2,1, 3,2,1, 3,2,1, 1,2,1, 5,2,1, 1,2,1, 5,2,1, 1,2,1, 7,1,1, 1,2,1, 1,2,1, 6,1,1, 2,2,1, 2,2,1, 3,2,1, 3,2,1, 5,2,1, 5,2,1, 5,2,1, 6,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2, 5,1,1, 1,2,1, 2,1,2, 3,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1, 5,2,1, 4,2,1, 3,2,1, 2,2,3, 5,1,1, 1,2,1, 2,2,1, 3,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2, 1,2,1, 6,1,1, 2,2,1, 2,2,1, 3,2,1, 3,2,1, 1,2,2, 5,2,1, 1,2,1, 5,2,1, 5,2,1, 7,1,1, 1,2,1, 0,0,0 }; //《世上只有妈妈好》 unsigned char code song4[]={ 6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, //6,2,3代表6,中音,3个半拍; //5,2,1代表5,中音,1个半拍; //3,2,2代表3,中音,2个半拍; //5,2,2代表5,中音,2个半拍; //1,3,2代表1,高音,2个半拍; //... 5,2,1,6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2, 5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0}; //《当你孤单你会想起谁》 unsigned char code song5[]={ 3,2,2, 3,2,1, 4,2,1, 3,2,2, 2,2,1, 1,2,1, 2,2,2, 5,2,2, 2,2,2, 2,2,3, 1,2,2, 1,2,1, 2,2,1, 1,2,2, 7,1,1, 6,1,1, 7,1,2, 3,2,2, 7,1,2, 7,1,3, 6,1,2, 2,2,1, 3,2,1, 2,2,1, 1,2,1, 6,1,2, 5,1,2, 2,2,1, 3,2,1, 2,2,1, 1,2,1, 6,1,2, 6,1,2, 2,2,1, 3,2,1, 2,2,1, 1,2,1, 6,1,1, 7,1,1, 1,2,6, 0,0,0 }; //《乡间小路》 unsigned char code song6[]={ 3,1,2, 3,1,1, 3,1,1, 6,0,1, 6,0,1, 1,1,2, 6,0,1, 5,0,1, 6,0,4, 6,0,2, 6,0,1 ,6,0,1, 6,0,2, 6,0,1, 1,1,1, 2,1,2, 2,1,1, 3,1,1, 2,1,4, 3,1,1, 3,1,1, 3,1,1, 2,1,1, 4,1,2, 4,1,2, 3,1,2, 2,1,1, 1,1,1, 2,1,4, 7,0,1, 7,0,1, 7,0,1, 6,0,1, 5,0,1, 5,0,1, 6,0,1, 7,0,1, 7,0,1, 6,0,1, 5,0,1, 6,0,4, 6,1,2, 3,1,1, 6,1,1, 7,1,1, 6,1,1, 5,1,1, 5,1,2, 5,1,1, 2,1,1, 5,1,1, 6,1,1, 5,1,1, 4,1,1, 4,1,2, 4,1,1, 3,1,1, 2,1,2, 1,1,1, 2,1,1, 3,1,1, 2,1,1, 1,1,1, 2,1,1, 3,1,4, 6,1,2, 3,1,1, 6,1,1, 7,1,1, 6,1,1, 5,1,1, 5,1,2, 2,1,1, 5,1,1, 6,1,1, 5,1,1, 4,1,1, 0,0,0}; //《送别》 unsigned char code song7[]={ 5,1,2, 3,1,3, 5,1,1, 1,2,3, 6,1,2, 1,2,2, 5,1,4, 5,1,2, 1,1,1, 2,1,1, 3,1,2, 2,1,1, 1,1,1, 2,1,4, 5,1,2, 3,1,1, 5,1,1, 1,2,2, 7,1,1, 6,1,2, 1,2,2, 5,1,4, 5,1,2, 2,1,1, 3,1,1, 4,1,2, 7,0,1, 1,1,4, 6,1,2, 1,2,2, 1,2,4, 7,1,2, 6,1,1, 7,1,1, 1,2,4, 6,1,1, 7,1,1, 1,2,1, 6,1,1, 6,1,1, 5,1,1, 3,1,1, 1,1,1, 2,1,8, 5,1,2, 3,1,1, 5,1,1, 1,2,2, 7,1,1, 6,1,2, 1,2,2, 5,1,4, 5,1,2, 2,1,1, 3,1,1, 4,1,2, 7,0,2, 1,1,4, 0,0,0}; //《最浪漫的事》 unsigned char code song8[]={ 5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1, 3,1,1, 5,1,5, 5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1, 6,1,1, 1,1,5, 1,1,1, 2,1,1, 3,1,1, 2,1,1, 2,1,1, 2,1,1, 1,1,1, 2,1,1, 1,1,1, 6,1,1, 3,1,2, 2,1,3, 5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1, 6,1,1, 1,1,5, 1,1,1, 2,1,1, 3,1,1, 4,1,2, 4,1,1, 5,1,1, 6,1,1, 6,1,1, 5,1,1, 6,1,2, 1,2,1, 6,1,3, 1,2,1, 6,1,1, 5,1,1, 5,1,4, 1,1,1, 6,1,1, 5,1,5, 5,1,1, 6,1,1, 1,2,1, 3,1,1, 2,1,1, 3,1,1, 1,1,6, 0,0,0};
复制代码第一个数字音符的范围是:1到,代表哆来咪发...
第二个数字范围是:0123之一,代表低音\中音\高音\超高音(第几个八度)
第三个数字范围是:嗯……又仔细看了一下,最大的值为6,于是写了一段note.js程序,把每首乐谱进行了压缩(顺手10字节对齐一下),把三个字节压缩为1个字节,直接把乐谱的空间节约了三分之二……
压缩后的乐谱代码如下:
////////////////////////////////////////////////7-5:对应的音符1234567之一(第几个音),代表哆来咪发... //4-3:0:低音, 1:中音, 2:高音, 3:超高音(第几个八度) //2-0:时间长度+1, 以半拍为单位, 乐曲数据表的结尾是0 ////////////////////////////////////////////// //《烟花易冷》 BYTE code song0[]={ 0xb0, 0x70, 0x51, 0x53, 0x70, 0x30, 0x50, 0x73, 0xb0, 0x70, 0x51, 0x51, 0xa8, 0x70, 0x90, 0x73, 0x70, 0x70, 0xf0, 0x70, 0x51, 0x30, 0xe8, 0x30, 0x50, 0x70, 0xd2, 0xc8, 0x30, 0x70, 0x50, 0xc8, 0x30, 0xe8, 0xa8, 0xcd, 0xb0, 0x70, 0x51, 0x50, 0x50, 0x70, 0x30, 0x50, 0x73, 0xb0, 0x70, 0x51, 0x50, 0x50, 0xa8, 0x70, 0x90, 0x73, 0x70, 0x70, 0xf2, 0x70, 0x51, 0x30, 0xe8, 0x30, 0x50, 0x70, 0xd2, 0xc8, 0x30, 0x70, 0x50, 0xc8, 0x30, 0xe9, 0xa9, 0xcd, 0x00 }; //《发如雪》 BYTE code song1[]={ 0xa8, 0x50, 0x71, 0x50, 0x70, 0xb0, 0xd0, 0xb2, 0x30, 0x50, 0x70, 0xd0, 0xb0, 0x70, 0xb2, 0xb0, 0xd0, 0x39, 0xd0, 0xb0, 0x70, 0xb0, 0x71, 0x30, 0x50, 0x70, 0x30, 0xc8, 0x70, 0x50, 0xa8, 0x50, 0x71, 0x50, 0x70, 0xb0, 0xd0, 0xb2, 0x30, 0x50, 0x70, 0xd0, 0xb2, 0xb0, 0xd0, 0x39, 0xd0, 0xb0, 0x70, 0xb0, 0x71, 0x30, 0xc8, 0x70, 0x50, 0x30, 0xc8, 0x30, 0x50, 0x50, 0x33, 0x00 }; //《简单爱》 BYTE code song2[]={ 0xa8, 0x30, 0x50, 0x70, 0x50, 0x70, 0x90, 0xb0, 0xb0, 0xb0, 0x90, 0x70, 0x52, 0xa8, 0x30, 0x50, 0x70, 0x90, 0xb0, 0xb0, 0xb0, 0xd0, 0xb1, 0x50, 0x70, 0x31, 0x30, 0xc8, 0x50, 0x50, 0x70, 0x70, 0x30, 0xb0, 0x30, 0xb0, 0x30, 0xe8, 0x30, 0x30, 0xc8, 0x50, 0x50, 0x70, 0x70, 0xb0, 0xb0, 0xb0, 0xd0, 0xb1, 0x50, 0x70, 0x31, 0xa8, 0x30, 0x49, 0x70, 0x50, 0x70, 0x90, 0xb0, 0xb0, 0xb0, 0x90, 0x70, 0x52, 0xa8, 0x30, 0x50, 0x70, 0x50, 0x70, 0x90, 0xb0, 0xb0, 0xb1, 0x50, 0x70, 0x31, 0x30, 0xc8, 0x50, 0x50, 0x70, 0x70, 0x31, 0xb0, 0x30, 0xb0, 0xb0, 0xe8, 0x30, 0x00 }; //《世上只有妈妈好》 BYTE code song3[]={ 0xd2, 0xb0, 0x71, 0xb1, 0x39, 0xd0, 0xb0, 0xd3, 0x71, 0xb0, 0xd0, 0xb1, 0x71, 0x30, 0xc8, 0xb0, 0x70, 0x53, 0x52, 0x70, 0xb1, 0xb0, 0xd0, 0x71, 0x51, 0x33, 0xb2, 0x70, 0x50, 0x30, 0xc8, 0x30, 0xad, 0x00}; //《当你孤单你会想起谁》 BYTE code song4[]={ 0x71, 0x70, 0x90, 0x71, 0x50, 0x30, 0x51, 0xb1, 0x51, 0x52, 0x31, 0x30, 0x50, 0x31, 0xe8, 0xc8, 0xe9, 0x71, 0xe9, 0xea, 0xc9, 0x50, 0x70, 0x50, 0x30, 0xc9, 0xa9, 0x50, 0x70, 0x50, 0x30, 0xc9, 0xc9, 0x50, 0x70, 0x50, 0x30, 0xc8, 0xe8, 0x35, 0x00 }; //《乡间小路》 BYTE code song5[]={ 0x69, 0x68, 0x68, 0xc0, 0xc0, 0x29, 0xc0, 0xa0, 0xc3, 0xc1, 0xc0, 0xc0, 0xc1, 0xc0, 0x28, 0x49, 0x48, 0x68, 0x4b, 0x68, 0x68, 0x68, 0x48, 0x89, 0x89, 0x69, 0x48, 0x28, 0x4b, 0xe0, 0xe0, 0xe0, 0xc0, 0xa0, 0xa0, 0xc0, 0xe0, 0xe0, 0xc0, 0xa0, 0xc3, 0xc9, 0x68, 0xc8, 0xe8, 0xc8, 0xa8, 0xa9, 0xa8, 0x48, 0xa8, 0xc8, 0xa8, 0x88, 0x89, 0x88, 0x68, 0x49, 0x28, 0x48, 0x68, 0x48, 0x28, 0x48, 0x6b, 0xc9, 0x68, 0xc8, 0xe8, 0xc8, 0xa8, 0xa9, 0x48, 0xa8, 0xc8, 0xa8, 0x88, 0x00}; //《送别》 BYTE code song6[]={ 0xa9, 0x6a, 0xa8, 0x32, 0xc9, 0x31, 0xab, 0xa9, 0x28, 0x48, 0x69, 0x48, 0x28, 0x4b, 0xa9, 0x68, 0xa8, 0x31, 0xe8, 0xc9, 0x31, 0xab, 0xa9, 0x48, 0x68, 0x89, 0xe0, 0x2b, 0xc9, 0x31, 0x33, 0xe9, 0xc8, 0xe8, 0x33, 0xc8, 0xe8, 0x30, 0xc8, 0xc8, 0xa8, 0x68, 0x28, 0x4e, 0xa9, 0x68, 0xa8, 0x31, 0xe8, 0xc9, 0x31, 0xab, 0xa9, 0x48, 0x68, 0x89, 0xe1, 0x2b, 0x00}; //《最浪漫的事》 BYTE code song7[]={ 0xa8, 0xc8, 0x30, 0xc9, 0xc8, 0xa8, 0xc8, 0xa8, 0x68, 0xac, 0xa8, 0xc8, 0x30, 0xc9, 0xc8, 0xa8, 0xc8, 0xa8, 0xc8, 0x2c, 0x28, 0x48, 0x68, 0x48, 0x48, 0x48, 0x28, 0x48, 0x28, 0xc8, 0x69, 0x4a, 0xa8, 0xc8, 0x30, 0xc9, 0xc8, 0xa8, 0xc8, 0xa8, 0xc8, 0x2c, 0x28, 0x48, 0x68, 0x89, 0x88, 0xa8, 0xc8, 0xc8, 0xa8, 0xc9, 0x30, 0xca, 0x30, 0xc8, 0xa8, 0xab, 0x28, 0xc8, 0xac, 0xa8, 0xc8, 0x30, 0x68, 0x48, 0x68, 0x2d, 0x00};
复制代码let tt = [5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1, 3,1,1, 5,1,5, 5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1, 6,1,1, 1,1,5, 1,1,1, 2,1,1, 3,1,1, 2,1,1, 2,1,1, 2,1,1, 1,1,1, 2,1,1, 1,1,1, 6,1,1, 3,1,2, 2,1,3, 5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1, 6,1,1, 1,1,5, 1,1,1, 2,1,1, 3,1,1, 4,1,2, 4,1,1, 5,1,1, 6,1,1, 6,1,1, 5,1,1, 6,1,2, 1,2,1, 6,1,3, 1,2,1, 6,1,1, 5,1,1, 5,1,4, 1,1,1, 6,1,1, 5,1,5, 5,1,1, 6,1,1, 1,2,1, 3,1,1, 2,1,1, 3,1,1, 1,1,6, 0,0,0]; let count = 0; let offset = 0; let str = '' while(tt[offset] != 0) { let tmp = 0; tmp += tt[offset] << 5; tmp += tt[offset + 1] << 3; if(tt[offset + 2] >= 8) tt[offset + 2] = 7; tmp += tt[offset + 2] - 1; //str += '0x' + tt[offset] + tt[offset + 1] + ',' + tt[offset + 2] + ', '; str += '0x' + tmp.toString(16) + ', '; offset += 3; //console.log(' ' + str); if(++count >= 10) { console.log(' ' + str); count = 0; str = ''; } } console.log(' ' + str + '0x00');
复制代码另外,原文的控制部分看的我也是一脸的蒙B。。。原文代码如下:
////////////////////////////////////////////////////////////////////////////////////void music_play(void)//播放相应歌曲的某个音符 { if(((music_num==1)&&(play_enable==1))&&(power_enable==1)) { LCDDispNum(5,2,music_num); fre=song1[num]+7*song1[num+1]-1;//第i个是音符,第i+1个是第几个八度 timer0h=FREQH[fre]; //从数据表中读出频率数值,实际上是定时的时间长度 timer0l=FREQL[fre]; time=song1[num+2]; //读出时间长度数值 num+=3; if(fre<0) //判断歌曲的结束位,结束后转到下一首 { num=0; //下一首从头播放 miao=0; music_num=2; } song(); //发出一个音符 } //////////////////////////////////////////////////////////////////////////////////// if(((music_num==2)&&(play_enable==1))&&(power_enable==1)) { LCDDispNum(5,2,music_num); fre=song2[num]+7*song2[num+1]-1; timer0h=FREQH[fre]; timer0l=FREQL[fre]; time=song2[num+2]; num+=3; if(fre<0) { num=0; miao=0; music_num=3; } song(); } //////////////////////////////////////////////////////////////////////////////////// if(((music_num==3)&&(play_enable==1))&&(power_enable==1)) { LCDDispNum(5,2,music_num); fre=song3[num]+7*song3[num+1]-1; timer0h=FREQH[fre]; timer0l=FREQL[fre]; time=song3[num+2]; num+=3; if(fre<0) { num=0; miao=0; music_num=4; } song(); } //////////////////////////////////////////////////////////////////////////////////// if(((music_num==4)&&(play_enable==1))&&(power_enable==1)) { LCDDispNum(5,2,music_num); fre=song4[num]+7*song4[num+1]-1; timer0h=FREQH[fre]; timer0l=FREQL[fre]; time=song4[num+2]; num+=3; if(fre<0) { num=0; miao=0; music_num=5; } song(); } //////////////////////////////////////////////////////////////////////////////////// if(((music_num==5)&&(play_enable==1))&&(power_enable==1)) { LCDDispNum(5,2,music_num); fre=song5[num]+7*song5[num+1]-1; timer0h=FREQH[fre]; timer0l=FREQL[fre]; time=song5[num+2]; num+=3; if(fre<0) { num=0; miao=0; music_num=1; } song(); } //////////////////////////////////////////////////////////////////////////////////// }
复制代码// 记录每个曲子的地址uint16 code songAddr[] = {song0, song1, song2, song3, song4, song5, song6, song7};
复制代码/*** 初始化音乐 */ void MusicInit() { SPEAK = 1; // 设定为高电位 // 初始化T2 PT2 = 1; // 将中断2设置为最高优先级 //PT2H = 1; T2MOD = 0; // 初始化模式寄存器 T2CON = 0; // 初始化控制寄存器 ET2 = 1; // 开启中断 // 播放第1个音符 //PlayNote(); PlayMusic(5); } /** * 播放音乐 * index 音乐序号 */ void PlayMusic(uint8 index) { TR2 = 0; // 停止定时器2 timers[0].enabled = FALSE; // 停止音符演奏 currMusic = index; // 要播放的音乐序号 musicOffset = 0; // 音乐偏移量为0 PlayNote(); // 开始播放第1个音符 } /** * 上一首 */ void PreviousMusic() { currMusic--; if(currMusic <= 1) currMusic = 7; PlayMusic(currMusic); } /** * 下一首 */ void NextMusic() { currMusic++; if(currMusic >= 8) currMusic = 0; PlayMusic(currMusic); } /** * 播放音符 */ void PlayNote() { BYTE fre; // 音乐频率 BYTE code *musicAddr = (BYTE*)songAddr[currMusic]; BYTE tmp = *(musicAddr + musicOffset); // 判断是否播放完毕 if(tmp == 0) { SPEAK = 1; //CLOSE_GREEN_LED(); // 关闭LED timers[0].enabled = FALSE; return; } fre = ((tmp & 0xF0) >> 5) + ((tmp & 0x18) >> 3) * 7 - 1; TL2 = FrL[fre]; // 设置定时初值 TH2 = FrH[fre]; // 设置定时初值 RCAP2L = FrL[fre]; // 设置定时重载值 RCAP2H = FrH[fre]; // 设置定时重载值 timers[0].count = ((tmp & 7) + 1) * 60; // 300ms做为一拍 if(!timers[0].enabled) { timers[0].enabled = TRUE; timers[0].value = 0; } // 开启定时器 TR2 = 1; //SWAP_GREEN_LED(); // 切换绿灯 } /** * 音乐软中断处理程序 */ void MusicHandle() { TR2 = 0; // 停止定时器2 musicOffset++; PlayNote(); // 播放音符 } // T2硬件中断处理程序 void tm2_isr() interrupt 5 { TF2 = 0; // 清除中断标志(T2定时器不会自动清除中断) SPEAK = !SPEAK; }
复制代码至此音乐部分改造完成,效果如下:
东西虽然简单,但是改造乐谱部分还是让我收获很大。整体程序编译下来,从2000多字节一下子降到893个字节,特别有成就感。
Program Size: data=53.0 xdata=0 const=583 code=839creating hex file from ".\Objects\test"... ".\Objects\test" - 0 Error(s), 0 Warning(s). Build Time Elapsed: 00:00:01
复制代码后面准备增加一个12232,用于显示播放时间,第几首乐曲,时间,温度、湿度、节日提醒功能。
单片机代码等做完后统一发,嗯,先哄儿子玩会,哈哈……