- /*风扇遥控芯片:BA5104 红外遥控解码程序 晶振频率:11.0592MHZ 1帧12位,一次至少发2帧*//*历时8天成功调试,干扰码直接清零,只显示相关键值*/
- /*解码后的键值:关机 0xfd81; 开/风速 0xfd82; 风类 0xfd84; 定时 0xfd88; 摇头 0xfd90; 彩灯 0xfdc3; 无 0xfda0; 无 0xfdc6*/
- #include "STC8G.h"/*单片机:STC8G1K08-TSSOP20*//*红外端口:P33(包含外部中断1,改端口时要注意)*/
- unsigned char q,b,s,g,/*位选*/xs,ir[13],j,c;unsigned int r,m,d0,d1;
- unsigned char code dm[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};/*共阴段码*/
- void delayms(unsigned int i){while(i--);}/*延时函数*/
- void int1init(){IT1=1;EX1=1;EA=1;}/*外部中断1初始化函数,设置成下降沿触发*/
- void d1r1Init()/*定时器1初始化函数*/{AUXR |= 0x40;/*1T*/TMOD &= 0x0F;TL1 = 0x70;/*初始值*/TH1 = 0xFF;/*初始值*/TF1 = 0;/*清除TF1标志*/TR1=0;/*先不启动*/ET1=1;/*开中断*/EA=1;}
- void kayscan()/*P1端口对地增加按键*/
- {
- P1=0xff;
- P34=1;P35=1;P36=1;P37=1;
- if(P11==0){delayms(5);if(P11==0){IAP_CONTR |= 0x20;/*软件复位,并且从用户程序开始执行*/while(!P11);}}
- if(P12==0){delayms(5);if(P12==0){xs=1;while(!P12);}}if(P13==0){delayms(5);if(P13==0){xs=2;while(!P13);}}
- P1=0x00;
- }
- void display()/*数码管扫描*/
- {
- unsigned char i;for(i=0;i<4;i++){switch(i)/*选择显示位置*/
- {case(0):P34=0;P35=1;P36=1;P37=1;break;/*千位*/case(1):P34=1;P35=0;P36=1;P37=1;break;/*百位*/case(2):P34=1;P35=1;P36=0;P37=1;break;/*十位*/case(3):P34=1;P35=1;P36=1;P37=0;break;/*个位*/}
- if(i==0){P1=dm[q];}/*千位*/if(i==1){P1=dm[b];}/*百位*/if(i==2){P1=dm[s];}/*十位*/if(i==3){P1=dm[g];}/*个位*/delayms(50); /*间隔一段时间扫描*/P1=0x00;/*消隐*/}
- }
- void ircl()/*红外时间记录*/
- {
- unsigned char c1;
- if(!P33)
- {
- d1=0;
- TR1=1;/*启动定时器1*/
- while(!P33);
- TR1=0;
- ir[j]=d1;
- }
- /*编码位置清零*/
- if(P33==1&&j>0)/*当端口高电平时,编码位置还未清零*/
- {
- c++;/*计算一下持续时间*/
- if(c>250){c1++;c=0;}/*超过一定的时间*/
- if(c1>5){j=0;c1=0;}/*就要再次按遥控按键*/
- /*如果还有干扰码就直接清零*/
- }
- }
- void xssz() /*显示的数值*/
- {
- /*按K1显示收录的红外编码*/
- if(xs==0){g=m/1%16;s=m/16%16;b=m/256%16;q=m/4096%16;}/*1倍代表示4位16进制,16倍表示8位16进制,256倍表示12位16进制,4096倍表示16位16进制*/
- /*按K2显示0表示编码位置清零成功*/
- if(xs==1){g=c%10;s=c/10%10;b=c/100%10;q=0;}
- /*按K3显示大约中断次数和快速清零*/
- if(xs==2){g=j%10;s=j/10%10;b=j/100%10;q=j/1000%10;}
- }
- void main()
- {
- P1M0=0xff; P1M1=0; P3M0=0; P3M1=0; P5M0=0; P5M1=0;/*端口模式*/P33=1;j=0;xs=0;
- d1r1Init();/*定时器1初始化*/
- delayms(1000);/*等待电源稳定*/
- int1init();/*外部中断1初始化*/
- while(1)
- {
- ircl();
- kayscan();
- xssz();
- display();
- }
- }
- /*传统51单片机具有5个中断源,中断优先级从高到低依次是:外部中断0(interrupt0)、定时器0(interrupt1)、外部中断1(interrupt2)、定时器1(interrupt3)和串口中断(interrupt4)。*/
- void int1() interrupt 2 /*外部中断1服务函数,低电平触发*//*受遥控中断影响,不够时间处理编码,记录时间不可以在这函数里*/
- {
- unsigned int i;
- j++;/*编码位置*/
- if(m==0)/*如果还没解码正确*/
- {
- for(i=1;i<13;i++)/*未捕获间隔码*/
- {
- r=r<<1;
- if(ir[i]>70&&ir[i]<125)
- {
- r=r|0x001;
- }
- }
- }
- if(j>12){r=r|0xf000;}/*表示收到符合长度的编码*/else{r=0x0000;}/*清零*/
- if(r==0xfd81|r==0xfd82|r==0xfd84|r==0xfd88|r==0xfd90|r==0xfdc3|r==0xfda0|r==0xfdc6)
- {
- m=r;/*收录合格编码*/
- }
- else
- {
- m=0;
- }
- if(j>12&m==0){j=0;}/*如果大于12位了,编码还不正确,就把位置清零,防止下一帧乱码*/
- }
- void TM1_Isr() interrupt 3 /*定时器1 中断服务函数,每约13微秒中断1次*/{d1++;/*每约13微秒加1*/}
复制代码 |