#include <reg52.h> #include <string.h> #include "utilities.h" #include "music.h" #define RldTmr(fr) 65536 - (11059200 / 12) / ((fr) << 1) #define FuDian(n) ((n) << 1) / 3 //附点n分音符的换算 sbit BUZZ = P1^6; uint code noteFreq[] = { //中音 1-7 和高音 1-7对应的频率列表 低音 523, 587, 659, 698, 784, 880, 988, 1047, 1175, 1319, 1397, 1568, 1760, 1976, //261, 293, 329, 349, 392, 440, 494 }; uint code tmrRld[] = { //中音 1-7 和高音 1-7对应的定时器重载值 RldTmr(523), RldTmr(587), RldTmr(659), RldTmr(698), RldTmr(784), RldTmr(880), RldTmr(988), RldTmr(1047), RldTmr(1175), RldTmr(1319), RldTmr(1397), RldTmr(1568), RldTmr(1760), RldTmr(1976), //RldTmr(261), RldTmr(293), RldTmr(329), RldTmr(349), RldTmr(392), RldTmr(440), RldTmr(494) }; uchar musicLen[10]; uchar musicNum = sizeof(musicSet) / sizeof(Music); bit enable = 1, tmrFlg = 0; uchar musicIdx = 0; uchar musicSpeed = 72; uchar nowMusic = 0; void initMusicInfo() { uchar i; for (i = 0; i < musicNum; i++) { musicLen[i] = strlen(musicSet[i].pNote); } } void delay(uint n) { while (n--) { keyDriver(); } } //固定标准为4分音符的速度:例如speed = 108 表示一分钟扫过108个4分音符 void playMusic(uchar musicIdx, uchar speed) { uchar i; uchar idx; uint cnt = 0; uint durationCnt = 0; //当前音符的时值对应的定时器计数 uint soundCnt = 0; //当前音符的发声时值对应的计数值 char * musicNote = musicSet[musicIdx].pNote; char * noteDuration = musicSet[musicIdx].pDur; for (i = 0; i < musicLen[musicIdx]; ) { while (!tmrFlg) ; tmrFlg = 0; //keyDriver(); //递归实现音乐的嵌套 if (cnt == 0) { idx = musicNote[i] - 1; T0RH = tmrRld[idx] >> 8; T0RL = tmrRld[idx]; durationCnt = (ulong)240 * (ulong)noteFreq[idx] / ((ulong)noteDuration[i] * (ulong)speed); soundCnt = durationCnt - (durationCnt >> 2); //当前音符时值的前3/4发声,后1/4静音 enable = 1; cnt++; } else { if (cnt == durationCnt) { cnt = 0; i++; } else { cnt++; if (cnt == soundCnt) { enable = 0; } } } } }