- /*風扇遙控芯片: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*/}
復制代碼 |