- #include<reg52.h>
- #include<intrins.h>
- #define NOTE_D0 0//220
- #define NOTE_D1 5//294
- #define NOTE_D2 7//330
- #define NOTE_D3 8//350
- #define NOTE_D4 10//393
- #define NOTE_D5 12//441
- #define NOTE_D6 14//495
- #define NOTE_D7 16//556
- #define NOTE_DL1 147
- #define NOTE_DL2 165
- #define NOTE_DL3 175
- #define NOTE_DL4 196
- #define NOTE_DL5 0//221
- #define NOTE_DL6 2//248
- #define NOTE_DL7 4//278
- #define NOTE_DH1 17//589
- #define NOTE_DH2 19//661
- #define NOTE_DH3 20//700
- #define NOTE_DH4 22//786
- #define NOTE_DH5 24//882
- #define NOTE_DH6 26//990
- #define NOTE_DH7 112
- sbit buzzer=P3^4;
- sbit k1=P3^3;//sbit Echo= P3^3;
- sbit k2=P3^2;//sbit Trig= P3^2;
- sbit DS = P3^1; //p3.4串行数据输入 DS
- sbit SH_CP = P3^0; //串行输入时钟,上升沿有效
- sbit ST_CP = P3^5; //串行寄存器时钟,上升沿有效
- typedef unsigned char uchar;
- typedef unsigned int uint;
- sfr P3M1 = 0xb1;
- sfr P3M0 = 0xb2;
- sfr T2H = 0xD6;
- sfr T2L = 0xD7;
- sfr IE2 = 0xAF;
- sfr AUXR = 0x8E;
- /**********函数声明********************/
- void SendTo595(uchar byteData);
- void xianshi(uint shu);
- void xian();
- void key1pros();
- void key2pros();
- void tiaoshi();
- void Timer2Init() ;
- /***********************************/
- char code DISP[] = {0xf5, 0x05, 0xb3, 0x97, 0x47, 0xd6, 0xf6, 0x85, 0xf7,0xd7};
- char code DIWP[] = {0xfd, 0x0d, 0xbb, 0x9f, 0x4f, 0xde, 0xfe, 0x8d, 0xff,0xdf};
- char code QQ[]={0x70,0xb0,0xd0,0xe0};
- int t50ms=0,t1s=60,tmin=60,th=9;
- uint po=0,aa=4,tt=0;
- uint c=0,v=0,b=0,n=0,x=1;
- uint length;//这里定义一个变量,后面用来表示共有多少个音符//uint time=0;//uint q;
- uchar th0_f; //在中断中装载的 T0 的值高 8 位
- uchar tl0_f ;//在中断中装载的 T0 的值低 8 位
- //T0 的值,及输出频率对照表
- uchar code freq[36*2]={
- 0xA9,0xEF,//00220HZ ,1 //0
- 0x93,0xF0,//00233HZ ,1#//1
- 0x73,0xF1,//00247HZ ,2//2
- 0x49,0xF2,//00262HZ ,2#//3
- 0x07,0xF3,//00277HZ ,3//4
- 0xC8,0xF3,//00294HZ ,4//5
- 0x73,0xF4,//00311HZ ,4#//6
- 0x1E,0xF5,//00330HZ ,5//7
- 0xB6,0xF5,//00349HZ ,5#//8
- 0x4C,0xF6,//00370HZ ,6//9
- 0xD7,0xF6,//00392HZ ,6#//10
- 0x5A,0xF7,//00415HZ ,7//11
- 0xD8,0xF7,//00440HZ 1 //12
- 0x4D,0xF8,//00466HZ 1# //13
- 0xBD,0xF8,//00494HZ 2 //14
- 0x24,0xF9,//00523HZ 2# //15
- 0x87,0xF9,//00554HZ 3 //16
- 0xE4,0xF9,//00587HZ 4 //17
- 0x3D,0xFA,//00622HZ 4# //18
- 0x90,0xFA,//00659HZ 5 //19
- 0xDE,0xFA,//00698HZ 5# //20
- 0x29,0xFB,//00740HZ 6 //21
- 0x6F,0xFB,//00784HZ 6# //22
- 0xB1,0xFB,//00831HZ 7 //23
- 0xEF,0xFB,//00880HZ `1
- 0x2A,0xFC,//00932HZ `1#
- 0x62,0xFC,//00988HZ `2
- 0x95,0xFC,//01046HZ `2#
- 0xC7,0xFC,//01109HZ `3
- 0xF6,0xFC,//01175HZ `4
- 0x22,0xFD,//01244HZ `4#
- 0x4B,0xFD,//01318HZ `5
- 0x73,0xFD,//01397HZ `5#
- 0x98,0xFD,//01480HZ `6
- 0xBB,0xFD,//01568HZ `6#
- 0xDC,0xFD,//01661HZ `7 //35
- };
- uint code tune[] =
- {
- NOTE_D0,NOTE_D6,NOTE_D7,NOTE_DH1,NOTE_D7,NOTE_DH1,NOTE_DH3,NOTE_D7,NOTE_D7,NOTE_D7,NOTE_D3,NOTE_D3, NOTE_D6,NOTE_D5,NOTE_D6,NOTE_DH1,NOTE_D5,NOTE_D5,NOTE_D5,NOTE_D3,NOTE_D4,NOTE_D3,NOTE_D4,NOTE_DH1, NOTE_D3,NOTE_D3,NOTE_D0,NOTE_DH1,NOTE_DH1,NOTE_DH1,NOTE_D7,NOTE_D4,NOTE_D4,NOTE_D7,NOTE_D7,NOTE_D7,NOTE_D0,NOTE_D6,NOTE_D7, NOTE_DH1,NOTE_D7,NOTE_DH1,NOTE_DH3,NOTE_D7,NOTE_D7,NOTE_D7,NOTE_D3,NOTE_D3,NOTE_D6,NOTE_D5,NOTE_D6,NOTE_DH1,NOTE_D5,NOTE_D5,NOTE_D5,NOTE_D2,NOTE_D3,NOTE_D4,NOTE_DH1,NOTE_D7,NOTE_D7,NOTE_DH1,NOTE_DH1,NOTE_DH2,NOTE_DH2,NOTE_DH3,NOTE_DH1,NOTE_DH1,NOTE_DH1,NOTE_DH1,NOTE_D7,NOTE_D6,NOTE_D6,NOTE_D7,NOTE_D5,NOTE_D6,NOTE_D6,NOTE_D6,NOTE_DH1,NOTE_DH2,NOTE_DH3,NOTE_DH2,NOTE_DH3,NOTE_DH5,NOTE_DH2,NOTE_DH2,NOTE_DH2,NOTE_D5,NOTE_D5,NOTE_DH1,NOTE_D7,NOTE_DH1,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_D6,NOTE_D7,NOTE_DH1,NOTE_D7,NOTE_DH2,NOTE_DH2,NOTE_DH1,NOTE_D5,NOTE_D5,NOTE_D5,NOTE_DH4,NOTE_DH3,NOTE_DH2,NOTE_DH1,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH6,NOTE_DH6,NOTE_DH5,NOTE_DH5,NOTE_DH3,NOTE_DH2,NOTE_DH1,NOTE_DH1,NOTE_D0,NOTE_DH1,NOTE_DH2,NOTE_DH1,NOTE_DH2,NOTE_DH2,NOTE_DH5,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH3,NOTE_DH6,NOTE_DH6,NOTE_DH5,NOTE_DH5, NOTE_DH3,NOTE_DH2,NOTE_DH1,NOTE_DH1,NOTE_D0,NOTE_DH1,NOTE_DH2,NOTE_DH1,NOTE_DH2,NOTE_DH2,NOTE_D7,NOTE_D6,NOTE_D6,NOTE_D6,NOTE_D6,NOTE_D7
- };//这部分就是整首曲子的音符部分,用了一个序列定义为tune,整数
- float code duration[]=
- {
- 1,0.5,0.5, 1+0.5,0.5,1,1, 1,1,1,0.5,0.5,
- 1+0.5,0.5,1,1, 1,1,1,1, 1+0.5,0.5,1,1,
- 1,1,0.5,0.5,0.5,0.5, 1+0.5,0.5,1,1, 1,1,1,0.5,0.5,
- 1+0.5,0.5,1,1, 1,1,1,0.5,0.5, 1+0.5,0.5,1,1,
- 1,1,1,0.5,0.5, 1,0.5,0.25,0.25,0.25,0.5, 0.5,0.5,0.5,0.25,0.5,1,
- 0.5,0.5,0.5,0.5,1,1, 1,1,1,0.5,0.5, 1+0.5,0.5,1,1,
- 1,1,1,0.5,0.5, 1.5,0.5,1,1, 1,1,1,1,
- 0.5,0.5,1,1,0.5,0.5, 1.5,0.25,0.5,1, 1,1,1,1,
- 1,1,1,1, 1,1,1,1, 0.5,0.5,1,1,0.5,0.5,
- 1,0.5,0.5,1,1, 1,1,1,1, 1,1,1,1,
- 0.5,0.5,1,1,0.5,0.5, 1,0.5,0.25,0.5,1, 1,1,1,0.5,0.5
- };//这部分是整首曲子的节拍部分,也定义个序列duration,浮点(数组的个数和前面音符的个数是一样的,一一对应么)
- void delay(uint z)//延时1ms
- {
- uint x,y;
- for(x=z;x>0;x--)
- {
- for(y=0;y<114;y++)
- {
- }
- }
- }
- void fasheng() //发声子程序
- {
- unsigned int a,x;
- for (a=0;a<900;a++)
- {
- buzzer=!buzzer;
- for (x=0;x<100;x++); //45为蜂鸣器发声频率
- }
- }
- void timer0 (void) interrupt 1
- {
-
- TH0=0x3C;
- TL0=0xB0;
- t50ms++;
- if(t50ms==20)//1s
- {
- t50ms=0;
- t1s--;
- //while(1){fasheng();delay(1000);}
- if(t1s==-1)//1min
- {
- t1s=59;
- tmin--;
- //fasheng();
- if(tmin==-1)//1h
- {
- fasheng();
- x=0;
- TR0=0;
-
- tmin=59;
- th--;
- }
- }
- }
- }
- //定时中断 2,用于产生唱歌频率
- void Timer2_inter() interrupt 12
- {
- T2L=tl0_f;
- T2H=th0_f; //调入预定时值
- buzzer=~buzzer; //取反音乐输出 IO
- }
- void Timer2Init() //50毫秒@11.0592MHz
- {
- AUXR &= ~(1<<4); // Timer2 停止运行
- AUXR &= 0xFB; //定时器时钟12T模式
- T2H = 0x00; // 数据位
- T2L = 0x4C; // 数据位
- IE2 |= 0x04; //允许定时器2产生中断
- //AUXR |= 0x10; //定时器2开始计时
- }
- void Time_Init()
- {
- TMOD=0x01; //设T0为方式1,GATE=1;
- TH0=0x3C;
- TL0=0xB0;
- ET0=1;
- EA=1;
-
- }
- void SendTo595(uchar Data)
- {
- uint i;
-
- for(i=0;i<8;i++)
- {
- SH_CP = 0;
-
- DS=0x80&Data;//&为按位运算符,即全1为1,有0为0,上式也就是 (1000 0000)&(1111 1111)=1000 0000,若高位为1则是1高位为0则这个式子为0
-
- Data=_crol_(Data,1); //左移一位 将高位补给低位,如果二进制数为01010101 那么_crol_(1) 为10101010
-
- SH_CP = 1; //上升沿让串行输入时钟变成高电平 并延时一个时钟周期
- _nop_();
-
- }
-
- }
- void xian()
- {
- uint qian;
- uint bai;
- uint shi;
- uint ge;
- uint j;
- qian=tmin/10;
- bai=tmin%10;
- shi=t1s/10;
- ge=t1s%10;
- for(j=0;j<20;j++)
- {
- SendTo595(QQ[0]);
- SendTo595(DISP[ge]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- delay(1);
- SendTo595(QQ[1]);
- SendTo595(DISP[shi]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- delay(1);
- SendTo595(QQ[2]);
- SendTo595(DIWP[bai]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- delay(1);
- SendTo595(QQ[3]);
- SendTo595(DISP[qian]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- delay(1);
- }
- }
- void key1pros()//定义独立按键控制
- {
- po=1000;
- if(k1==1)//说明按下去了
- {
- while(po--);//消抖
- if(k1==1)
- {
- fasheng() ;
- tt=tt+1;
- if(tt==10)
- {
- tt=0;
- }//翻转
- }
-
- while(k1);//按键松开
- }
- }
- void key2pros()
- {
- po=1000;
- if(k2==1)//说明按下去了
- {
- while(po--);//消抖
- if(k2==1)
- {
- fasheng() ;
- aa=aa-1;
-
- }
-
- while(k2);//按键松开
- }
-
- }
- void tiaoshi()
- {
- switch(aa)
- {
- case 4:
- while(aa==4)
- {
- key2pros();
- key1pros();
- c=tt;
- SendTo595(QQ[0]);
- SendTo595(DISP[0]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[1]);
- SendTo595(DISP[0]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[2]);
- SendTo595(DIWP[0]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[3]);
- SendTo595(DISP[c]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- }
- break;
- case 3:while(aa==3)
- {
- key2pros();
- key1pros();
- v=tt;
- SendTo595(QQ[0]);
- SendTo595(DISP[0]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[1]);
- SendTo595(DISP[0]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[2]);
- SendTo595(DIWP[v]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[3]);
- SendTo595(DISP[c]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- }
-
- break;
- case 2:while(aa==2)
- {
- key2pros();
- key1pros();
- b=tt;
- SendTo595(QQ[0]);
- SendTo595(DISP[0]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[1]);
- SendTo595(DISP[b]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[2]);
- SendTo595(DIWP[v]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[3]);
- SendTo595(DISP[c]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- }
-
- break;
- case 1:
- while(aa==1)
- {
- key2pros();
- key1pros();
- n=tt;
- SendTo595(QQ[0]);
- SendTo595(DISP[n]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[1]);
- SendTo595(DISP[b]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[2]);
- SendTo595(DIWP[v]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- SendTo595(QQ[3]);
- SendTo595(DISP[c]);
- ST_CP = 0;
- _nop_();
- //位移寄存器完毕,转移到存储寄存器
- ST_CP = 1; //上升沿,存储寄存器变为高电平 延迟两个时钟周期
- _nop_();
- // _nop_();
- }
- t1s=b*10+n;
- tmin=c*10+v;
-
- break;
-
- }
- }
- void main()
- {
- Time_Init();
- Timer2Init();
- P3M0 = 0x00;
- P3M1 = 0x00;
- length = sizeof(tune)/sizeof(tune[0]);
- while(aa>0)
- {
- tiaoshi();
- //qq=tt;
- //TR0 = 1;
- //xian();
- }
- TR0 = 1;
- while(x)
- {
- xian();
- }
- AUXR |= 0x10;
- while(1)
- {
- for(x=0;x<length;x++)
- {
- tl0_f=freq[2*tune[x]]; //置一个音符的值
- th0_f=freq[2*tune[x]+1];
- delay(3500*duration[x]);
- }
- }
- }
复制代码
|