標(biāo)題: 單片機(jī)遙控風(fēng)扇控制程序,望大師優(yōu)化 [打印本頁]

作者: 玉萌業(yè)余發(fā)展    時(shí)間: 2023-5-23 14:07
標(biāo)題: 單片機(jī)遙控風(fēng)扇控制程序,望大師優(yōu)化
  1. /*風(fēng)扇遙控芯片:BA5104  紅外遙控解碼程序  晶振頻率:11.0592MHZ  1幀12位,一次至少發(fā)2幀*//*歷時(shí)8天成功調(diào)試,干擾碼直接清零,只顯示相關(guān)鍵值*/
  2. /*解碼后的鍵值:關(guān)機(jī) 0xfd81; 開/風(fēng)速 0xfd82; 風(fēng)類 0xfd84; 定時(shí) 0xfd88; 搖頭 0xfd90; 彩燈 0xfdc3; 無 0xfda0; 無 0xfdc6*/
  3. #include "STC8G.h"/*單片機(jī):STC8G1K08-TSSOP20*//*紅外端口:P33(包含外部中斷1,改端口時(shí)要注意)*/
  4. 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;
  5. 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};/*共陰段碼*/
  6. void delayms(unsigned int i){while(i--);}/*延時(shí)函數(shù)*/void int1init(){PX1=1;/*設(shè)置中斷優(yōu)先級*/IT1=1;EX1=1;EA=1;}/*外部中斷1初始化函數(shù),設(shè)置成下降沿觸發(fā)*/
  7. void d0init()/*定時(shí)器0 1微秒@11.0592MHz*/
  8. {AUXR |= 0x80;/*定時(shí)器時(shí)鐘1T模式*/TMOD &= 0xF0;/*設(shè)置定時(shí)器模式*/TL0 = 0xF5;/*設(shè)置定時(shí)初始值*/TH0 = 0xFF;/*設(shè)置定時(shí)初始值*/TF0 = 0;/*清除TF0標(biāo)志*/TR0 = 0;/*定時(shí)器0先不計(jì)時(shí)*/}
  9. void d1init()/*定時(shí)器1初始化函數(shù)*/{AUXR |= 0x40;/*1T*/TMOD &= 0x0F;TL1 = 0x70;/*初始值*/TH1 = 0xFF;/*初始值*/TF1 = 0;/*清除TF1標(biāo)志*/TR1=0;/*先不啟動(dòng)*/ET1=1;/*開中斷*/EA=1;}
  10. void kayscan()/*P1端口對地增加按鍵*/
  11. {
  12.         P1=0xff;
  13.         P34=1;P35=1;P36=1;P37=1;
  14.   if(P11==0){delayms(5);if(P11==0){m=0xfd90;buz=1;while(!P11);}} /*搖頭*/
  15.         if(P12==0){delayms(5);if(P12==0){m=0xfd84;buz=1;while(!P12);}} /*風(fēng)類*/
  16.   if(P13==0){delayms(5);if(P13==0){m=0xfd81;buz=1;while(!P13);}} /*關(guān)機(jī)*/
  17.         if(P14==0){delayms(5);if(P14==0){m=0xfd88;buz=1;while(!P14);}} /*定時(shí)*/
  18.         if(P15==0){delayms(5);if(P15==0){m=0xfd82;buz=1;while(!P15);}} /*開/風(fēng)速*/
  19.         P1=0x00;
  20. }
  21. void display()/*數(shù)碼管掃描*/
  22. {
  23.         unsigned char i;for(i=0;i<4;i++){switch(i)/*選擇顯示位置*/
  24.         {
  25.                 case(0):P34=0;P35=1;P36=1;P37=1;break;  /*千位*/
  26.                 case(1):P34=1;P35=0;P36=1;P37=1;break;  /*百位*/
  27.                 case(2):P34=1;P35=1;P36=0;P37=1;break;  /*十位*/
  28.           case(3):P34=1;P35=1;P36=1;P37=0;break;  /*個(gè)位*/
  29.         }
  30.     if(i==0){P1=dm[q];}/*千位*/
  31.                 if(i==0&se>0&sm==1){P1=dm[20];}
  32.           if(i==1){P1=dm[b]; /*百位*/
  33.                 if(ds>999&sm==1){P1=dm[b]+0x80;}}
  34.           if(i==2){P1=dm[s];}/*十位*/
  35.           if(i==3){P1=dm[g];/*個(gè)位*/
  36.                 if(yt==1){P1=dm[g]+0x80;}}
  37.           if(P33==1){delayms(50);}       /*間隔一段時(shí)間掃描*/
  38.           P1=0x00;          /*消隱*/
  39.         }
  40. }
  41. void ircl()      /*紅外時(shí)間記錄*/
  42. {
  43.         unsigned char c1;
  44.         if(!P33)
  45.         {
  46.     d1=0;
  47.     TR1=1;       /*啟動(dòng)定時(shí)器1*/
  48.     while(!P33);
  49.     TR1=0;
  50.     ir[j]=d1;
  51.         }              /*編碼位置清零*/                    
  52.   if(P33==1&&j>0)/*當(dāng)端口高電平時(shí),編碼位置還未清零*/
  53.         {
  54.     c1++;        /*計(jì)算一下持續(xù)時(shí)間*/
  55.    if(c1>250)    /*超過一定的時(shí)間*/
  56.   {
  57.     c++;c1=0;
  58.   }
  59.          if(c>5)       /*就要再次按遙控按鍵*/
  60.   {
  61.           j=0;c=0;     /*如果還有干擾碼就直接清零*/
  62.         }                     
  63.         }
  64. }
  65. void kzhs()/*鍵值控制函數(shù) 包含主板按鍵和紅外遙控按鍵*/
  66. {
  67.         unsigned char fl,zd;
  68.         if(on==1&cd==1){display();/*開數(shù)碼管*/}
  69.         if(on==1&m==0xfd81){fl=0;on=0;dw=0;zd=0;se=0;ds=0;TR0=0;cd=0;j=0;}/*關(guān)機(jī)狀態(tài)*/
  70.         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;}/*開機(jī)狀態(tài)*/
  71.   if(on==1&m==0xfd90){yt=~yt;cd=1;j=0;m=0;}/*搖頭*/if(dw==0){P31=0;P32=0;P55=0;}
  72.   if(fl==0&dw==1){P31=1;P32=0;P55=0;q=16;}/*慢檔*/
  73.   if(fl==0&dw==2){P31=0;P32=1;P55=0;q=17;}/*中檔*/
  74.   if(fl==0&dw==3){P31=0;P32=0;P55=1;q=18;}/*快檔*/
  75.         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;}
  76.         /*定時(shí)控制函數(shù)*//*8.0小時(shí)=480分鐘=28800秒  999秒=16.65分鐘=0.2775小時(shí)*/
  77.         if(ds>999){g=19;s=ds/60/6%10;b=ds/60/60;}/*g位顯示H,s顯示10進(jìn)制的分鐘,b顯示小時(shí)加小數(shù)點(diǎn)*/
  78.         if(ds<999){g=ds%10;s=ds/10%10;b=ds/100%10;/*q=ds/1000%10;*/}/*顯示剩余秒數(shù)*/
  79.         if(on==1&m==0xfd84){fl++;if(fl>2){fl=0;}zd=0;cd=1;j=0;m=0;}if(fl==0){se=0;}
  80.         /*A類自然風(fēng):高速運(yùn)轉(zhuǎn)10秒,中速運(yùn)轉(zhuǎn)10秒,低速運(yùn)轉(zhuǎn)10秒;進(jìn)入循環(huán)*/
  81.         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;}
  82.         /*b類睡眠風(fēng):高速轉(zhuǎn)10分鐘,中速轉(zhuǎn)30分鐘;之后退出睡眠模式,返回長風(fēng)1檔*/
  83.   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;}
  84.         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;}/*快檔*/
  85.         if(m==0xfdc3){cd=~cd;j=0;m=0;}/*彩燈開關(guān),關(guān)機(jī)后單顯示電壓,開機(jī)后定時(shí)和電壓切換顯示*/
  86.         if(ds!=0&c==0){ET0=1;}/*定時(shí)打開時(shí),檢測有無紅外信號(hào)*/if(se!=0&c==0){ET0=1;}/*自動(dòng)風(fēng)打開時(shí),檢測有無紅外信號(hào)*/
  87. }
  88. void fmq()/*蜂鳴器*/
  89. {
  90.                 if(off==0&buz>0)
  91.           {        
  92.             buz++;
  93.                   P54=0;        
  94.           }
  95.           if(buz>800)/*延時(shí)*/
  96.           {
  97.                   P54=1;        
  98.                 if(m==0xfd81)
  99.                 {
  100.                         off=1;
  101.                         m=0;
  102.                 }
  103.                   buz=0;
  104.           }
  105. }
  106. void main()
  107. {
  108.         P1M0=0xff; P1M1=0; P3M0=0x06; P3M1=0; P5M0=0x30; P5M1=0;/*端口模式*/
  109.         P31=0;P32=0;P33=1;P54=1;P55=0;cd=1;j=0;dw=0;ds=0;gj=0;yt=0;buz=0;/*初始化*/
  110.         d0init()/*定時(shí)器0初始化*/;d1init();/*定時(shí)器1初始化*/int1init();/*外部中斷1初始化*/
  111.         buz=1;fmq();/*上電蜂鳴器響一聲*/
  112.         while(1)
  113.         {
  114.                 ircl();
  115.                 kayscan();
  116.                 kzhs();
  117.                 fmq();
  118.         }
  119. }
  120. /*傳統(tǒng)51單片機(jī)具有5個(gè)中斷源,中斷優(yōu)先級從高到低依次是:外部中斷0(interrupt0)、定時(shí)器0(interrupt1)、外部中斷1(interrupt2)、定時(shí)器1(interrupt3)和串口中斷(interrupt4)。*/
  121. void dsq0() interrupt 1
  122. {
  123.         unsigned int ms,tu,tm;
  124.         tu=965;          /*調(diào)整微秒,建議:965*/
  125.         tm=99;           /*毫秒調(diào)整,建議:99*/
  126.   d0=d0++;         /*每約1微秒加1*/
  127.         if(buz>0)
  128.         {        
  129.           buz++;
  130.                 P54=0;        
  131.   }
  132.         if(buz>800)      /*延時(shí)*/
  133.         {
  134.                 P54=1;
  135.                 buz=0;
  136.         }
  137.         if(!P33)         /*檢測到紅外信號(hào)*/
  138.         {
  139.                 ET0=0;         /*返回主程序*/
  140.         }
  141.         if(d0>tu)        /*受紅外信號(hào)檢測影響,建議199*/
  142.         {
  143.                 ms++;          /*每約1000微秒=1毫秒*/
  144.                 d0=0;          /*us清零*/
  145.         }
  146.         if(ms>tm/2)      /*每約0.5秒*/
  147.         {
  148.           sm=0;          /*關(guān)閉閃秒*/
  149.         }
  150.         if(ms>tm)        /*每約1000毫秒=1秒 參考值:19*/
  151.         {
  152.                 if(ds>0)                        
  153.      {
  154.                  ds--;         /*定時(shí)秒數(shù)自減*/
  155.                  }            
  156.                  se++;
  157.                  sm=1;         /*點(diǎn)亮閃秒*/
  158.                 if(gj==1&ds==0)/*允許關(guān)機(jī),定時(shí)時(shí)間到了*/
  159.                 {
  160.                         m=0xfd81;    /*送出關(guān)機(jī)指令*/
  161.                         gj=0;
  162.                 }
  163.                 ms=0;          /*毫秒清零*/
  164.         }
  165. }
  166. void int1() interrupt 2 /*外部中斷1服務(wù)函數(shù),低電平觸發(fā)*//*受遙控中斷影響,不夠時(shí)間處理編碼,記錄時(shí)間不放在這函數(shù)*/
  167. {
  168.         unsigned char i;
  169.         j++;                  /*編碼位置*/
  170.   if(m==0)              /*如果還沒解碼正確*/
  171.           {
  172.       for(i=1;i<13;i++) /*未捕獲間隔碼*/
  173.          {
  174.            r=r<<1;      /*從低位起左移1位*/
  175.            if(ir[i]>70&&ir[i]<125) /*編碼為1*/
  176.              {
  177.                      r=r|0x001;/*或1*/
  178.              }
  179.           }
  180.     }
  181.         if(j>12){r=r|0xf000;} /*表示收到符合長度的編碼*/
  182.   else{r=0x0000;}       /*干擾清零*/  
  183.         if(r==0xfd81|r==0xfd82|r==0xfd84|r==0xfd88|r==0xfd90|r==0xfdc3|r==0xfda0|r==0xfdc6)
  184.         {
  185.                 m=r;                /*收錄合格編碼*/
  186.                 buz=1;              /*啟動(dòng)蜂鳴器*/
  187.         }
  188.         else
  189.         {
  190.                 m=0;                /*干擾碼清零*/
  191.         }
  192.         if(j>12&m==0){j=0;}   /*如果大于12位了,編碼還不正確,就把位置清零,防止下一幀亂碼*/
  193. }
  194. void dsqi() interrupt 3 /*定時(shí)器1 中斷服務(wù)函數(shù),每約13微秒中斷1次*/{d1++;/*每約13微秒加1*/}
復(fù)制代碼

作者: xuyaqi    時(shí)間: 2023-5-23 16:09
你13微秒中斷1次,造成cpu一直不停處理中斷,根本沒時(shí)間干別的,定時(shí)器1 應(yīng)該有一個(gè)合理中斷時(shí)間間隔。
作者: 123156fsadf    時(shí)間: 2023-5-23 17:06
1、代碼沒對齊,風(fēng)格較差
2、中斷中代碼過長,可能導(dǎo)致下個(gè)中斷進(jìn)來了都沒處理完
3、51的棧空間太小,不建議中斷太多代碼
4、函數(shù)名太短,且為拼音首字母,難以理解
5、中斷間隔太短了
作者: yzwzfyz    時(shí)間: 2023-5-24 11:23
不要急于寫程序。先規(guī)劃一下方案。
再出個(gè)程序流程圖,先走通流程圖而后再寫程序。
如沙發(fā)提出的問題,你如果規(guī)劃過方案,就不犯。
例如:列出風(fēng)扇的功能,一個(gè)給出實(shí)現(xiàn)的方式。切換的方法,條件,檢測的方式,顯示的方式……。
這此都在事先做規(guī)劃。至少羅列于EXCEL表中吧。
作者: 玉萌業(yè)余發(fā)展    時(shí)間: 2023-5-24 12:21
123156fsadf 發(fā)表于 2023-5-23 17:06
1、代碼沒對齊,風(fēng)格較差
2、中斷中代碼過長,可能導(dǎo)致下個(gè)中斷進(jìn)來了都沒處理完
3、51的?臻g太小,不 ...

謝謝建議。我這是業(yè)余愛好的
作者: 玉萌業(yè)余發(fā)展    時(shí)間: 2023-5-24 12:21
xuyaqi 發(fā)表于 2023-5-23 16:09
你13微秒中斷1次,造成cpu一直不停處理中斷,根本沒時(shí)間干別的,定時(shí)器1 應(yīng)該有一個(gè)合理中斷時(shí)間間隔。

試了,剛好可以識(shí)別紅外信號(hào)
作者: 玉萌業(yè)余發(fā)展    時(shí)間: 2023-5-24 12:22
yzwzfyz 發(fā)表于 2023-5-24 11:23
不要急于寫程序。先規(guī)劃一下方案。
再出個(gè)程序流程圖,先走通流程圖而后再寫程序。
如沙發(fā)提出的問題,你 ...

嗯嗯。專業(yè)的手法就是不一樣。
作者: 123456ZXC1    時(shí)間: 2023-5-24 12:27
先給你來一段
#include "STC8G.h"

// 定義紅外解碼鍵值
#define KEY_POWER     0xFD81
#define KEY_MODE      0xFD82
#define KEY_WIND      0xFD84
#define KEY_TIMER     0xFD88
#define KEY_SWING     0xFD90
#define KEY_LIGHT     0xFDC3

// 定義數(shù)碼管段碼
unsigned char code SEGMENT[] = {
    0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
    0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71,
    0x08, 0x48, 0x49, 0x76
};

// 全局變量
bit fanOn = 0;             // 風(fēng)扇開關(guān)狀態(tài)
unsigned char fanSpeed = 0; // 風(fēng)扇速度
bit fanSwing = 0;          // 風(fēng)扇搖頭狀態(tài)
bit fanLight = 0;          // 風(fēng)扇彩燈狀態(tài)
unsigned int fanTimer = 0; // 風(fēng)扇定時(shí)器

// 延時(shí)函數(shù)
void delayms(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++) {
        for (j = 0; j < 1000; j++);
    }
}

// 數(shù)碼管顯示函數(shù)
void display(unsigned char digit) {
    unsigned char segment = SEGMENT[digit];
    P1 = segment;
}

// 控制風(fēng)扇函數(shù)
void controlFan() {
    // 根據(jù)風(fēng)扇狀態(tài)進(jìn)行相應(yīng)操作
    if (fanOn) {
        // 控制風(fēng)扇開關(guān)
        P3 &= 0xF8;
        P3 |= fanSpeed;
        // 控制風(fēng)扇搖頭
        P1 &= 0xDF;
        P1 |= (fanSwing << 5);
        // 控制風(fēng)扇彩燈
        P5 &= 0xDF;
        P5 |= (fanLight << 5);
    } else {
        // 關(guān)閉風(fēng)扇
        P3 &= 0xF8;
    }
}

// 外部中斷1中斷服務(wù)函數(shù)
void int1() interrupt 2 {
    // 延時(shí)一段時(shí)間,避免按鍵抖動(dòng)
    delayms(10);
    if (P3_2 == 0) { // 檢測外部中斷1觸發(fā)
        // 解碼鍵值
        unsigned int keyValue = (P1 << 8) | P0;
        
        // 根據(jù)鍵值執(zhí)行相應(yīng)操作
        switch (keyValue) {
            case KEY_POWER:
                fanOn = !fanOn; // 切換風(fēng)扇開關(guān)狀態(tài)
                break;
            case KEY_MODE:
                fanSpeed++; // 切換風(fēng)扇速度
                if (fanSpeed > 3) {
                    fanSpeed = 0;
                }
                break;
            case KEY_WIND:
                fan

作者: 玉萌業(yè)余發(fā)展    時(shí)間: 2023-5-24 16:06
123456ZXC1 發(fā)表于 2023-5-24 12:27
先給你來一段
#include "STC8G.h"

嗯。還行,有點(diǎn)邏輯性
作者: 桔妄    時(shí)間: 2023-5-25 23:36
配合原理圖調(diào)試?yán)砬,?huì)好些吧

作者: liucan2020    時(shí)間: 2023-5-26 17:06
能實(shí)現(xiàn)功能就是一大步,其它的慢慢累積,多看、多練再過段時(shí)間會(huì)頭看一下,就會(huì)發(fā)現(xiàn)很多問題

作者: 玉萌業(yè)余發(fā)展    時(shí)間: 2023-5-28 09:54
liucan2020 發(fā)表于 2023-5-26 17:06
能實(shí)現(xiàn)功能就是一大步,其它的慢慢累積,多看、多練再過段時(shí)間會(huì)頭看一下,就會(huì)發(fā)現(xiàn)很多問題

牛逼!這就是成功的奧秘。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1