蜂鸣器播放音乐+普中51单片机+江科大自化协
1 现象
利用蜂鸣器实现音乐播放功能,播放《天空之城》。
2 原理
(1)天空之城的乐谱
3 参考程序
3.1 主程序
#include <REGX52.H> #include "delayms.h" #include "timer0.h" //蜂鸣器端口定义 sbit buzzer = P2^5; //播放速度,值为四分音符的时长 #define SPEED 500 //音符与索引对应表,P:休止符,L:低音,M:中音,H:高音,下划线:升半音符号# #define P 0 #define L1 1 #define L1_ 2 #define L2 3 #define L2_ 4 #define L3 5 #define L4 6 #define L4_ 7 #define L5 8 #define L5_ 9 #define L6 10 #define L6_ 11 #define L7 12 #define M1 13 #define M1_ 14 #define M2 15 #define M2_ 16 #define M3 17 #define M4 18 #define M4_ 19 #define M5 20 #define M5_ 21 #define M6 22 #define M6_ 23 #define M7 24 #define H1 25 #define H1_ 26 #define H2 27 #define H2_ 28 #define H3 29 #define H4 30 #define H4_ 31 #define H5 32 #define H5_ 33 #define H6 34 #define H6_ 35 #define H7 36 //索引与频率对照表 unsigned int FreqTable[]={ 0, 63472,63584,63697,63797,63897,63987,64074,64156,64233,64307,64376,64441, 64502,64560,64615,64667,64715,64761,64805,64846,64885,64921,64956,64989, 65020,65048,65076,65102,65126,65149,65171,65191,65210,65229,65246,65262 }; //乐谱,天空之城,频率,音长 unsigned char code Music[]={ //第1行 P, 4, P, 4, P, 4, M6, 2, M7, 2, H1, 4+2,M7, 2, H1, 4, H3, 4, M7, 4+4+4, M3, 2, M3, 2, //第2行 M6, 4+2,M5, 2, M6, 4, H1, 4, M5, 4+4+4, M3, 4, M4, 4+2,M3, 2, M4, 4, H1, 4, //第3行 M3, 4+2,P, 2, H1, 2, H1, 2, H1, 2, M7, 4+2,M4_,2, M4_,4, M7, 4, M7, 4+4,P, 4, M6, 2, M7, 2, //第4行 H1, 4+2,M7, 2, H1, 4, H3, 4, M7, 4+4+4, M3, 2, M3, 2, M6, 4+2, M5, 2, M6, 4, H1, 4, //第5行 M5, 4+4+4, M2, 2, M3, 2, M4, 4, H1, 2, M7, 2+2, H1, 2+4, H2, 2, H2, 2, H3, 2, H1, 2+4+4, //第6行 H1, 2, M7, 2, M6, 2, M6, 2, M7, 4, M5_,4, M6, 4+4+4, H1, 2, H2, 2, H3, 4+2,H2, 2, H3, 4, H5, 4, //第7行 H2, 4+4+4, M5, 2, M5, 2, H1, 4+2, M7, 2, H1, 4, H3, 4, H3, 4+4+4+4, //第8行 M6, 2, M7, 2, H1, 4, M7, 4, H2, 2, H2, 2, H1, 4+2,M5, 2+4+4, H4, 4, H3, 4, H2, 4, H1, 4, //第9行 H3, 4+4+4, H3, 4, H6, 4+4, H5, 4, H5, 4, H3, 2, H2, 2, H1, 4+4, P, 2, H1, 2, //第10行 H2, 4, H1, 2, H2, 2, H2, 4, H5, 4, H3, 4+4+4, H3, 4, H6, 4+4, H5, 4+4, //第11行 H3, 2, H2, 2, H1, 4+4, P, 2, H1, 2, H2, 4, H1, 2, H2, 2+4, M7, 4, M6, 4+4+4, M6, 2, M7, 2, 0xFF //终止符号 }; unsigned char FreqSelect,MusicSelect; void main() { timer0_init(); while(1) { if(Music[MusicSelect]!=0xFF) //如果不是停止标志位 { FreqSelect = Music[MusicSelect]; //选择音符对应的频率 MusicSelect++; delayms(SPEED/4*Music[MusicSelect]); //选择音符对应的时值 MusicSelect++; TR0 = 0; delayms(5); //音符间短暂停顿 TR0 = 1; } else //如果是停止标志位,停止播放 { TR0 = 0; while(1); } } } void timer0_routine() interrupt 1 { if(FreqTable[FreqSelect]) //如果不是休止符 { /*取对应频率值的重装载值到定时器*/ TL0 = FreqTable[FreqSelect]%256; //设置定时初值 TH0 = FreqTable[FreqSelect]/256; //设置定时初值 buzzer=!buzzer; //翻转蜂鸣器IO口 } }
3.2 延时函数
#ifndef _delayms_h_ #define _delayms_h_ delayms(unsigned int xms); #endif
#include <intrins.h> void delayms(unsigned int xms) //@11.0592MHz { unsigned char i, j; while(xms--) { _nop_(); i = 2; j = 199; do { while (--j); } while (--i); } }
3.3 定时器函数
#ifndef _timer0_h_ #define _timer0_h_ void timer0_init(void); #endif
#include <REGX52.H> /** * @brief 定时器0初始化,1毫秒@11.0592MHz * @param 无 * @retval 无 */ void timer0_init(void) //1毫秒@11.0592MHz { TMOD &= 0xF0; //设置定时器模式,1111_0000,&,高四位保留,低四位清零 TMOD |= 0x01; //设置定时器模式,0000_0001,|,高四位保留,设置模式为T0 TL0 = 0x66; //设置定时初始值,1ms,@11.0592MHz TH0 = 0xFC; //设置定时初始值,1ms,@11.0592MHz TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0=1; //打开定时器T0中断开关 EA=1; //打开中断系统总开关 PT0=0; //设置T0中断优先级,低 }