標(biāo)題: 單片機(jī)紅外遙控跟獨(dú)立按鍵怎樣實(shí)現(xiàn)同樣的功能? [打印本頁]

作者: 修羅_戰(zhàn)    時(shí)間: 2022-6-10 14:03
標(biāo)題: 單片機(jī)紅外遙控跟獨(dú)立按鍵怎樣實(shí)現(xiàn)同樣的功能?
請教一下各位大佬,我想要紅外遙控跟一個(gè)獨(dú)立按鍵實(shí)現(xiàn)同樣的功能,但是不會(huì)整合。下面的代碼單獨(dú)使用紅外遙控或者獨(dú)立按鍵都能正常切換功能,但是整合到一起就不會(huì)了。本人初學(xué)者軟件寫的有點(diǎn)亂,望大佬們指點(diǎn)一二。

謝謝
  1. #include <reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. unsigned char irtime;//紅外用全局變量
  5. bit irpro_ok,irok;
  6. unsigned char IRcord[4];//用來存放用戶碼、用戶反碼、數(shù)據(jù)碼、數(shù)據(jù)反碼
  7. unsigned char irdata[33];//用來存放32位碼值

  8. typedef unsigned char u8;
  9. typedef unsigned int u16;

  10. u16 mode;

  11. sbit key = P3^4;

  12. void delay(u16 i)
  13. {
  14.         while(i--);
  15. }

  16. void tim0_isr()interrupt 1  //定時(shí)器0中斷服務(wù)函數(shù)
  17. {
  18.         irtime++;
  19. }

  20. void ex0_isr()interrupt 0   //外部中斷0服務(wù)函數(shù)
  21. {
  22.         static unsigned char i;
  23.         static bit startflag;
  24.         if(startflag)
  25.         {
  26.                 if(irtime<53&&irtime>=32)
  27.                 i=0;
  28.                 irdata[ i]=irtime;[ i]
  29.                 irtime=0;
  30.                 i++;
  31.                 if(i==33)
  32.                 {
  33.                         irok=1;
  34.                         i=0;
  35.                 }
  36.         }
  37.         else
  38.         {
  39.                 irtime=0;
  40.                 startflag=1;                        
  41.         }
  42. }

  43. void TIM0init()//定時(shí)器0初始化
  44. {
  45.         TMOD=0x02;//定時(shí)器0工作方式2,TH0是重裝值,TL0是初值
  46.         TH0=0x00;
  47.         TL0=0x00;
  48.                 EA=1;
  49.         ET0=1;//開總中斷
  50.         TR0=1;

  51.         IT0=1;
  52.         EX0=1;

  53. }
  54. void Ircordpro()//紅外碼值處理函數(shù)(關(guān)鍵函數(shù))
  55. {
  56.         unsigned char i,j,k=1;
  57.         unsigned char cord,value;

  58.         for(i=0;i<4;i++)                //處理4個(gè)字節(jié)
  59.         {
  60.                 for(j=1;j<=8;j++)         //處理1個(gè)字節(jié)8位
  61.                 {
  62.                         cord=irdata[k];
  63.                         value=value>>1;
  64.                         if(cord>7)value=value|0x80;//大于某值為1
  65.                         k++;
  66.                 }
  67.                 IRcord[ i]=value;[ i]
  68.                 value=0;
  69.         }
  70.         irpro_ok=1;//處理完畢標(biāo)志位置1
  71. }

  72. void Key()                          //按鍵
  73. {
  74.         if(key==0)
  75.         {
  76.                 delay(1000);
  77.                 if(key==0)
  78.                 {
  79.                         mode++;
  80.                         if(mode==8)
  81.                         {
  82.                                 mode=0;
  83.                         }
  84.                         while(!key);
  85.                 }
  86.         }
  87. }

  88. void IR_LED()
  89. {
  90.         if(irok)
  91.         {                        
  92.                 Ircordpro();
  93.                 irok=0;
  94.         }
  95.         if(irpro_ok)//遙控成功接收
  96.         {                        
  97.                 switch(IRcord[2])
  98.                 {        
  99.                         case 0x04:P1 = 0x01; break;      //打開紅色LED
  100.                         case 0x05:P1 = 0x02; break;      //打開綠色LED
  101.                         case 0x06:P1 = 0x04; break;      //打開藍(lán)色LED
  102.                         case 0x07:P1 = 0x07; break;      //打開白色LED
  103.                         case 0x08:P1 = 0x03; break;      //打開紅綠色LED
  104.                         case 0x09:P1 = 0x05; break;      //打開紅藍(lán)色LED
  105.                         case 0x0a:P1 = 0x06; break;      //打開綠藍(lán)色LED
  106.                 }
  107.         }
  108. }

  109. void main()
  110. {        
  111.         TIM0init();
  112.         while(1)
  113.         {        
  114.                 Key();
  115.                 IR_LED();
  116.         }
  117. }        

復(fù)制代碼



作者: lkc8210    時(shí)間: 2022-6-10 15:52
  1. #include <reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. unsigned char irtime;//紅外用全局變量
  5. bit irpro_ok,irok;
  6. bit key_ok;//<<<<<<<<<<<<<<<<<<<<<<<<<<<
  7. unsigned char IRcord[4];//用來存放用戶碼、用戶反碼、數(shù)據(jù)碼、數(shù)據(jù)反碼
  8. unsigned char irdata[33];//用來存放32位碼值

  9. typedef unsigned char u8;
  10. typedef unsigned int u16;

  11. u16 mode;

  12. sbit key = P3^4;

  13. void delay(u16 i)
  14. {
  15.         while(i--);
  16. }

  17. void tim0_isr()interrupt 1  //定時(shí)器0中斷服務(wù)函數(shù)
  18. {
  19.         irtime++;
  20. }

  21. void ex0_isr()interrupt 0   //外部中斷0服務(wù)函數(shù)
  22. {
  23.         static unsigned char i;
  24.         static bit startflag;
  25.         if(startflag)
  26.         {
  27.                 if(irtime<53&&irtime>=32)
  28.                         i=0;
  29.                 irdata[ i]=irtime;
  30.                 [ i]
  31.                 irtime=0;
  32.                 i++;
  33.                 if(i==33)
  34.                 {
  35.                         irok=1;
  36.                         i=0;
  37.                 }
  38.         }
  39.         else
  40.         {
  41.                 irtime=0;
  42.                 startflag=1;
  43.         }
  44. }

  45. void TIM0init()//定時(shí)器0初始化
  46. {
  47.         TMOD=0x02;//定時(shí)器0工作方式2,TH0是重裝值,TL0是初值
  48.         TH0=0x00;
  49.         TL0=0x00;
  50.         EA=1;
  51.         ET0=1;//開總中斷
  52.         TR0=1;

  53.         IT0=1;
  54.         EX0=1;

  55. }
  56. void Ircordpro()//紅外碼值處理函數(shù)(關(guān)鍵函數(shù))
  57. {
  58.         unsigned char i,j,k=1;
  59.         unsigned char cord,value;

  60.         for(i=0; i<4; i++)              //處理4個(gè)字節(jié)
  61.         {
  62.                 for(j=1; j<=8; j++)       //處理1個(gè)字節(jié)8位
  63.                 {
  64.                         cord=irdata[k];
  65.                         value=value>>1;
  66.                         if(cord>7)value=value|0x80;//大于某值為1
  67.                         k++;
  68.                 }
  69.                 IRcord[ i]=value;
  70.                 [ i]
  71.                 value=0;
  72.         }
  73.         irpro_ok=1;//處理完畢標(biāo)志位置1
  74. }

  75. void Key()                          //按鍵
  76. {
  77.         if(key==0)
  78.         {
  79.                 delay(1000);
  80.                 if(key==0)
  81.                 {
  82.                         key_ok = 1;//<<<<<<<<<<<<<<<<<<<<<<<<<<<
  83.                         mode++;
  84.                         if(mode==8)
  85.                         {
  86.                                 mode=0;
  87.                         }
  88.                         while(!key);
  89.                 }
  90.         }
  91. }

  92. void IR_LED()
  93. {
  94.         if(irok)
  95.         {
  96.                 Ircordpro();
  97.                 irok=0;
  98.         }
  99. }
  100. void Led_Control()//<<<<<<<<<<<<<<<<<<<<<<<<<<<
  101. {
  102.         static u8 Temp = 0;
  103.         if(irpro_ok)
  104.         {
  105.                 irpro_ok = 0;
  106.                 Temp = IRcord[2];
  107.         }
  108.         if(key_ok)
  109.         {
  110.                 key_ok = 0;
  111.                 Temp = mode+4;
  112.         }
  113.         switch(Temp)
  114.         {
  115.                 case 0x04:P1 = 0x01; break;      //打開紅色LED
  116.                 case 0x05:P1 = 0x02; break;      //打開綠色LED
  117.                 case 0x06:P1 = 0x04; break;      //打開藍(lán)色LED
  118.                 case 0x07:P1 = 0x07; break;      //打開白色LED
  119.                 case 0x08:P1 = 0x03; break;      //打開紅綠色LED
  120.                 case 0x09:P1 = 0x05; break;      //打開紅藍(lán)色LED
  121.                 case 0x0a:P1 = 0x06; break;      //打開綠藍(lán)色LED
  122.                 default:break;
  123.         }
  124. }
  125. void main()
  126. {
  127.         TIM0init();
  128.         while(1)
  129.         {
  130.                 Key();
  131.                 IR_LED();
  132.                 Led_Control();//<<<<<<<<<<<<<<<<<<<<<<<<<<<
  133.         }
  134. }

復(fù)制代碼



作者: wulin    時(shí)間: 2022-6-10 16:27
兩者能對同一個(gè)變量控制就整合到一起了。
作者: 修羅_戰(zhàn)    時(shí)間: 2022-6-10 17:22
wulin 發(fā)表于 2022-6-10 16:27
兩者能對同一個(gè)變量控制就整合到一起了。

就是不知道如何控制,能否給個(gè)示例呢。
作者: 修羅_戰(zhàn)    時(shí)間: 2022-6-10 23:46
lkc8210 發(fā)表于 2022-6-10 15:52

感謝大佬,還有個(gè)問題請教一下。按照你的代碼下載進(jìn)去之后發(fā)現(xiàn)上電時(shí)按下按鍵第一次的時(shí)候直接跳過第一個(gè)“case 0x04:P1 = 0x01; break;      //打開紅色LED”直接從第二行“case 0x05:P1 = 0x02; break;      //打開綠色LED”開始執(zhí)行。當(dāng)case循環(huán)一周之后就又正常了。
作者: lkc8210    時(shí)間: 2022-6-11 17:37
修羅_戰(zhàn) 發(fā)表于 2022-6-10 23:46
感謝大佬,還有個(gè)問題請教一下。按照你的代碼下載進(jìn)去之后發(fā)現(xiàn)上電時(shí)按下按鍵第一次的時(shí)候直接跳過第一個(gè) ...

大問題已幫你解決了
小問題就當(dāng)是功課吧~
作者: 修羅_戰(zhàn)    時(shí)間: 2022-6-16 18:31
lkc8210 發(fā)表于 2022-6-11 17:37
大問題已幫你解決了
小問題就當(dāng)是功課吧~

謝謝大佬,我把按鍵功能做到void Led_Control()里面問題解決了。

void Led_Control()//<<<<<<<<<<<<<<<<<<<<<<<<<<<
{
        static u8 Temp = 0;
        if(irok)
    {
        Ircordpro();
        irok=0;
    }
    if(irpro_ok)
    {
                irpro_ok = 0;
                Temp = IRcord[2];
    }
    if(key_ok)
    {
        key_ok = 0;
        Temp = mode+4;
                mode++;                          //*****************
                if(mode == 8)          //******************
                {                                  //*********************
                        mode = 0;          //************************
                }                                  //*****************

    }   
    switch(Temp)
    {
        case 0x04:P1 = 0x01; break;      //打開紅色LED
        case 0x05:P1 = 0x02; break;      //打開綠色LED
        case 0x06:P1 = 0x04; break;      //打開藍(lán)色LED
        case 0x07:P1 = 0x07; break;      //打開白色LED
        case 0x08:P1 = 0x03; break;      //打開紅綠色LED
        case 0x09:P1 = 0x05; break;      //打開紅藍(lán)色LED
        case 0x0a:P1 = 0x06; break;      //打開綠藍(lán)色LED
                case 0x0b:LED_R(); break;        //打開紅色LED呼吸
        default:break;
    }
}
作者: 修羅_戰(zhàn)    時(shí)間: 2022-6-16 18:38
lkc8210 發(fā)表于 2022-6-11 17:37
大問題已幫你解決了
小問題就當(dāng)是功課吧~

但是我又有個(gè)疑惑,現(xiàn)在的按鍵功能是按循序依次往下實(shí)行的。比如
case 0x04: ................;break;
case 0x05: ................;break;
case 0x06: ................;break;
case 0x07: ................;break;
case 0x08: ................;break;
按循序依次往上+1,那么如果我0x05這行去掉之后按鍵就會(huì)空按一下才能跳到0x06這一行。這個(gè)又改怎樣做呢
大佬有空能否幫忙解答一下,謝謝
作者: lkc8210    時(shí)間: 2022-6-16 21:17
修羅_戰(zhàn) 發(fā)表于 2022-6-16 18:38
但是我又有個(gè)疑惑,現(xiàn)在的按鍵功能是按循序依次往下實(shí)行的。比如
case 0x04: ................;break;
...

case 0x04: ................;break;
case 0x05: Temp=0x06; mode = 2; break;
case 0x06: ................;break;
case 0x07: ................;break;
case 0x08: ................;break;
簡單粗爆
作者: kmsj    時(shí)間: 2022-6-16 22:30
太亂了,基本上一點(diǎn)思路都沒有,最近我可能也要編類似的程序,想想沒有什么難度啊,板凳的說法是對的,兩者能對同一個(gè)變量控制就整合到一起了?上睦镉姓希炕揪幊趟悸,按鍵去抖動(dòng)得到穩(wěn)定鍵值,紅外接收得到穩(wěn)定鍵值,這兩個(gè)鍵值共用一個(gè)全局變量,比如叫做key_ok,if(key_ok==某鍵值){key_ok=0;操作1;操作2},最關(guān)鍵就是查詢到一個(gè)穩(wěn)定鍵值之后,穩(wěn)定鍵值一定要清零,然后執(zhí)行相應(yīng)的操作,這就要求按鍵去抖動(dòng)和紅外接收要相當(dāng)可靠,剩下的操作就簡單了,if語句太多可改為switch語句就完事了。
作者: 修羅_戰(zhàn)    時(shí)間: 2022-6-17 09:59
lkc8210 發(fā)表于 2022-6-16 21:17
case 0x04: ................;break;
case 0x05: Temp=0x06; mode = 2; break;
case 0x06: ......... ...

非常感謝大佬的指點(diǎn),這樣做之后按鍵是正常的了?墒窃诩t外遙控上面0x05跟0x06就同時(shí)控制一個(gè)功能了
作者: 單片機(jī)學(xué)習(xí)習(xí)    時(shí)間: 2022-7-8 18:46
遙控某個(gè)鍵用A代表,獨(dú)立某個(gè)按鍵用B代表,if{(A==0x11)||(B==0)}{BEEP=0;}這樣簡單實(shí)現(xiàn)遙控和按鍵,A.B無論誰按下都能,控制蜂鳴器




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