- /*风扇遥控芯片: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,/*位选*/ir[13],j,c,dw;unsigned int r,m,d0,d1,ds,se,buz;bit off,on,sm,cd,gj,yt;
- unsigned char code dm[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x08,0x48,0x49,0x76,0x00};/*共阴段码*/
- void delayms(unsigned int i){while(i--);}/*延时函数*/void int1init(){PX1=1;/*设置中断优先级*/IT1=1;EX1=1;EA=1;}/*外部中断1初始化函数,设置成下降沿触发*/
- void d0init()/*定时器0 1微秒@11.0592MHz*/
- {AUXR |= 0x80;/*定时器时钟1T模式*/TMOD &= 0xF0;/*设置定时器模式*/TL0 = 0xF5;/*设置定时初始值*/TH0 = 0xFF;/*设置定时初始值*/TF0 = 0;/*清除TF0标志*/TR0 = 0;/*定时器0先不计时*/}
- void d1init()/*定时器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){m=0xfd90;buz=1;while(!P11);}} /*摇头*/
- if(P12==0){delayms(5);if(P12==0){m=0xfd84;buz=1;while(!P12);}} /*风类*/
- if(P13==0){delayms(5);if(P13==0){m=0xfd81;buz=1;while(!P13);}} /*关机*/
- if(P14==0){delayms(5);if(P14==0){m=0xfd88;buz=1;while(!P14);}} /*定时*/
- if(P15==0){delayms(5);if(P15==0){m=0xfd82;buz=1;while(!P15);}} /*开/风速*/
- 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==0&se>0&sm==1){P1=dm[20];}
- if(i==1){P1=dm[b]; /*百位*/
- if(ds>999&sm==1){P1=dm[b]+0x80;}}
- if(i==2){P1=dm[s];}/*十位*/
- if(i==3){P1=dm[g];/*个位*/
- if(yt==1){P1=dm[g]+0x80;}}
- if(P33==1){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)/*当端口高电平时,编码位置还未清零*/
- {
- c1++; /*计算一下持续时间*/
- if(c1>250) /*超过一定的时间*/
- {
- c++;c1=0;
- }
- if(c>5) /*就要再次按遥控按键*/
- {
- j=0;c=0; /*如果还有干扰码就直接清零*/
- }
- }
- }
- void kzhs()/*键值控制函数 包含主板按键和红外遥控按键*/
- {
- unsigned char fl,zd;
- if(on==1&cd==1){display();/*开数码管*/}
- if(on==1&m==0xfd81){fl=0;on=0;dw=0;zd=0;se=0;ds=0;TR0=0;cd=0;j=0;}/*关机状态*/
- if(m==0xfd82&fl==0){fl=0;off=0;on=1;dw=dw+1;if(dw>3){dw=1;}cd=1;gj=0;j=0;m=0;}/*开机状态*/
- if(on==1&m==0xfd90){yt=~yt;cd=1;j=0;m=0;}/*摇头*/if(dw==0){P31=0;P32=0;P55=0;}
- if(fl==0&dw==1){P31=1;P32=0;P55=0;q=16;}/*慢档*/
- if(fl==0&dw==2){P31=0;P32=1;P55=0;q=17;}/*中档*/
- if(fl==0&dw==3){P31=0;P32=0;P55=1;q=18;}/*快档*/
- if(on==1&m==0xfd88){ds=ds+1800;d0=0;TR0=1;if(ds>28800){ds=0;}cd=1;gj=1;j=0;m=0;}
- /*定时控制函数*//*8.0小时=480分钟=28800秒 999秒=16.65分钟=0.2775小时*/
- if(ds>999){g=19;s=ds/60/6%10;b=ds/60/60;}/*g位显示H,s显示10进制的分钟,b显示小时加小数点*/
- if(ds<999){g=ds%10;s=ds/10%10;b=ds/100%10;/*q=ds/1000%10;*/}/*显示剩余秒数*/
- if(on==1&m==0xfd84){fl++;if(fl>2){fl=0;}zd=0;cd=1;j=0;m=0;}if(fl==0){se=0;}
- /*A类自然风:高速运转10秒,中速运转10秒,低速运转10秒;进入循环*/
- if(fl==1){q=10;if(se>1&se<11){zd=3;}if(se>10&se<21){zd=2;}if(se>20&se<31){zd=1;}if(se>30|se==0){se=1;}TR0=1;}
- /*b类睡眠风:高速转10分钟,中速转30分钟;之后退出睡眠模式,返回长风1档*/
- if(fl==2){q=11;if(se>1&se<600){zd=3;}if(se>600&se<1800){zd=2;}if(se>1800){m=0xfd84;}if(se==0){se=1;}TR0=1;}
- if(zd==1){P31=1;P32=0;P55=0;}/*慢档*/if(zd==2){P31=0;P32=1;P55=0;}/*中档*/if(zd==3){P31=0;P32=0;P55=1;}/*快档*/
- if(m==0xfdc3){cd=~cd;j=0;m=0;}/*彩灯开关,关机后单显示电压,开机后定时和电压切换显示*/
- if(ds!=0&c==0){ET0=1;}/*定时打开时,检测有无红外信号*/if(se!=0&c==0){ET0=1;}/*自动风打开时,检测有无红外信号*/
- }
- void fmq()/*蜂鸣器*/
- {
- if(off==0&buz>0)
- {
- buz++;
- P54=0;
- }
- if(buz>800)/*延时*/
- {
- P54=1;
- if(m==0xfd81)
- {
- off=1;
- m=0;
- }
- buz=0;
- }
- }
- void main()
- {
- P1M0=0xff; P1M1=0; P3M0=0x06; P3M1=0; P5M0=0x30; P5M1=0;/*端口模式*/
- P31=0;P32=0;P33=1;P54=1;P55=0;cd=1;j=0;dw=0;ds=0;gj=0;yt=0;buz=0;/*初始化*/
- d0init()/*定时器0初始化*/;d1init();/*定时器1初始化*/int1init();/*外部中断1初始化*/
- buz=1;fmq();/*上电蜂鸣器响一声*/
- while(1)
- {
- ircl();
- kayscan();
- kzhs();
- fmq();
- }
- }
- /*传统51单片机具有5个中断源,中断优先级从高到低依次是:外部中断0(interrupt0)、定时器0(interrupt1)、外部中断1(interrupt2)、定时器1(interrupt3)和串口中断(interrupt4)。*/
- void dsq0() interrupt 1
- {
- unsigned int ms,tu,tm;
- tu=965; /*调整微秒,建议:965*/
- tm=99; /*毫秒调整,建议:99*/
- d0=d0++; /*每约1微秒加1*/
- if(buz>0)
- {
- buz++;
- P54=0;
- }
- if(buz>800) /*延时*/
- {
- P54=1;
- buz=0;
- }
- if(!P33) /*检测到红外信号*/
- {
- ET0=0; /*返回主程序*/
- }
- if(d0>tu) /*受红外信号检测影响,建议199*/
- {
- ms++; /*每约1000微秒=1毫秒*/
- d0=0; /*us清零*/
- }
- if(ms>tm/2) /*每约0.5秒*/
- {
- sm=0; /*关闭闪秒*/
- }
- if(ms>tm) /*每约1000毫秒=1秒 参考值:19*/
- {
- if(ds>0)
- {
- ds--; /*定时秒数自减*/
- }
- se++;
- sm=1; /*点亮闪秒*/
- if(gj==1&ds==0)/*允许关机,定时时间到了*/
- {
- m=0xfd81; /*送出关机指令*/
- gj=0;
- }
- ms=0; /*毫秒清零*/
- }
- }
- void int1() interrupt 2 /*外部中断1服务函数,低电平触发*//*受遥控中断影响,不够时间处理编码,记录时间不放在这函数*/
- {
- unsigned char i;
- j++; /*编码位置*/
- if(m==0) /*如果还没解码正确*/
- {
- for(i=1;i<13;i++) /*未捕获间隔码*/
- {
- r=r<<1; /*从低位起左移1位*/
- if(ir[i]>70&&ir[i]<125) /*编码为1*/
- {
- r=r|0x001;/*或1*/
- }
- }
- }
- 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; /*收录合格编码*/
- buz=1; /*启动蜂鸣器*/
- }
- else
- {
- m=0; /*干扰码清零*/
- }
- if(j>12&m==0){j=0;} /*如果大于12位了,编码还不正确,就把位置清零,防止下一帧乱码*/
- }
- void dsqi() interrupt 3 /*定时器1 中断服务函数,每约13微秒中断1次*/{d1++;/*每约13微秒加1*/}
复制代码 |