#include #define uchar unsigned char #define uint unsigned int void delay1(uint z); //定义特殊功能寄存器的位变量 sbit key1=P3^2; //按key1可自动//外部中断 sbit key2=P3^3; //按key2可自动//外部中断 sbit fm=P3^7; //蜂鸣器连续的IO口 sbit key3=P3^0; //减数 sbit key4=P3^1; //加速 //uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, //0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};//共阴极数码管显示码制0~F uchar code table[]={ 0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e}; //速度模式共有5种 unsigned char code SpeedCode[]={250,150,100,50,10}; uchar count2=1,RunMode=1;//音乐、流水灯标志 uchar zd=1; //自动播放标志 uchar timeh,timel,i; uint LEDIndex = 0;//LED位置 bit LEDDirection = 1,LEDFlag = 1;//LED方向,LED亮灭 uint Timer0Count,SystemSpeed;//跑马灯速度, 系统速度 char SystemSpeedIndex=0;//速度模式参数 //---------------------------简谱--------------------------------------- //编程规则:字节高位是简谱,低位是持续时间 //代表多少个十六分音符 //1-7代表中央C调,8-E代表高八度,0代表停顿 //最后的0是结束标志 uchar code qnzl[]={ //千年之恋 0x12,0x22,0x34,0x84,0x74,0x54,0x38,0x42,0x32,0x22,0x42,0x34,0x84,0x72,0x82,0x94,0xA8,0x08, 0x32,0x31,0x21,0x32,0x52,0x32,0x31,0x21,0x32,0x62, 0x32,0x31,0x21,0x32,0x82,0x71,0x81,0x71,0x51,0x32,0x22, 0x32,0x31,0x21,0x32,0x52,0x32,0x31,0x21,0x32,0x62, 0x32,0x31,0x21,0x32,0x82,0x83,0x71,0x72,0x02, 0x63,0xA1,0xA2,0x62,0x92,0x82,0x52, 0x31,0x51,0x63,0x51,0x63,0x51,0x63,0x51,0x62,0x82,0x7C,0x02, 0x61,0x71,0x82,0x71,0x62,0xA2,0x71,0x76, 0x61,0x71,0x82,0x71,0x62,0x52,0x31,0x36, 0x61,0x71,0x82,0x71,0x62,0xA3,0x73,0x62,0x53, 0x42,0x61,0x62,0x83,0x83,0x91,0x91, 0x61,0x71,0x82,0x71,0x62,0x0A2,0x71,0x76, 0x61,0x71,0x82,0x71,0x62,0x52,0x31,0x36, 0x61,0x71,0x82,0x71,0x62,0xA3,0x73,0x62,0x53, 0x42,0x82,0x88,0x02,0x74,0x94,0x89,0xff//结束标志 }; uchar code jmszl[]={ //寂寞沙洲冷 0x12,0x12,0x22,0x32,0x31,0x22,0x21,0x22, 0x21,0x31,0x51,0x52,0x31,0x52,0x61,0x15,0x14, 0x51,0x52,0x31,0x52,0x62,0x13,0x11,0x13,0x32,0x28,0x08,0x28, 0x31,0x32,0x31,0x32,0x11,0x21,0x51,0x52,0x51,0x52, 0x51,0x51,0x31,0x32,0x31,0x32,0x81,0x72,0x63, 0x62,0x71,0x81,0x72,0x61,0x61,0x52,0x31,0x21,0x32,0x51,0x54, 0x22,0x12,0x11,0x12,0x11,0x12,0x12,0x14,0x26,0x32,0x26, 0x32,0x61,0x51,0x51,0x31,0x31,0x21,0x31,0x51,0x61,0x51,0x31,0x51, 0x02,0x32,0x81,0x81,0x81,0x81,0x62,0x52,0x34, 0x31,0x81,0x81,0x81,0x61,0x91,0x82, 0x51,0x51,0x51,0x51,0x31,0x61,0x53, 0x21,0x11,0x21,0x11,0x22,0x11,0x21,0x26, 0x32,0x61,0x51,0x51,0x31,0x31,0x21,0x31,0x51,0x61,0x51,0x31,0x51,0x52, 0x31,0x31,0x81,0x81,0x81,0x61,0x91,0x81,0x61,0x31,0x56, 0x32,0x32,0x81,0x81,0x81,0x81,0x91,0x81,0x61,0x81,0x61,0x51,0x31,0x51,0x34, 0x21,0x31,0x51,0x31,0x21,0x11,0x61,0x21,0x16, 0xff}; uchar code srkl[]={0x52,0x52,0x64,0x54,0x84,0x74,//生日快乐 0x52,0x52,0x64,0x54,0x94,0x84, 0x52,0x52,0xc4,0xA4,0x84,0x74,0x64, 0xB2,0xB2,0xA4,0x84,0x94,0x84, 0x52,0x52,0x64,0x54,0x84,0x74, 0x52,0x52,0x64,0x54,0x94,0x84, 0x52,0x52,0xc4,0xA4,0x84,0x74,0x64, 0xB2,0xB2,0xA4,0x84,0x94,0x84,0xff}; uchar code goon[]={0x64,0x84,0x92,0x91,0x81,0x93,0x61, //康定情歌 0x54,0x62,0x82,0x92,0x91,0x81,0x92, 0x64,0x62,0x82,0x92,0x91,0x81,0x93, 0x61,0x54,0x82,0x62,0x51,0x61,0x51, 0x41,0x52,0x24,0x92,0x54,0x82,0x64, 0x52,0x42,0x94,0x82,0x62,0x51,0x61, 0x51,0x41,0x52,0x24,0xff}; //----------------------------简谱音调对应的定时器初值--------------------------- //适合11.0592M的晶振 uchar code chuzhi[]={ 0xff,0xff,//占位 0xFC,0x8E,//中央C调1-7 0xFC,0xED, 0xFD,0x43, 0xFD,0x6A, 0xFD,0xB3, 0xFD,0xF3, 0xFE,0x2D, 0xFE,0x47, //高八度1-7 0xFE,0x76, 0xFE,0xA1, 0xFE,0xC7, 0xFE,0xD9, 0xFE,0xF9, 0xFF,0x16 }; void LEDShow(unsigned int LEDStatus1, unsigned int LEDStatus2) { P2 = ~(LEDStatus1&0x00FF); //P2输出 P1 = ~(LEDStatus2&0x00FF); //P1输出 } //速度选择函数 void SetSpeed(unsigned char Speed) { SystemSpeed =SpeedCode[Speed];//速度模式 } void delay(uint z) //延时165MS,即十六分音符 { uint x,y; for(x=z;x>0;x--) for(y=19000;y>0;y--); } void delay1(uint z) //延时1MS { uint x,y; for(x=z;x>0;x--) for(y=112;y>0;y--); } //mode 1(一个灯右移) void Mode_1(void) { LEDShow(0x0800>>LEDIndex,0x0800>>LEDIndex); LEDIndex = (LEDIndex+1)%8; } //Mode 2 void Mode_2(void) { if(LEDDirection) //选择LED方向 LEDShow(~(0x0001<>LEDIndex),~(0x0800>>LEDIndex));//LED一个灭的灯右移 if(LEDIndex==11) LEDDirection = !LEDDirection;//改变方向 LEDIndex = (LEDIndex+1)%16;//循环 } //Mode 3 void Mode_3(void) { if(LEDDirection) { if(LEDFlag) //LED 灭 LEDShow(0x0FFE<>LEDIndex),~(0x07FF>>LEDIndex));//一个亮的灯右移 } else { if(LEDFlag) LEDShow(0x07FF>>LEDIndex,0x07FF>>LEDIndex); //一个灭的灯右移 else LEDShow(~(0x0FFE<>LEDIndex,0x0F00>>LEDIndex); //四个左灯右移 if(LEDIndex==11) LEDDirection = !LEDDirection; LEDIndex = (LEDIndex+1)%16; } //Mode 5 void Mode_5(void) { if(LEDDirection) LEDShow(~(0x000F<>LEDIndex),~(0x0F00>>LEDIndex));//四个灯右移 if(LEDIndex==11) LEDDirection = !LEDDirection; LEDIndex = (LEDIndex+1)%16; } //Mode 6 void Mode_6(void) { if(LEDDirection) //选择LED方向 LEDShow(~(0x0003<>LEDIndex),~(0x0C00>>LEDIndex));//LED两个灭的灯右移 if(LEDIndex==11) LEDDirection = !LEDDirection;//改变方向 LEDIndex = (LEDIndex+2)%16;//循环 } //Mode 7(一个灯隔右移) void Mode_7(void) { LEDShow(0x0800>>LEDIndex,0x0800>>LEDIndex); LEDIndex = (LEDIndex+2)%16; } //Mode 8 void Mode_8(void) { if(LEDDirection) //选择LED方向 LEDShow(~(0x0007<>LEDIndex),~(0x0E00>>LEDIndex));//LED三个灭的灯右移 if(LEDIndex==11) LEDDirection = !LEDDirection;//改变方向 LEDIndex = (LEDIndex+1)%16;//循环 } //Mode 9 void Mode_9(void) { if(LEDDirection) //选择LED方向 LEDShow(~(0x0007<>LEDIndex),~(0x0E00>>LEDIndex));//LED三个灭的灯右移 if(LEDIndex==11) LEDDirection = !LEDDirection;//改变方向 LEDIndex = (LEDIndex+2)%16;//循环 } //Mode 10(一个灯隔两位右移) void Mode_10(void) { LEDShow(0x0800>>LEDIndex,0x0800>>LEDIndex); LEDIndex = (LEDIndex+3)%16; } void Timer0EventRun(void) { switch(RunMode) { case 0:Mode_1();break; case 1:Mode_2();break; case 2:Mode_3();break; case 3:Mode_4();break; case 4:Mode_5();break; case 5:Mode_6();break; case 6:Mode_7();break; case 7:Mode_8();break; case 8:Mode_9();break; case 9:Mode_10();break; default:break; } } void song() { uint temp; uchar jp;//jp是简谱 i=0; while(1) { if(key3==0) //减速键按下时key3=0 { if(key3==0) //两次查询防止抖动 { SystemSpeedIndex++; //速度模式参数加1 if(SystemSpeedIndex>4) SystemSpeedIndex=0; //只有5种速度 SetSpeed(SystemSpeedIndex); } } if(key4==0) { if(key4==0) { SystemSpeedIndex--; if(SystemSpeedIndex<0) SystemSpeedIndex=4; SetSpeed(SystemSpeedIndex); } } P0=table[RunMode]; //共阴极数码管显示码制 if(count2==0) { break; } if(count2==1) //千年之恋 temp=qnzl[i]; if(count2==2) //寂寞沙洲冷 temp=jmszl[i]; if(count2==3) //生日快乐 temp=srkl[i]; if(count2==4) //康定情歌 temp=goon[i]; if(temp==0xff) //结束 break; jp=temp/16; //取数的高4位 if(jp!=0) { timeh = chuzhi[jp*2]; timel = chuzhi[jp*2+1]; TR0=1;//开定时器T0 } else { TR0=0;//定时器T0的开定时器位,TR0=0表示关定时器 fm=0;//关蜂鸣器 } delay(temp%16); //取数的低4位 TR0=0; //唱完一个音停15MS,关定时器T0 fm=0; i++; } TR0=0;//定时器T0的开定时器位,TR0=0表示关定时器 fm=0; } main() { EX1=1;//开外部中断1 IT1=1;//外部中断1下降沿触发方式 EX0=1;//开外部中断0 IT0=1;//外部中断0下降沿触发方式 TMOD=0x11;//定时器0,1工作在方式1 TH0=0;TL0=0; TH1=0xFC;//定时器1 的高8里写入十六进制值 0xFC TL1=0xFB; ET0=1;//定时器0的中断允许开关 ET1=1; TR0=0;//定时器T0的开关定时器位,TR=0 表示关定时器 P0=table[1];//共阴(阳)极数码管显示码制0~F SetSpeed(0); EA=1;//开总中断 TR1=1;//开启定时器T1 while(1) { song(); delay1(50); if(zd)//自动播放标志 { count2++; if(count2>4) //共有四首音乐 count2=1; RunMode++; if(RunMode>9) RunMode=0; } } } void int1() interrupt 2 //手动播放歌曲和跑马灯,外部中断1 { //EA=0;//关总中断 if(key2==0) { if(key2==0) { zd = 0; TR0=1; //定时器T0的开定时器,TR0=1表示开定时器 i=0;//从头开始唱 delay1(50); count2++; if(count2>4)//音乐标志 count2=1; RunMode++; if(RunMode>9)//流水灯标志 RunMode=0; } } EA=1;//开总中断 } void int0() interrupt 0 //自动切换,外部中断0 { EA=0;//关总中断 delay1(1);//去抖 if(key1==0) { delay1(1); if(key1==0) { zd = 1; } } EA=1;//开总中断 } void timer0() interrupt 1 //用于产生各种音调,定时器0 { EA=0;//关总中断 TR0=0; //定时器T0的开定时器位,TR0=0表示关定时器 TH0=timeh;//定时器0的高8位里写入timeh TL0=timel; fm=~fm;//产生波形 TR0=1;//定时器T0的开定时器位,TR0=1表示开定时器 EA=1;//开总中断 } void Timer1() interrupt 3 //控制跑马灯速度,定时器1 { EA=0;//关总中断 TR1=0;//关闭定时器T1 TH1=0xFC;//定时器1的高8位里写入十六进制值 0xFC TL1=0xFB; Timer0Count++; if(Timer0Count>=SystemSpeed) { Timer0Count = 0; Timer0EventRun(); //跑马灯模式 } TR1=1;//启动定时器T1 EA=1;//开总中断 }