#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
#define YF_YF 160
#define SFYF_JG 4/5
sbit BEEP = P1^5; //蜂鸣器驱动线
//红外引脚接P3^3(外部中断1引脚)
///////lcd12864///
sbit rs=P2^6; //寄存器选择输入
sbit rw=P2^5; //液晶读/写控制
sbit en= P2^7; //液晶使能控制
sbit psb=P3^2; //(此引脚为INT0接口)串/并方式控制 (由于psb=P3^2;与红外的P3^2接口重复,所以红外选P3^3,即INT1)
sbit rst1=P3^7; //液晶复位端口(注意:开发板连的是P3^7,这里用P2^0,由于和DQ=P3^7引脚重复,所以导致实验失败!!!)
uchar Time_H=0;
uchar Time_L=0;
uint code FreTab[12]={262,277,293,311,329,349,370,392,415,440,466,494}; // 原始频率表,低音
uchar code XY_Tab[7]={0,2,4,5,7,9,11}; // 1-7
uint New_FreTab[12];
uchar YC_Tab[]={1,2,4,8,16,32,64};
uchar IRtime; //记录中断次数,每次256us;
uchar startflag; //开始标志位
uchar bitnum; //位标号
uchar IRdata[33]; //装一帧数据33个IRtime的个数(1个引导码,8个用户码,8个用户码,8个数据码,8个数据反码)
uchar IRrecOK; //接收完成标志位
uchar IRcode[4]; //一帧数据的4组码
uchar IRprosOK; //处理完成标志位
uchar code table1[]=" 1挥着翅膀的女孩";
uchar code table2[]=" 2同一首歌 ";
uchar code table3[]=" 3两只蝴蝶 ";
uchar code table4[]=" 4祝你生日快乐 ";
//挥着翅膀的女孩
uchar code MusicGirl[]={ 0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x03,
0x16,0x03, 0x17,0x03, 0x17,0x03, 0x17,0x03, 0x18,0x03,
0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x02, 0x18,0x03,
0x17,0x03, 0x15,0x02, 0x18,0x03, 0x17,0x03, 0x18,0x02,
0x10,0x03, 0x15,0x03, 0x16,0x02, 0x15,0x03, 0x16,0x03,
0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x1A,0x03,
0x1B,0x03, 0x1F,0x03, 0x1F,0x03, 0x17,0x03, 0x18,0x03,
0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x03, 0x17,0x03,
0x18,0x03, 0x1F,0x03, 0x1F,0x02, 0x16,0x03, 0x17,0x03,
0x18,0x03, 0x17,0x03, 0x18,0x03, 0x20,0x03, 0x20,0x02,
0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,
0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03,
0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,
0x1A,0x03, 0x19,0x03, 0x15,0x03, 0x15,0x03, 0x17,0x03,
0x16,0x66, 0x17,0x04, 0x18,0x04, 0x18,0x03, 0x19,0x03,
0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,
0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03,
0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,
0x1A,0x03, 0x19,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,
0x1F,0x00, 0x1A,0x03, 0x1A,0x03, 0x1A,0x03, 0x1B,0x03,
0x1B,0x03, 0x1A,0x03, 0x19,0x03, 0x19,0x02, 0x17,0x03,
0x15,0x17, 0x15,0x03, 0x16,0x03, 0x17,0x03, 0x18,0x03,
0x17,0x04, 0x18,0x0E, 0x18,0x03, 0x17,0x04, 0x18,0x0E,
0x18,0x66, 0x17,0x03, 0x18,0x03, 0x17,0x03, 0x18,0x03,
0x20,0x03, 0x20,0x02, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66,
0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03, 0x1B,0x03,
0x1F,0x66, 0x1F,0x04, 0x1B,0x0E, 0x1B,0x03, 0x19,0x03,
0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,
0x15,0x03, 0x15,0x03, 0x17,0x03, 0x16,0x66, 0x17,0x04,
0x18,0x04, 0x18,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,
0x1F,0x66, 0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03,
0x1B,0x03, 0x1F,0x66, 0x1F,0x03, 0x1B,0x03, 0x19,0x03,
0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,
0x19,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x00, 0x18,0x02,
0x18,0x03, 0x1A,0x03, 0x19,0x0D, 0x15,0x03, 0x15,0x02,
0x18,0x66, 0x16,0x02, 0x17,0x02, 0x15,0x00, 0x00,0x00};
//同一首歌
uchar code MusicSame[]={ 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x66, 0x18,0x03,
0x17,0x02, 0x15,0x02, 0x16,0x01, 0x15,0x02, 0x10,0x02,
0x15,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x02,
0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x02, 0x18,0x66,
0x17,0x03, 0x19,0x02, 0x16,0x03, 0x17,0x03, 0x16,0x00,
0x17,0x01, 0x19,0x02, 0x1B,0x02, 0x1B,0x70, 0x1A,0x03,
0x1A,0x01, 0x19,0x02, 0x19,0x03, 0x1A,0x03, 0x1B,0x02,
0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x18,0x66, 0x18,0x03,
0x19,0x02, 0x1A,0x02, 0x19,0x0C, 0x18,0x0D, 0x17,0x03,
0x16,0x01, 0x11,0x02, 0x11,0x03, 0x10,0x03, 0x0F,0x0C,
0x10,0x02, 0x15,0x00, 0x1F,0x01, 0x1A,0x01, 0x18,0x66,
0x19,0x03, 0x1A,0x01, 0x1B,0x02, 0x1B,0x03, 0x1B,0x03,
0x1B,0x0C, 0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x1F,0x01,
0x1A,0x01, 0x18,0x66, 0x19,0x03, 0x1A,0x01, 0x10,0x02,
0x10,0x03, 0x10,0x03, 0x1A,0x0C, 0x18,0x0D, 0x17,0x03,
0x16,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x70,
0x18,0x03, 0x17,0x02, 0x15,0x03, 0x15,0x03, 0x16,0x66,
0x16,0x03, 0x16,0x02, 0x16,0x03, 0x15,0x03, 0x10,0x02,
0x10,0x01, 0x11,0x01, 0x11,0x66, 0x10,0x03, 0x0F,0x0C,
0x1A,0x02, 0x19,0x02, 0x16,0x03, 0x16,0x03, 0x18,0x66,
0x18,0x03, 0x18,0x02, 0x17,0x03, 0x16,0x03, 0x19,0x00,
0x00,0x00 };
//两只蝴蝶
uchar code MusicTwo[]={ 0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,
0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,
0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,
0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x16,0x03,
0x17,0x01, 0x16,0x03, 0x17,0x03, 0x16,0x03, 0x15,0x01,
0x10,0x03, 0x15,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,
0x16,0x03, 0x15,0x03, 0x10,0x03, 0x15,0x03, 0x16,0x01,
0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,
0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,
0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,
0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x19,0x03,
0x19,0x01, 0x19,0x03, 0x1A,0x03, 0x19,0x03, 0x17,0x01,
0x16,0x03, 0x16,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,
0x16,0x03, 0x15,0x03, 0x10,0x03, 0x10,0x0D, 0x15,0x00,
0x19,0x03, 0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03,
0x1B,0x03, 0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03,
0x16,0x0D, 0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03,
0x1A,0x02, 0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03,
0x16,0x01, 0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03,
0x19,0x02, 0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E,
0x1B,0x04, 0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E,
0x1B,0x04, 0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03,
0x17,0x0D, 0x16,0x03, 0x17,0x03, 0x19,0x01, 0x19,0x03,
0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03, 0x1B,0x03,
0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03, 0x16,0x03,
0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03, 0x1A,0x02,
0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x01,
0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03, 0x19,0x03,
0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,
0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,
0x17,0x16, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,
0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03, 0x0F,0x02,
0x10,0x03, 0x15,0x00, 0x00,0x00 };
//祝你生日快乐
uchar code MusicHappy[]={0x0F,0x03, 0x0F,0x03, 0x10,0x02, 0x0F,0x02, 0x15,0x02,
0x11,0x01, 0x0F,0x03, 0x0F,0x03, 0x10,0x02, 0x0F,0x02,
0x16,0x02, 0x15,0x01, 0x0F,0x03, 0x0F,0x03, 0x19,0x02,
0x17,0x02, 0x15,0x02, 0x11,0x0C, 0x10,0x02, 0x18,0x03,
0x18,0x03, 0x17,0x02, 0x15,0x02, 0x16,0x02, 0x17,0x01,
0x0F,0x03, 0x0F,0x03, 0x10,0x02, 0x0F,0x02, 0x15,0x02,
0x11,0x01, 0x0F,0x03, 0x0F,0x03, 0x10,0x02, 0x0F,0x02,
0x16,0x02, 0x15,0x01, 0x0F,0x03, 0x0F,0x03, 0x19,0x02,
0x17,0x02, 0x15,0x02, 0x11,0x0C, 0x10,0x02, 0x18,0x03,
0x18,0x03, 0x17,0x02, 0x15,0x02, 0x16,0x02, 0x10,0x01,
0x00,0x00 };
void Delay_10MS(void);
void JX_New_Few_FerTab(uchar QSD,uchar SYD);
void Play_Music(uchar *Sound,uchar QSD,uchar SYD);
void timer1_init(void);
void timer0_init(void);
void int1_init(void);
void IRpros(void);
void beep(void);
void delay_50us(uint t);
void delay_1ms(uint z);
void LCD12864_write_com(uchar com);
void LCD12864_write_data(uchar dat);
void LCD12864_init(void);
void delay_50us(uint t)//已调试过,延时50us
{
uchar j;
for(;t>0;t--)
for(j=38;j>0;j--);
}
void delay_1ms(uint z)//已调试过,延时1ms
{
uint x,y;
for(x=z;x>0;x--)
for(y=247;y>0;y--);
}
void LCD12864_write_com(uchar com)
{
en=0;
rs=0;
rw=0;
delay_50us(1);
P0=com;
en=1;
delay_50us(3);
en=0;
delay_50us(4);
}
void LCD12864_write_data(uchar dat)
{
en=0;
rs=1;
rw=0;
delay_50us(1);
P0=dat;
en=1;
delay_50us(3);
en=0;
delay_50us(4);
}
void LCD12864_init(void)
{
uchar i;
psb=1;
rst1=0;
delay_1ms(100);
rst1=1;
LCD12864_write_com(0x30);
delay_50us(4);
LCD12864_write_com(0x30);
delay_50us(2);
LCD12864_write_com(0x0c);
delay_50us(4);
LCD12864_write_com(0x01);
delay_50us(1);
LCD12864_write_com(0x06);
delay_1ms(10);
LCD12864_write_com(0x80); //显示的一行
for(i=0;i<16;i++)
{
LCD12864_write_data(table1);
}
LCD12864_write_com(0x90); //显示的二行
for(i=0;i<16;i++)
{
LCD12864_write_data(table2);
}
LCD12864_write_com(0x88); //显示的三行
for(i=0;i<16;i++)
{
LCD12864_write_data(table3);
}
LCD12864_write_com(0x98); //显示的四行
for(i=0;i<16;i++)
{
LCD12864_write_data(table4);
}
}
void timer0_init(void)
{
TMOD=0x02; //定时器0工作在方式2(自动重装8位初值)
TH0=0x00;
TL0=0x00; //256us溢出产生中断
ET0=1;
EA=1;
TR0=1;
}
void int1_init(void)
{
IT1=1; //外部中断0选择下降沿触发
EX1=1;
EA=1;
}
void IRpros(void)
{
uchar i,j,k;
uchar value;
k=1; //跳过引导码
for(i=0;i<4;i++) //一帧数据4组,一组一组来
{
for(j=0;j<8;j++) //一组数据8位,一位一位来
{
value=value>>1; //由于从低位读起,所以用循环右移
if(IRdata[k]>6) // (1.125ms/0.256ms=4.39)< 6 <(2.25ms/0.256ms=8.80),取中间值6做判断标准
value=value|0x80;
k++; //k一直加到32,k不需清零,因为接收下一帧数据的时候从头开始,即k=1
}
IRcode=value;
}
IRprosOK=1;
}
void beep(void)
{
uchar i;
for (i=0;i<200;i++) //喇叭发声的时间循环,改变大小可以改变发声时间长短
{
delay_50us(20); //参数决定发声的频率,估算值,可以自行更改参数并
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
}
void timer1_init(void)
{
TMOD=0x10;
TH1=0xFF;
TL1=0xFF;
ET1=1;
TR1= 0;
EA=1;
}
void main(void)
{
timer0_init();
int1_init();
timer1_init();
LCD12864_init();
while(1)
{
if(IRrecOK)
{
IRpros();
IRrecOK=0;
}
if(IRprosOK)
{
beep();
IRprosOK=0;
}
if((IRcode[2])==(~IRcode[3])&&(IRcode[0]==0x00)&&(IRcode[1]==0xff))//地址码数据码验证
{
switch(IRcode[2]) // 注意:红外解码、12864显示、蜂鸣器演奏模块调试过正常,本人第一次使用红外键码,一到 switch(IRcode[2]) 就进不去了,求高手指点,感激不尽!
{
case 0x0c: LCD12864_write_com(0x80);LCD12864_write_data(0x10);Play_Music(MusicGirl,0,0);//按键1
break;
case 0x18: LCD12864_write_com(0x90);LCD12864_write_data(0x10);Play_Music(MusicSame,0,0);//按键2
break;
case 0x5e: LCD12864_write_com(0x88);LCD12864_write_data(0x10);Play_Music(MusicTwo,0,0);//按键3
break;
case 0x08: LCD12864_write_com(0x98);LCD12864_write_data(0x10);Play_Music(MusicHappy,5,0);//按键4
break;
}
}
/* if(IRcode[2]==0x0c)
{
LCD12864_write_com(0x80);LCD12864_write_data(0x10);Play_Music(MusicGirl,0,0);
}
else
{
LCD12864_write_com(0x98);LCD12864_write_data(0x10);Play_Music(MusicHappy,5,0);
}*/
}
}
void timer0() interrupt 1 //中断服务子程序不需函数声明,定时器0的中断号为1
{
IRtime++;
}
void int1() interrupt 2 //中断服务子程序不需函数声明,外部中断1的中断号为2
{
if(startflag)
{
if(IRtime>33) // 9ms/0.256ms=35.15,传播途中波形有变化,选33。检测引导码
bitnum=0;
IRdata[bitnum]=IRtime;
IRtime=0;
bitnum++;
if(bitnum==33)
{
bitnum=0;
IRrecOK=1; //一帧数据接受完毕
startflag=0; //标志位清零,每一帧都开头都进入else,打开startflag=1
}
}
else //每一帧数据开头打开startflag=1,一帧内再不进入else,下一帧再进入
{
startflag=1;
IRtime=0;
}
}
void timer1() interrupt 3
{
BEEP=~BEEP;
TH1=Time_H;
TL1=Time_L;
}
void JX_New_Few_FerTab(uchar QSD,uchar SYD) // QSD 0-11 SYD 1-3 1降8度 2不变,3升8度
{
uchar i=0;
uchar j=0;
for(i=0;i<12;i++) // 12次循环
{
j=i+QSD; //根据起始调判断起始音符位置
if(j>11) //如果起始调不是最低
{
j=j-12; // 0-11
New_FreTab=FreTab[j]*2;// 频率*2
}
else //频率不变
{
New_FreTab=FreTab[j];
}
if(SYD==1) //判断升降调。1降调,2不变,3升调。
{
New_FreTab>>=1;//频率减一半
}
else
{
if(SYD==3)
{
New_FreTab<<=1;
}
}
}
}
void Play_Music(uchar *Sound,uchar QSD,uchar SYD)
{
uint GQ_CD=0; //歌曲长度
uint GQ_WZ=0;
uchar GQ_YG=0;
uchar GQ_YC=0;
uint YP_PL=0;
uchar YG_Bai=0;
uchar YG_Shi=0;
uchar YG_Ge=0;
uchar YC_Bai=0;
uchar YC_Shi=0;
uchar YC_Ge=0;
uint DSD_PL=0;
uint YF0=0; // 1分音符变量
uint YF1=0; // 发音长度时间
uint YF2=0; //不发音长度时间
uint YF4=0; // 4分音符时间
uint FY_JG=0;
uint YZ_TC=0;
uint JF_YF=0;
uchar i=0;
JX_New_Few_FerTab(QSD,SYD);
while(Sound[GQ_CD]!=0) //判断歌曲长度
{
GQ_CD+=2; //指向下一位音符数据
}
while(GQ_WZ<GQ_CD)
{
GQ_YG=Sound[GQ_WZ];
YG_Bai=GQ_YG/100; // 1升半音,0不升
YG_Shi=GQ_YG/10%10; // 1低音,2为中音,3为高音
YG_Ge=GQ_YG%10; // 1-7 音符位;
YP_PL=New_FreTab[XY_Tab[YG_Ge-1]+YG_Bai];// yg_ge -1 1-7 0-6
if(YG_Ge!=0)
{
switch(YG_Shi)
{
case 2: YP_PL<<=1;break;
case 3: YP_PL<<=2;break;
}
DSD_PL=65536-(50000/YP_PL)*10;
Time_H=DSD_PL>>8;
Time_L=DSD_PL&0x00FF;
TH1=Time_H;
TL1=Time_L;
}
GQ_YC=Sound[GQ_WZ+1];
YC_Bai=GQ_YC/100; // 1有符点,0无符点
YC_Shi=GQ_YC/10%10; // 演奏效果0普通,1连音,2顿音
YC_Ge=GQ_YC%10; // 几分音符。
YF0=YF_YF;
YF4=YF0/4;
FY_JG=YF4-YF4*SFYF_JG;
JF_YF=YC_Tab[YC_Ge];// 几分音符;
YZ_TC=YF0/JF_YF; // 算出对应延时长度多少个10MS
if(YC_Bai==1) //判断是否有符点
{
YZ_TC=YZ_TC+YZ_TC/2;//有符点
}
if(YC_Shi!=1) //不是连音
{
if(YC_Shi==0) //是否为普通音
{
if(JF_YF<=4) // 是否小于16分音
{
YF1=YZ_TC-FY_JG; // 发音有间隔
}
else // 不小于16分音
{
YF1=YZ_TC*SFYF_JG;//发音无音隔
}
}
else //是顿音,演奏时间为原来的一半
{
YF1=YZ_TC/2;
}
}
else //是连音,发音无音隔
{
YF1 =YZ_TC;
}
if(YG_Ge==0) //没有音符数据
{
YF1=0; //演奏时间 = 0
}
else //有音符数据
{
YF2=YZ_TC-YF1;
TR1=1;
for(i=YF1;i>0;i--)
{
Delay_10MS();
}
BEEP=1;
TR1=0;
for(i= YF2;i>0;i--)
{
Delay_10MS();
}
}
GQ_WZ+=2; //指向下一个音符
}
}
void Delay_10MS(void) //延时函数 10MS
{
uchar a=0;
uchar b=0;
for(a=50;a>0;a--)
{
for(b=100;b>0;b--);
}
} |