#include<reg52.h> #define uint unsigned int #define uchar unsigned char //硬件端口定义 sbit SPK=P2^0; //定义音乐输出端口 sbit key1=P3^2; //定义按键1 用于 暂停 sbit key2=P3^3; //定义按键2 用于 切换 sbit rs=P2^1; sbit rw=P2^2; sbit ep=P2^3; void delay1(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void write_com(uchar com) { rs=0; rw=0; ep=0; P0=com; delay1(2); ep=1; delay1(2); ep=0; delay1(2); } void write_dat(uchar dat) { rs=1; rw=0; ep=0; P0=dat; delay1(2); ep=1; delay1(2); ep=0; delay1(2); } void write_zfc(uchar *p) { while(*p!=0) write_dat(*p++); } void init_1602() { write_com(0x38); write_com(0x01); write_com(0x06); write_com(0x0c); } unsigned char W=0,T; //用于选择音乐 unsigned char Timer0_H,Timer0_L,Time; void delay5ms(void) //误差 0us { unsigned char a,b; for(b=185;b>0;b--) for(a=12;a>0;a--); } void delay500ms(void) //误差 0us { unsigned char a,b,c; for(c=205;c>0;c--) for(b=116;b>0;b--) for(a=9;a>0;a--); } //世上只有妈妈好 数据表 音谱,高中低音,音长 code unsigned char MUSIC[102]={ 6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 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 }; //送别 数据表 音谱,高中低音,音长 code unsigned char MUSIC1[174]={ 5,2,2, 3,2,1, 5,2,1, 1,3,4, 6,2,2, 1,3,2, 5,2,4, 5,2,2, 1,2,1, 2,2,1, 3,2,2, 2,2,1, 1,2,1, 2,2,8, 5,2,2, 3,2,1, 5,2,1, 1,3,3, 7,2,1, 6,2,2, 1,3,2, 5,2,4, 5,2,2, 2,2,1, 3,2,1, 4,2,3, 7,1,1, 1,2,8, 6,2,2, 1,3,2, 1,3,4, 7,2,2, 6,2,1, 7,2,1, 1,3,4, 6,2,1, 7,2,1, 1,3,1, 6,2,1, 6,2,1, 5,2,1, 3,2,1, 1,2,1, 2,2,8, 5,2,2, 3,2,1, 5,2,1, 1,3,3, 7,2,1, 6,2,2, 1,3,2, 5,2,4, 5,2,2, 2,2,1, 3,2,1, 4,2,3, 7,1,1, 1,2,8 }; //新年好 数据表 音谱,高中低音,音长 code unsigned char MUSIC2[90]={ 1,2,1, 1,2,1, 1,2,2, 5,1,2, 3,2,1, 3,2,1, 3,2,2, 1,2,2, 1,2,1, 3,2,1, 5,2,2, 5,2,2, 4,2,1, 3,2,1, 2,2,4, 2,2,1, 3,2,1, 4,2,2, 4,2,2, 3,2,1, 2,2,1, 3,2,2, 1,2,2, 1,2,1, 3,2,1, 2,2,2, 5,1,2, 7,1,1, 2,2,1, 1,2,4 }; //童年 数据表 音谱,高中低音,音长 code unsigned char MUSIC3[423]={ 5,1,1, 5,1,1, 3,1,1, 5,1,2, 3,1,1, 5,1,2, 6,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 1,2,2, 2,2,1, 2,2,1, 3,2,1, 2,2,2, 5,1,1, 6,1,1, 5,1,1, 1,2,1, 1,2,1, 5,1,1, 1,2,1, 1,2,1, 1,2,2, 1,2,1, 1,2,1, 5,1,2, 1,2,1, 6,1,1, 5,1,1, 3,1,1, 2,1,1, 1,1,2, 3,1,1, 5,1,1, 5,1,2, 5,1,1, 3,1,1, 6,1,1, 6,1,1, 1,2,1, 6,1,1, 6,1,1, 6,1,1, 6,1,1, 5,1,1, 1,2,2, 1,2,1, 1,2,1, 1,2,1, 6,1,1, 1,2,1, 6,1,1, 5,1,2, 0,2,1, 3,1,1, 6,1,1, 1,2,1, 6,1,1, 5,1,1, 3,1,1, 2,1,1, 3,1,1, 5,1,1, 5,1,2, 5,1,1, 3,1,1, 6,1,1, 6,1,1, 1,2,1, 6,1,1, 6,1,1, 6,1,1, 6,1,1, 5,1,1, 1,2,2, 1,2,1, 1,2,1, 1,2,1, 6,1,1, 6,1,1, 1,2,1, 2,2,2, 0,2,1, 5,1,1, 2,2,1, 5,2,1, 2,2,2, 5,2,1, 5,2,2, 5,2,1, 5,2,1, 5,2,1, 3,2,1, 2,2,1, 1,2,1, 1,2,2, 6,1,1, 6,1,1, 1,2,1, 6,1,1, 1,2,1, 2,2,1, 2,2,1, 2,2,1, 2,2,1, 2,2,1, 1,2,1, 3,2,1, 2,2,1, 2,2,8, 3,2,1, 3,2,2, 3,2,1, 3,2,2, 2,2,2, 1,2,1, 1,2,2, 1,2,1, 2,2,1, 1,2,1, 6,1,1, 5,1,1, 5,1,1, 5,1,2, 5,1,1, 6,1,1, 5,1,1, 2,2,1, 3,2,1, 1,2,8, 1,2,1, 5,1,2, 1,2,1, 6,1,1, 5,1,1, 3,1,1, 2,1,1, 1,2,6, 0,2,2 }; // 音阶频率表 高八位 code unsigned char FREQH[]={ 0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8, 0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i 0xFC,0xFD,0xFD,0xFD,0xFD,0xFE, 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF, } ; // 音阶频率表 低八位 code unsigned char FREQL[]={ 0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6, 0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i 0xEE,0x44, 0x6B,0xB4,0xF4,0x2D, 0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16, }; /*uS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255,大致延时长度 T=tx2+5 uS */ void DelayUs2x(unsigned char t) { while(--t); } /* mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255*/ void DelayMs(unsigned char t) { while(t--) { //大致延时1mS DelayUs2x(245); DelayUs2x(245); } } /*节拍延时函数 各调1/4节拍时间: 调4/4 125ms 调2/4 250ms 调3/4 187ms*/ void delay(uchar t) { uchar i; for(i=0;i<t;i++) DelayMs(250); TR0=0; } /*定时器0中断*/ void TIM0_ISR() interrupt 1 { TR0=0; SPK=!SPK; TH0=Timer0_H; TL0=Timer0_L; TR0=1; } /*歌曲处理函数*/ void Song() { TH0=Timer0_H;//赋值定时器时间,决定频率 TL0=Timer0_L; TR0=1; //打开定时器 delay(Time); //延时所需要的节拍 } /*主函数*/ void led(unsigned char a); void main(void) { unsigned int i; unsigned char k; TMOD|=0x01; //置定时器0工作方式1 EA=1; //打开全局中断 ET0=1; //打开 定时器0 中断 EX0=1; //打开 外部中断0 中断 IT0=1; //设置为下降沿中断 EX1=1; //打开 外部中断1 中断 IT1=1; //设置为下降沿中断 PX1=1; //设置 外部中断1 为高优先级 init_1602(); while(1) { //i=0; if(W==0) { T=W; write_com(0x81); write_zfc("Only mother is good"); write_com(0xc4); write_zfc("in the world"); for(i=0;i<100;i=i+3) { //音乐数组长度 ,唱完从头再来 led(MUSIC[i]); k=MUSIC[i]+7*MUSIC[i+1]-1;//去音符振荡频率所需数据 Timer0_H=FREQH[k]; Timer0_L=FREQL[k]; Time=MUSIC[i+2]; //节拍时长 // i=i+3; Song(); if(T!=W) break; } } if(W==1) { T=W; write_com(0x01); write_com(0x80); write_zfc(" Farewell "); for(i=0;i<174;i=i+3) { //音乐数组长度 ,唱完从头再来 led(MUSIC1[i]); k=MUSIC1[i]+7*MUSIC1[i+1]-1;//去音符振荡频率所需数据 Timer0_H=FREQH[k]; Timer0_L=FREQL[k]; Time=MUSIC1[i+2]; //节拍时长 // i=i+3; Song(); if(T!=W) break; } } if(W==2) { T=W; write_com(0x80); write_zfc(" Happy New Year "); for(i=0;i<90;i=i+3) { //音乐数组长度 ,唱完从头再来 led(MUSIC2[i]); k=MUSIC2[i]+7*MUSIC2[i+1]-1;//去音符振荡频率所需数据 Timer0_H=FREQH[k]; Timer0_L=FREQL[k]; Time=MUSIC2[i+2]; //节拍时长 // i=i+3; Song(); if(T!=W) break; } } if(W==3) { T=W; write_com(0x80); write_zfc(" The Childhood"); for(i=0;i<423;i=i+3) { //音乐数组长度 ,唱完从头再来 led(MUSIC3[i]); k=MUSIC3[i]+7*MUSIC3[i+1]-1;//去音符振荡频率所需数据 Timer0_H=FREQH[k]; Timer0_L=FREQL[k]; Time=MUSIC3[i+2]; //节拍时长 // i=i+3; Song(); if(T!=W) break; } } } } /* 频谱函数*/ void led(unsigned char a) { switch(a) { case 0:P1=0xff;break; case 1:P1=0x7f;break; //D1-D7亮 case 2:P1=0x7e;break; //D2-D7亮 case 3:P1=0x7c;break; //D3-D7亮 case 4:P1=0x78;break; //D4-D7亮 case 5:P1=0x70;break; //D5-D7亮 case 6:P1=0x60;break; //D6-D7亮 case 7:P1=0x40;break; //D7亮 case 8:P1=0x00;break; //全灭 } } /*外部中断0 中断服务程序 用于暂停*/ void zhongduan0() interrupt 0 { delay5ms(); //按键去抖 if(!key1) { while(!key1); //松手检测 while(key1&&T==W); //检测按键是否按下 delay5ms(); //按键去抖 while(key1&&T==W); //检测按键是否按下 while(!key1&&T==W); //松手检测 } } /*外部中断1 中断服务程序*/ void zhongduan1() interrupt 2 { delay5ms(); //按键去抖 if(!key2) { if(W==3) W=0; else W++; while(!key2); //松手检测 delay500ms(); } } |