久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2104|回復: 11
收起左側

單片機遙控風扇控制程序,望大師優化

[復制鏈接]
回帖獎勵 90 黑幣 回復本帖可獲得 3 黑幣獎勵! 每人限 1 次
ID:796012 發表于 2023-5-23 14:07 | 顯示全部樓層 |閱讀模式
  1. /*風扇遙控芯片:BA5104  紅外遙控解碼程序  晶振頻率:11.0592MHZ  1幀12位,一次至少發2幀*//*歷時8天成功調試,干擾碼直接清零,只顯示相關鍵值*/
  2. /*解碼后的鍵值:關機 0xfd81; 開/風速 0xfd82; 風類 0xfd84; 定時 0xfd88; 搖頭 0xfd90; 彩燈 0xfdc3; 無 0xfda0; 無 0xfdc6*/
  3. #include "STC8G.h"/*單片機:STC8G1K08-TSSOP20*//*紅外端口:P33(包含外部中斷1,改端口時要注意)*/
  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--);}/*延時函數*/void int1init(){PX1=1;/*設置中斷優先級*/IT1=1;EX1=1;EA=1;}/*外部中斷1初始化函數,設置成下降沿觸發*/
  7. void d0init()/*定時器0 1微秒@11.0592MHz*/
  8. {AUXR |= 0x80;/*定時器時鐘1T模式*/TMOD &= 0xF0;/*設置定時器模式*/TL0 = 0xF5;/*設置定時初始值*/TH0 = 0xFF;/*設置定時初始值*/TF0 = 0;/*清除TF0標志*/TR0 = 0;/*定時器0先不計時*/}
  9. void d1init()/*定時器1初始化函數*/{AUXR |= 0x40;/*1T*/TMOD &= 0x0F;TL1 = 0x70;/*初始值*/TH1 = 0xFF;/*初始值*/TF1 = 0;/*清除TF1標志*/TR1=0;/*先不啟動*/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);}} /*風類*/
  16.   if(P13==0){delayms(5);if(P13==0){m=0xfd81;buz=1;while(!P13);}} /*關機*/
  17.         if(P14==0){delayms(5);if(P14==0){m=0xfd88;buz=1;while(!P14);}} /*定時*/
  18.         if(P15==0){delayms(5);if(P15==0){m=0xfd82;buz=1;while(!P15);}} /*開/風速*/
  19.         P1=0x00;
  20. }
  21. void display()/*數碼管掃描*/
  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;  /*個位*/
  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];/*個位*/
  36.                 if(yt==1){P1=dm[g]+0x80;}}
  37.           if(P33==1){delayms(50);}       /*間隔一段時間掃描*/
  38.           P1=0x00;          /*消隱*/
  39.         }
  40. }
  41. void ircl()      /*紅外時間記錄*/
  42. {
  43.         unsigned char c1;
  44.         if(!P33)
  45.         {
  46.     d1=0;
  47.     TR1=1;       /*啟動定時器1*/
  48.     while(!P33);
  49.     TR1=0;
  50.     ir[j]=d1;
  51.         }              /*編碼位置清零*/                    
  52.   if(P33==1&&j>0)/*當端口高電平時,編碼位置還未清零*/
  53.         {
  54.     c1++;        /*計算一下持續時間*/
  55.    if(c1>250)    /*超過一定的時間*/
  56.   {
  57.     c++;c1=0;
  58.   }
  59.          if(c>5)       /*就要再次按遙控按鍵*/
  60.   {
  61.           j=0;c=0;     /*如果還有干擾碼就直接清零*/
  62.         }                     
  63.         }
  64. }
  65. void kzhs()/*鍵值控制函數 包含主板按鍵和紅外遙控按鍵*/
  66. {
  67.         unsigned char fl,zd;
  68.         if(on==1&cd==1){display();/*開數碼管*/}
  69.         if(on==1&m==0xfd81){fl=0;on=0;dw=0;zd=0;se=0;ds=0;TR0=0;cd=0;j=0;}/*關機狀態*/
  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;}/*開機狀態*/
  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.         /*定時控制函數*//*8.0小時=480分鐘=28800秒  999秒=16.65分鐘=0.2775小時*/
  77.         if(ds>999){g=19;s=ds/60/6%10;b=ds/60/60;}/*g位顯示H,s顯示10進制的分鐘,b顯示小時加小數點*/
  78.         if(ds<999){g=ds%10;s=ds/10%10;b=ds/100%10;/*q=ds/1000%10;*/}/*顯示剩余秒數*/
  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類自然風:高速運轉10秒,中速運轉10秒,低速運轉10秒;進入循環*/
  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類睡眠風:高速轉10分鐘,中速轉30分鐘;之后退出睡眠模式,返回長風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;}/*彩燈開關,關機后單顯示電壓,開機后定時和電壓切換顯示*/
  86.         if(ds!=0&c==0){ET0=1;}/*定時打開時,檢測有無紅外信號*/if(se!=0&c==0){ET0=1;}/*自動風打開時,檢測有無紅外信號*/
  87. }
  88. void fmq()/*蜂鳴器*/
  89. {
  90.                 if(off==0&buz>0)
  91.           {        
  92.             buz++;
  93.                   P54=0;        
  94.           }
  95.           if(buz>800)/*延時*/
  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()/*定時器0初始化*/;d1init();/*定時器1初始化*/int1init();/*外部中斷1初始化*/
  111.         buz=1;fmq();/*上電蜂鳴器響一聲*/
  112.         while(1)
  113.         {
  114.                 ircl();
  115.                 kayscan();
  116.                 kzhs();
  117.                 fmq();
  118.         }
  119. }
  120. /*傳統51單片機具有5個中斷源,中斷優先級從高到低依次是:外部中斷0(interrupt0)、定時器0(interrupt1)、外部中斷1(interrupt2)、定時器1(interrupt3)和串口中斷(interrupt4)。*/
  121. void dsq0() interrupt 1
  122. {
  123.         unsigned int ms,tu,tm;
  124.         tu=965;          /*調整微秒,建議:965*/
  125.         tm=99;           /*毫秒調整,建議:99*/
  126.   d0=d0++;         /*每約1微秒加1*/
  127.         if(buz>0)
  128.         {        
  129.           buz++;
  130.                 P54=0;        
  131.   }
  132.         if(buz>800)      /*延時*/
  133.         {
  134.                 P54=1;
  135.                 buz=0;
  136.         }
  137.         if(!P33)         /*檢測到紅外信號*/
  138.         {
  139.                 ET0=0;         /*返回主程序*/
  140.         }
  141.         if(d0>tu)        /*受紅外信號檢測影響,建議199*/
  142.         {
  143.                 ms++;          /*每約1000微秒=1毫秒*/
  144.                 d0=0;          /*us清零*/
  145.         }
  146.         if(ms>tm/2)      /*每約0.5秒*/
  147.         {
  148.           sm=0;          /*關閉閃秒*/
  149.         }
  150.         if(ms>tm)        /*每約1000毫秒=1秒 參考值:19*/
  151.         {
  152.                 if(ds>0)                        
  153.      {
  154.                  ds--;         /*定時秒數自減*/
  155.                  }            
  156.                  se++;
  157.                  sm=1;         /*點亮閃秒*/
  158.                 if(gj==1&ds==0)/*允許關機,定時時間到了*/
  159.                 {
  160.                         m=0xfd81;    /*送出關機指令*/
  161.                         gj=0;
  162.                 }
  163.                 ms=0;          /*毫秒清零*/
  164.         }
  165. }
  166. void int1() interrupt 2 /*外部中斷1服務函數,低電平觸發*//*受遙控中斷影響,不夠時間處理編碼,記錄時間不放在這函數*/
  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;              /*啟動蜂鳴器*/
  187.         }
  188.         else
  189.         {
  190.                 m=0;                /*干擾碼清零*/
  191.         }
  192.         if(j>12&m==0){j=0;}   /*如果大于12位了,編碼還不正確,就把位置清零,防止下一幀亂碼*/
  193. }
  194. void dsqi() interrupt 3 /*定時器1 中斷服務函數,每約13微秒中斷1次*/{d1++;/*每約13微秒加1*/}
復制代碼
回復

使用道具 舉報

ID:796012 發表于 2023-5-28 09:54 | 顯示全部樓層
liucan2020 發表于 2023-5-26 17:06
能實現功能就是一大步,其它的慢慢累積,多看、多練再過段時間會頭看一下,就會發現很多問題

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

使用道具 舉報

ID:1040201 發表于 2023-5-26 17:06 | 顯示全部樓層
能實現功能就是一大步,其它的慢慢累積,多看、多練再過段時間會頭看一下,就會發現很多問題
回復

使用道具 舉報

ID:1079725 發表于 2023-5-25 23:36 | 顯示全部樓層
配合原理圖調試理清,會好些吧
回復

使用道具 舉報

ID:796012 發表于 2023-5-24 16:06 | 顯示全部樓層
123456ZXC1 發表于 2023-5-24 12:27
先給你來一段
#include "STC8G.h"

嗯。還行,有點邏輯性
回復

使用道具 舉報

ID:526543 發表于 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

// 定義數碼管段碼
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;             // 風扇開關狀態
unsigned char fanSpeed = 0; // 風扇速度
bit fanSwing = 0;          // 風扇搖頭狀態
bit fanLight = 0;          // 風扇彩燈狀態
unsigned int fanTimer = 0; // 風扇定時器

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

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

// 控制風扇函數
void controlFan() {
    // 根據風扇狀態進行相應操作
    if (fanOn) {
        // 控制風扇開關
        P3 &= 0xF8;
        P3 |= fanSpeed;
        // 控制風扇搖頭
        P1 &= 0xDF;
        P1 |= (fanSwing << 5);
        // 控制風扇彩燈
        P5 &= 0xDF;
        P5 |= (fanLight << 5);
    } else {
        // 關閉風扇
        P3 &= 0xF8;
    }
}

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

使用道具 舉報

ID:796012 發表于 2023-5-24 12:22 | 顯示全部樓層
yzwzfyz 發表于 2023-5-24 11:23
不要急于寫程序。先規劃一下方案。
再出個程序流程圖,先走通流程圖而后再寫程序。
如沙發提出的問題,你 ...

嗯嗯。專業的手法就是不一樣。
回復

使用道具 舉報

ID:796012 發表于 2023-5-24 12:21 | 顯示全部樓層
xuyaqi 發表于 2023-5-23 16:09
你13微秒中斷1次,造成cpu一直不停處理中斷,根本沒時間干別的,定時器1 應該有一個合理中斷時間間隔。

試了,剛好可以識別紅外信號
回復

使用道具 舉報

ID:796012 發表于 2023-5-24 12:21 | 顯示全部樓層
123156fsadf 發表于 2023-5-23 17:06
1、代碼沒對齊,風格較差
2、中斷中代碼過長,可能導致下個中斷進來了都沒處理完
3、51的棧空間太小,不 ...

謝謝建議。我這是業余愛好的
回復

使用道具 舉報

ID:123289 發表于 2023-5-24 11:23 | 顯示全部樓層
不要急于寫程序。先規劃一下方案。
再出個程序流程圖,先走通流程圖而后再寫程序。
如沙發提出的問題,你如果規劃過方案,就不犯。
例如:列出風扇的功能,一個給出實現的方式。切換的方法,條件,檢測的方式,顯示的方式……。
這此都在事先做規劃。至少羅列于EXCEL表中吧。

評分

參與人數 1黑幣 +5 收起 理由
yueguang3048 + 5 很給力!

查看全部評分

回復

使用道具 舉報

ID:744809 發表于 2023-5-23 17:06 | 顯示全部樓層
1、代碼沒對齊,風格較差
2、中斷中代碼過長,可能導致下個中斷進來了都沒處理完
3、51的棧空間太小,不建議中斷太多代碼
4、函數名太短,且為拼音首字母,難以理解
5、中斷間隔太短了
回復

使用道具 舉報

ID:94031 發表于 2023-5-23 16:09 | 顯示全部樓層
你13微秒中斷1次,造成cpu一直不停處理中斷,根本沒時間干別的,定時器1 應該有一個合理中斷時間間隔。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文在线一区 | 亚洲一区二区视频 | 精品日韩一区二区三区av动图 | 色综合色综合色综合 | 色婷婷在线视频 | 国产亚洲精品久久久优势 | 视频一区二区三区在线观看 | 久久久男人的天堂 | 91精品综合久久久久久五月天 | 久久丝袜| 国产欧美一区二区三区在线看 | 国产美女h视频 | 国产中文字幕在线观看 | 日本三级电影在线看 | 浮生影院免费观看中文版 | 日本粉嫩一区二区三区视频 | 欧美日韩看片 | 亚洲一区久久 | 精品一区二区电影 | 日韩av三区 | 日韩a | 久热精品在线播放 | 欧美成人精品激情在线观看 | 国产综合精品一区二区三区 | 亚洲精选久久 | 黄网站涩免费蜜桃网站 | 欧美国产中文字幕 | 日韩三级视频 | 看一级毛片视频 | 久久福利电影 | 日本午夜网站 | 国产一区在线免费 | 最近中文字幕免费 | 91久久国产综合久久91精品网站 | 精品一区av | 视频一区在线 | 国产伦精品一区二区三区四区视频 | 欧美一区2区三区3区公司 | 91精品久久久久久久久中文字幕 | 91传媒在线观看 | 午夜精品在线观看 |