找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 140608|回復(fù): 55
收起左側(cè)

單片機(jī)紅外遙控原理及程序(非常詳細(xì))

  [復(fù)制鏈接]
ID:100029 發(fā)表于 2015-12-22 21:43 | 顯示全部樓層 |閱讀模式

應(yīng)該說(shuō)現(xiàn)在每一塊開(kāi)發(fā)板都帶有紅外模塊,并且大都配置了相應(yīng)的程序。但其實(shí)自己動(dòng)手寫解碼程序,更能鍛煉自己所學(xué),且不談程序?qū)懙娜绾,這個(gè)過(guò)程中肯定是受益良多的,F(xiàn)在我就把我花一下午寫出的解碼程序與大家分享,期待高手的光臨指正。

首先,必須要了解一些基本原理。其實(shí)按下遙控器的某一個(gè)鍵,遙控器會(huì)發(fā)出一連串經(jīng)過(guò)調(diào)制后的信號(hào),這個(gè)信號(hào)經(jīng)過(guò)紅外一體化模塊接收后,輸出解調(diào)后的數(shù)字脈沖,每個(gè)按鍵對(duì)應(yīng)不同的脈沖,故識(shí)別出不同的脈沖就能識(shí)別出不同的按鍵。

上圖就是很常見(jiàn)的車載MP3遙控器,比較小巧,很好用。下面是紅外發(fā)射和接受原理:

到此讀者可能會(huì)有疑惑,那么不同的調(diào)制解調(diào)方法那么出來(lái)的脈沖規(guī)則是不一樣的?是的,的確如此。

遙控發(fā)射器專用芯片很多,根據(jù)編碼格式可以分成兩大類,這里我們以運(yùn)用比較廣泛,解碼比較容易的一類來(lái)加以說(shuō)明,現(xiàn)以日本NEC的uPD6121G組成發(fā)射電路為例說(shuō)明編碼原理(一般家庭用的DVD、VCD、音響都使用這種編碼方式)。當(dāng)發(fā)射器按鍵按下后,即有遙控碼發(fā)出,所按的鍵不同遙控編碼也不同。這種遙控碼具有以下特征:

       采用脈寬調(diào)制的串行碼,以脈寬為0.565ms、間隔0.56ms、周期為1.125ms的組合表示二進(jìn)制的“0”;以脈寬為0.565ms、間隔1.685ms、周期為2.25ms的組合表示二進(jìn)制的“1”,其波形如圖所示。

如圖可見(jiàn),0與1前端的低電平持續(xù)都是0.56ms,那么就是后面的高電平持續(xù)時(shí)間不同,0為0.56ms,1為1.685ms,找到不同之處,編程時(shí)就有識(shí)別的依據(jù)了!

上述“0”和“1”組成的32位二進(jìn)制碼經(jīng)38kHz的載頻進(jìn)行二次調(diào)制以提高發(fā)射效率,達(dá)到降低電源功耗的目的。然后再通過(guò)紅外發(fā)射二極管產(chǎn)生紅外線向空間發(fā)射,如圖所示。

UPD6121G產(chǎn)生的遙控編碼是連續(xù)的32位二進(jìn)制碼組,其中前16位為用戶識(shí)別碼,能區(qū)別不同的電器設(shè)備,防止不同機(jī)種遙控碼互相干擾。該芯片的用戶識(shí)別碼固定為十六進(jìn)制01H;后16位為8位操作碼(功能碼)及其反碼。UPD6121G最多額128種不同組合的編碼。

請(qǐng)看下圖,來(lái)自網(wǎng)絡(luò):



當(dāng)一個(gè)鍵按下超過(guò)36ms,振蕩器使芯片激活,將發(fā)射一組108ms的編碼脈沖,這108ms發(fā)射代碼由一個(gè)引導(dǎo)碼(9ms),一個(gè)結(jié)果碼(4.5ms),低8位地址碼(9ms~18ms),高8位地址碼(9ms~18ms),8位數(shù)據(jù)碼(9ms~18ms)和這8位數(shù)據(jù)的反碼(9ms~18ms)組成。如果鍵按下超過(guò)108ms仍未松開(kāi),接下來(lái)發(fā)射的代碼(連發(fā)碼)將僅由起始碼(9ms)和結(jié)束碼(2.25ms)組成。(實(shí)際上人手的動(dòng)作是很慢的,即使你快速的按下按鍵,可能對(duì)于芯片來(lái)說(shuō)還是超過(guò)108ms,所以如何處理連發(fā)碼是很關(guān)鍵的)

遙控器在按鍵按下后,周期性地發(fā)出同一種32位二進(jìn)制碼,周期約為108ms。一組碼本身的持續(xù)時(shí)間隨它包含的二進(jìn)制“0”和“1”的個(gè)數(shù)不同而不同,大約在45~63ms之間,圖為發(fā)射波形圖。

 

下面是我寫的代碼,按鍵編碼通過(guò)串口發(fā)送到電腦端:

由于時(shí)間關(guān)系,代碼注釋不多。

其中START_Judge()函數(shù)是判斷9ms低電平,既是判斷有無(wú)遙控信號(hào)。

BOOT_REPEATING_CODE_Judge()是判斷是引導(dǎo)碼還是連發(fā)碼,引導(dǎo)碼則進(jìn)入接受數(shù)據(jù)環(huán)節(jié),連發(fā)碼表明數(shù)據(jù)已經(jīng)接受結(jié)束。

H_L_LEVEL_Judge()是接受數(shù)據(jù)時(shí)判斷高低電平。

如果亂碼,請(qǐng)參考:


注明:以下代碼為純軟件方式,沒(méi)有用到中斷,定時(shí)器方式,純CPU查詢,但測(cè)試結(jié)果倒也可以,至少比較穩(wěn)定,得到的碼值不管對(duì)不對(duì),都是那個(gè)值。

[cpp] view plaincopy
  1. /*------------------------------------------------------------*- 
  2.   紅外收發(fā).C 
  3.   ------------------------------------------------------------ 
  4.   遙控器測(cè)試 
  5. -*------------------------------------------------------------*/  
  6.   
  7. #include <reg52.h>  
  8.   
  9. // --- 紅外接收一體化輸出口 ----------------------------------  
  10. sbit IR_Out = P3^2;  
  11.   
  12. bit START_Flag = 0;  
  13. bit BOOT_REPEATING_CODE_Flag = 0;  
  14. unsigned char DATA[4] = {0};  
  15. bdata unsigned char TEMP_BIT;  
  16.   
  17. sbit B0 = TEMP_BIT^0;  
  18. sbit B1 = TEMP_BIT^1;  
  19. sbit B2 = TEMP_BIT^2;  
  20. sbit B3 = TEMP_BIT^3;  
  21. sbit B4 = TEMP_BIT^4;  
  22. sbit B5 = TEMP_BIT^5;  
  23. sbit B6 = TEMP_BIT^6;  
  24. sbit B7 = TEMP_BIT^7;  
  25.   
  26. // --- 有無(wú)遙控信號(hào)判斷函數(shù) ----------------------------------  
  27. bit START_Judge();  
  28.   
  29. // --- 連發(fā)碼判斷函數(shù) ----------------------------------------  
  30. bit BOOT_REPEATING_CODE_Judge();  
  31.   
  32. // --- "0"和"1"識(shí)別 ------------------------------------------  
  33. bit H_L_LEVEL_Judge();  
  34.   
  35. // --- 串口初始化 --------------------------------------------  
  36. void UART_Initial();  
  37.   
  38. void DELAY_Us(unsigned int Us)  
  39. {  
  40.     unsigned int x;  
  41.     for(x = 0; x <= (Us/200-1); x++);  
  42. }  
  43. void DELAY_Ms(unsigned int Ms)  
  44. {  
  45.     unsigned int x,y;  
  46.     for(x = 0; x <= (Ms-1); x++)  
  47.     {  
  48.         for(y = 0; y <= 120; y++);  
  49.     }  
  50. }  
  51.   
  52. void main()  
  53. {  
  54.     unsigned char i;  
  55.     UART_Initial();  
  56.     IR_Out = 1;  
  57.     while(1)  
  58.     {         
  59.         START_Flag = START_Judge();  
  60.         BOOT_REPEATING_CODE_Flag = BOOT_REPEATING_CODE_Judge();  
  61.         if ( START_Flag && !BOOT_REPEATING_CODE_Flag )  
  62.         {             
  63.             for(i =0;i <4; i++)  
  64.             {                 
  65.                 B0 = H_L_LEVEL_Judge();  
  66.                 B1 = H_L_LEVEL_Judge();  
  67.                 B2 = H_L_LEVEL_Judge();  
  68.                 B3 = H_L_LEVEL_Judge();  
  69.                 B4 = H_L_LEVEL_Judge();  
  70.                 B5 = H_L_LEVEL_Judge();  
  71.                 B6 = H_L_LEVEL_Judge();  
  72.                 B7 = H_L_LEVEL_Judge();                               
  73.                 DATA[i] = TEMP_BIT;  
  74.             }  
  75.             for(i =0;i <4; i++)  
  76.             {  
  77.                 SBUF = DATA[i];  
  78.                 while( TI == 0 );  
  79.                 TI = 0;  
  80.             }  
  81.         }  
  82.     }  
  83. }  
  84.   
  85. void UART_Initial()  
  86. {  
  87.     SCON = 0x50;            // SCON: 模式 1, 8-bit UART, 使能接收  
  88.   
  89.     TMOD |= 0x20;           // TMOD: timer 1, mode 2, 8-bit reload  
  90.   
  91.     TH1 = 0xFD;             // TH1: reload value for 9600 baud @  
  92.                             // 11.0592MHz   
  93.     TR1 = 1;                // TR1: timer 1 run  
  94.   
  95.     EA = 0;                 // 關(guān)閉總中斷  
  96.     ES = 0;                 // 關(guān)閉串口中斷  
  97. }  
  98.       
  99.   
  100. bit START_Judge()  
  101. {  
  102.     bit TEMP_Flag = 1;  
  103.     unsigned char i = 0;  
  104.   
  105.     //在正常無(wú)遙控信號(hào)時(shí),一體化紅外接收頭輸出是高電平,程序一直在循環(huán)。  
  106.     while ( IR_Out == 1);  
  107.   
  108.     //重復(fù)10次,目的是檢測(cè)在6876~8352微秒內(nèi)如果出現(xiàn)高電平就退出解碼程序  
  109.     for(i =0;i <9; i++)  
  110.     {  
  111.         DELAY_Us(800);      // 測(cè)試實(shí)際延時(shí)約為764~928us  
  112.         if ( IR_Out == 1 )  
  113.         {  
  114.             TEMP_Flag = 0;  
  115.             break;  
  116.         }  
  117.     }  
  118.       
  119.     return TEMP_Flag;  
  120. }  
  121.   
  122. bit BOOT_REPEATING_CODE_Judge()  
  123. {  
  124.     bit TEMP_Flag = 1;  
  125.     while( IR_Out == 0 ) ;  // 等待高電平避開(kāi)9毫秒低電平引導(dǎo)脈沖  
  126.   
  127.     DELAY_Ms(1);            // 測(cè)試實(shí)際延時(shí)約為1.007ms   
  128.     DELAY_Ms(1);            // 測(cè)試實(shí)際延時(shí)約為1.007ms   
  129.     DELAY_Us(200);          // 0.086ms  
  130.     DELAY_Us(200);          // 0.086ms    
  131.     DELAY_Us(200);          // 0.086ms  
  132.                             // 共計(jì)2.272ms      
  133.   
  134.     if( IR_Out == 0 )  
  135.     {  
  136.         TEMP_Flag = 1;      // 是連發(fā)碼  
  137.     }  
  138.     else  
  139.     {  
  140.         TEMP_Flag = 0;      // 不是連發(fā)碼,而是引導(dǎo)碼  
  141.     }  
  142.     return TEMP_Flag;  
  143. }  
  144. bit H_L_LEVEL_Judge()  
  145. {  
  146.     while( IR_Out == 0 );   // 等待地址碼第一位的高電平信號(hào)  
  147.     DELAY_Us(800);          // 測(cè)試實(shí)際延時(shí)約為764~928us  
  148.     if ( IR_Out == 1)  
  149.     {  
  150.         DELAY_Ms(1);        // 測(cè)試實(shí)際延時(shí)約為1.007ms   
  151.         return 1;  
  152.     }  
  153.     else  
  154.     {  
  155.         return 0;  
  156.     }  
  157. }

  158.  

     

    編輯如下:

    01 FE 8B 74 --- 01 FE 8D 72 --- 01 FE 8F 70

    01 FE 89 76 --- 01 FE 81 7E --- 01 FE 87 78

    01 FE 0F F0 --- 01 FE 2B D4 --- 01 FE 13 EC

    01 FE 2D D2 --- 01 FE 33 CC --- 01 FE 1B E4

    01 FE 19 E6 --- 01 FE 31 CE --- 01 FE BD 42

    01 FE 11 EE --- 01 FE 39 C6 --- 01 FE B5 4A
    以上為對(duì)應(yīng)按鍵的編碼。

    過(guò)程中存在問(wèn)題:

    一是如何有效的識(shí)別引導(dǎo)碼和連發(fā)碼,因?yàn)檫@個(gè)能直接影響到長(zhǎng)時(shí)間按鍵,單片機(jī)的響應(yīng)與否。這個(gè)問(wèn)題,貌似我以解決,就是長(zhǎng)時(shí)間按鍵后,單片機(jī)識(shí)別一次按鍵后,如果還是同一按鍵,就不與理睬。

    還有一個(gè)問(wèn)題就是,如果連續(xù)按下兩次按鍵,該程序能夠識(shí)別出,但是如果間隔很短,第二下按鍵的編碼容易出錯(cuò),容易變成這樣:

    03 FE 8B 74.。。。就是第一個(gè)字節(jié)出現(xiàn)誤差,這個(gè)問(wèn)題現(xiàn)在還未來(lái)得及解決。

    還有就是本程序?qū)τ谘訒r(shí)函數(shù)的精度要求很高,因?yàn)楸旧硖幚淼拿}沖就是MS級(jí)別的。所以需要嚴(yán)格的測(cè)試延時(shí)函數(shù)的實(shí)際延時(shí)時(shí)間:

     

    以上的代碼,可以看出許多問(wèn)題,軟件延時(shí)不準(zhǔn)確,大量的“while( IR_Out == 0 ) ;”代碼,抗干擾能力弱,容易進(jìn)入死循環(huán)。

    下面介紹的這種解碼方法,利用外部中斷觸發(fā)程序,定時(shí)器定時(shí)(但沒(méi)有設(shè)置定時(shí)中斷程序,即判斷TF的值確定定時(shí)結(jié)束),在代碼過(guò)程中,開(kāi)頭的一個(gè)7.93ms延時(shí),足以濾掉不合法的紅外信號(hào)。應(yīng)該說(shuō)效率質(zhì)量更高的。

    代碼注釋很詳細(xì),在此不在細(xì)述:

    [cpp] view plaincopy
    1. /*------------------------------------------------------------*- 
    2.   IR_Decoder.C (v1.00) 
    3.   ------------------------------------------------------------ 
    4.   名稱:遙控器紅外解碼,PO口接LED,顯示功能碼以供查看 
    5.   編寫:mhjerry 
    6.   日期:20011.7 
    7.   內(nèi)容:按遙控器上的按鍵,會(huì)在PO口LED上顯示 
    8. -*------------------------------------------------------------*/  
    9. #include "reg52.h"  
    10.   
    11. // 此口為紅外信號(hào)輸入MCU口  
    12. sbit IR_Out = P3^2;   
    13.   
    14. // 主程序運(yùn)行標(biāo)志位,運(yùn)行主程序時(shí)LED滅,運(yùn)行中斷程序時(shí)LED亮    
    15. sbit IR_Flag = P3^1;  
    16.   
    17. // LED顯示口  
    18. #define LED_Port P1  
    19.   
    20. // 用于存放按鍵碼值,初始化為0000 0000這樣接受數(shù)據(jù)時(shí)可以只考慮1了   
    21. unsigned char dat[4] = {0,0,0,0};  
    22.   
    23.   
    24. /*............................................................*/  
    25. void main()  
    26. {  
    27.     IR_Out = 1;     // 此口為MCU輸入口,故需要置1  
    28.     IR_Flag = 1;    // 滅LED燈  
    29.     TMOD = 0x01;    // 定時(shí)器0,方式1  
    30.     IT0 = 1;        // 外部中斷0,下降沿觸發(fā)  
    31.     EX0 = 1;        // 準(zhǔn)許外部中斷  
    32.     EA = 1;         // CPU準(zhǔn)許中斷  
    33.   
    34.     while(1)  
    35.     {  
    36.         IR_Flag = 1;// 執(zhí)行主程序時(shí),LED燈滅  
    37.     }  
    38. }  
    39. /*------------------------------------------------------------*-  
    40.   函數(shù)名稱:Int0() 
    41.   函數(shù)輸入:無(wú)(容許中斷時(shí),外部觸發(fā)) 
    42.   函數(shù)輸出:無(wú) 
    43.   函數(shù)說(shuō)明:外部中斷0中斷處理 
    44. -*------------------------------------------------------------*/  
    45. void Int0() interrupt 0  
    46. {  
    47.     unsigned char i,j;  
    48.     EX0 = 0;            // 關(guān)閉外部中斷0  
    49.     IR_Flag = 0;        // 執(zhí)行中斷程序時(shí),LED燈亮  
    50.     i = 10;             // 0.793ms延時(shí),運(yùn)行10次  
    51.     while( --i )  
    52.     {  
    53.         // 定時(shí)0.793ms,延時(shí)0.793ms*10=7.93ms  
    54.         TH0 = 0xfc;  
    55.         TL0 = 0xe7;  
    56.         TR0 = 1;  
    57.         while( !TF0 );  
    58.         TF0 = 0;  
    59.         TR0 = 0;  
    60.           
    61.         // 這7.93ms期間只要IR_Out變高電平,就非合法的紅外信號(hào),跳出  
    62.         if( IR_Out )  
    63.         {  
    64.             EX0 = 1;    // 準(zhǔn)許中斷  
    65.             return ;  
    66.         }  
    67.     }  
    68.       
    69.     // 程序進(jìn)行到這里,表明是合法的紅外信號(hào)(利用9ms判斷)  
    70.     while( !IR_Out );   // 等待9ms低電平過(guò)去  
    71.       
    72.     // 程序進(jìn)行到這里,表明經(jīng)過(guò)9ms低電平  
    73.     TH0 = 0xf6;  
    74.     TL0 = 0xff;  
    75.     TR0 = 1;  
    76.     while( !TF0 );  
    77.     TF0 = 0;  
    78.     TR0 = 0;            // 延時(shí)2.305ms  
    79.       
    80.     // IR_Out 為低表明是連發(fā)碼,不予理睬,跳出  
    81.     if( !IR_Out )  
    82.     {  
    83.         EX0=1;  
    84.         return;  
    85.     }  
    86.   
    87.     // 程序進(jìn)行到這里,表明是引導(dǎo)碼,等待4.5ms高電平的過(guò)去  
    88.     while( IR_Out );      
    89.       
    90.     // 開(kāi)始接收用戶碼  
    91.     for(i=0; i<4; i++)  
    92.     {  
    93.         for(j=0; j<8; j++)  
    94.         {  
    95.             while( !IR_Out );   // 等待低電平過(guò)去  
    96.             dat[i] >>= 1;     // 把上次的數(shù)據(jù)位右移一位  
    97.   
    98.             TH0 = 0xfc;  
    99.             TL0 = 0xe7;  
    100.             TR0 = 1;  
    101.             while( !TF0 );  
    102.             TR0=0;  
    103.             TF0=0;              //延時(shí)0.793ms   
    104.               
    105.             // 若為數(shù)據(jù)"1",則延時(shí)后IR_Out為高電平  
    106.             if( IR_Out )   
    107.             {  
    108.                 dat[i] |= 0x80;     // 所有數(shù)據(jù)位1放最高位  
    109.                 while( IR_Out );    // 等待高電平過(guò)去  
    110.             }  
    111.         }  
    112.     }     
    113.     LED_Port = dat[2];  
    114.     EX0=1;      // 開(kāi)中斷  
    115.     return;  
    116. }  
    117. /*------------------------------------------------------------*- 
    118.   ---- END OF FILE ------------------------------------------- 
    119. -*------------------------------------------------------------*/  
     
 

評(píng)分

參與人數(shù) 6黑幣 +25 收起 理由
暮舞 + 3 贊一個(gè)!
驍勇阿凱 + 5 贊一個(gè)!
我放假快樂(lè) + 5 絕世好帖!
ASDAASD + 5 很給力!
zyt@0121 + 2
單片機(jī)~+ + 5 很給力!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:161497 發(fā)表于 2017-1-24 09:52 | 顯示全部樓層
講得很詳細(xì)  這些資料在哪里下載?
回復(fù)

使用道具 舉報(bào)

ID:161497 發(fā)表于 2017-1-24 09:52 | 顯示全部樓層
資料在哪里下載
回復(fù)

使用道具 舉報(bào)

ID:165041 發(fā)表于 2017-2-17 09:40 | 顯示全部樓層
第61行下面應(yīng)該是為低電平就跳出.
回復(fù)

使用道具 舉報(bào)

ID:165041 發(fā)表于 2017-2-17 12:30 | 顯示全部樓層
還有在while(--i)之前加個(gè)低電平判斷,大哥啊,我還是個(gè)新手呢,根據(jù)你的邏輯寫的PIC的,找了好久才找到這兩個(gè)BUG;
最后還是要非常感謝哥們的分享!
回復(fù)

使用道具 舉報(bào)

ID:165262 發(fā)表于 2017-2-18 16:26 | 顯示全部樓層
學(xué)習(xí)了!
回復(fù)

使用道具 舉報(bào)

ID:166593 發(fā)表于 2017-2-25 15:54 | 顯示全部樓層
只看懂了cpu延時(shí)的程序,有個(gè)疑問(wèn)希望能幫忙解決一下:
在判斷是引導(dǎo)碼還是連發(fā)碼的函數(shù)里,如果是引導(dǎo)碼延時(shí)2.272ms后還有約2ms的高電平?如果直接進(jìn)入數(shù)據(jù)接收函數(shù)不會(huì)出現(xiàn)誤差么?
回復(fù)

使用道具 舉報(bào)

ID:74784 發(fā)表于 2017-2-26 22:41 | 顯示全部樓層
有50462發(fā)射芯片的解碼不?
回復(fù)

使用道具 舉報(bào)

ID:130231 發(fā)表于 2017-3-17 15:26 | 顯示全部樓層
不錯(cuò)哦
回復(fù)

使用道具 舉報(bào)

ID:147518 發(fā)表于 2017-7-11 18:28 來(lái)自手機(jī) | 顯示全部樓層
學(xué)習(xí)了,雖看不懂但也贊了
回復(fù)

使用道具 舉報(bào)

ID:174969 發(fā)表于 2017-8-19 05:24 | 顯示全部樓層
很好的資料,算是我學(xué)習(xí)紅外遙控的第一篇
回復(fù)

使用道具 舉報(bào)

ID:229128 發(fā)表于 2017-12-11 13:23 | 顯示全部樓層
“有無(wú)遙控信號(hào)判斷函數(shù)” 這個(gè)不是很懂有這方面的資料不?
回復(fù)

使用道具 舉報(bào)

ID:278860 發(fā)表于 2018-1-28 19:41 | 顯示全部樓層
牛的一匹
回復(fù)

使用道具 舉報(bào)

ID:164089 發(fā)表于 2018-1-31 21:56 來(lái)自手機(jī) | 顯示全部樓層
資料很好傻
回復(fù)

使用道具 舉報(bào)

ID:164089 發(fā)表于 2018-1-31 21:57 來(lái)自手機(jī) | 顯示全部樓層
程序還有點(diǎn)問(wèn)題,正在研究。
回復(fù)

使用道具 舉報(bào)

ID:287608 發(fā)表于 2018-3-5 07:56 | 顯示全部樓層
寫的很多,只可惜看不懂,學(xué)會(huì)了再來(lái)下載吧
回復(fù)

使用道具 舉報(bào)

ID:291105 發(fā)表于 2018-3-14 21:57 | 顯示全部樓層
這個(gè)那么多,要慢慢看了
回復(fù)

使用道具 舉報(bào)

ID:84997 發(fā)表于 2018-3-15 09:40 | 顯示全部樓層
非常好的文章,學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

ID:91280 發(fā)表于 2018-4-13 20:52 來(lái)自手機(jī) | 顯示全部樓層
好東西,學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

ID:85743 發(fā)表于 2018-4-18 23:49 | 顯示全部樓層

學(xué)習(xí)了,謝謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:313033 發(fā)表于 2018-4-21 14:27 | 顯示全部樓層
學(xué)習(xí)到了,單片機(jī)小白目前看不懂
回復(fù)

使用道具 舉報(bào)

ID:313821 發(fā)表于 2018-4-22 16:33 | 顯示全部樓層
找到了組織
回復(fù)

使用道具 舉報(bào)

ID:308180 發(fā)表于 2018-4-27 16:10 | 顯示全部樓層
很棒,學(xué)習(xí)中斷很有用
回復(fù)

使用道具 舉報(bào)

ID:111025 發(fā)表于 2018-5-10 17:34 | 顯示全部樓層
學(xué)習(xí)了!!
回復(fù)

使用道具 舉報(bào)

ID:369787 發(fā)表于 2018-7-11 22:07 | 顯示全部樓層
還是不懂
回復(fù)

使用道具 舉報(bào)

ID:327464 發(fā)表于 2018-7-15 03:58 | 顯示全部樓層
有死循環(huán)的概率,最好加個(gè)超時(shí)判斷
回復(fù)

使用道具 舉報(bào)

ID:267435 發(fā)表于 2018-7-18 09:54 | 顯示全部樓層
講得很細(xì)致  資料在哪里下載?
回復(fù)

使用道具 舉報(bào)

ID:374177 發(fā)表于 2018-7-18 16:10 | 顯示全部樓層
看到有更簡(jiǎn)結(jié)的C程序,我哪天對(duì)比一下功能。
回復(fù)

使用道具 舉報(bào)

ID:375003 發(fā)表于 2018-7-19 18:44 | 顯示全部樓層
我做的仿真遙控器
PIC12f509仿真空調(diào)搖控器

#include "pic12f509.h"

//#include<htc.h>
//  _CONFIG (0x02); //表示用內(nèi)部的RC震蕩器;
// 配置文件在編程器寫入的時(shí)候指定選項(xiàng)
//**************************************************
//                       __________
//               VDD-| 1             8 |-VSS
//                GP5-| 2            7 |-GP0/DAT
//                GP4-| 3            6 |-GP1/CLK
//  GP3/RMCLR--| 4            5 |-GP2
//                       |_________|
//                 12F508
//***************************************************
//按鍵必須用以下三個(gè)腳,不然睡眠后不能喚醒;
//發(fā)射二極管正極接電源,負(fù)極經(jīng)100歐電阻接5腳;
#define uchar unsigned char
#define uint unsigned int
#define IR_out  GP2
#define pwr_KEY GP1
#define up_KEY  GP3
#define down_KEY GP0

union//定義一個(gè)可以位操作的結(jié)構(gòu)體
{
struct{
       unsigned b0:1;
       unsigned b1:1;
       unsigned b2:1;
       unsigned b3:1;
       unsigned b4:1;
       unsigned b5:1;
       unsigned b6:1;
       unsigned b7:1;
      }oneBit;
      unsigned char allBits;
}myFlag;

#define wHB myFlag.oneBit.b7
#define wBYT myFlag.allBits

const uchar chuai[]={0x41,0x49,0x45,0x4d,0x43,0x4b,0x47};//26度到32度
static bit key;
uchar ii;

#define H 1
#define L 0

void init()
{
    TRISGPIO=0b11111011;//只有GP2輸出;
    OPTION=0b00001000;//TIM0不用分頻器0x80;引腳變化可以喚醒,開(kāi)上拉
    OSCCAL=0b00000000;//晶振頻率不校正.
}

void dly(uint Delay) /*延時(shí)t/0.5ms*/
  {
    uchar i=50;
    while(--Delay)while(--i);
   }


start()
{
   uint i=342;
  while(i--)//輸出9ms負(fù)脈沖;
   { IR_out=L;ii=2;//輸出負(fù)脈沖
     while(--ii);
     IR_out=H;     //輸出正脈沖
   }
   i=171;
   while(i--)//輸出4.5ms正脈沖;
   { IR_out=H;ii=2;//輸出負(fù)脈沖
     while(--ii);
     IR_out=H;    //輸出正脈沖
   }
}
output_0()
{
  uint i=19;
  while(i--)//輸出9ms負(fù)脈沖;
   { IR_out=L;ii=2;//輸出負(fù)脈沖
     while(--ii);
     IR_out=H;     //輸出正脈沖
   }
   i=26;
   while(i--)//輸出4.5ms正脈沖;
   { IR_out=H;ii=2;//輸出負(fù)脈沖
     while(--ii);
     IR_out=H;    //輸出正脈沖
   }
}
output_1()
{
  uint i=19;
  while(i--)//輸出9ms負(fù)脈沖;
   { IR_out=L;ii=2;//輸出負(fù)脈沖
     while(--ii);
     IR_out=H;     //輸出正脈沖
   }
   i=66;
   while(i--)//輸出4.5ms正脈沖;
   { IR_out=H;ii=2;//輸出負(fù)脈沖
     while(--ii);
     IR_out=H;    //輸出正脈沖
   }
}
void main()
{
uchar dat3=0,dat4=0,zz=0,zr=0;
uchar dat1=0,dat2=0;
init();
uchar nFUN;//定義成局部變量復(fù)位不會(huì)清零;
GPIO=0XFF; //IO口全是高電平;
if(nFUN>6)nFUN=6;//如果值不確定,初始化成6;
IR_out=1;//關(guān)輸出三極管;
dat1=0XC1;dat2=0x60;
while(1){
          wBYT=dat1;key=0;
        IR_out=1;
    if(pwr_KEY==0){dly(10);if(pwr_KEY==0){while(pwr_KEY==0);key=1;}
           dat3=0x20;dat4=0x41;nFUN=0;}//電源26度開(kāi)機(jī);復(fù)位nFUN.
    if(up_KEY==0){dly(10);if(up_KEY==0){while(up_KEY==0);key=1;}
          dat3=0;if(nFUN<6)nFUN++;dat4=chuai[nFUN];}//溫度加;參數(shù)100延時(shí)時(shí)間21ms
    if(down_KEY==0){dly(10);if(down_KEY==0){while(down_KEY==0);key=1;}
           dat3=0;if(nFUN>0)nFUN--;dat4=chuai[nFUN];}//溫度減;參數(shù)100延時(shí)時(shí)間21ms
    if(key)
    {
        start();
        wBYT=dat1;
         for(zz=0;zz<=6;zz++)
         {

             if(zz==1)wBYT=dat2;
             if(zz==2)wBYT=dat3;
             if(zz==3)wBYT=dat4;
             if(zz==4)wBYT=0x00;
             if(zz==5)wBYT=0x00;
             if(zz==6){key=0;output_0();break;}
             for(zr=0;zr<8;zr++)
            {
               if(wHB)output_1();
               else output_0();
               wBYT<<=1;
             }

          }

    }
#asm
        SLEEP
#endasm
  }
}

評(píng)分

參與人數(shù) 1黑幣 +70 收起 理由
admin + 70 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:261485 發(fā)表于 2018-7-21 09:16 | 顯示全部樓層
我學(xué)這個(gè)很久了,就是不懂遙控小車的話,前進(jìn)后退,轉(zhuǎn)彎的程序,應(yīng)該放在哪里才能被發(fā)送到小車。比如按遙控器的1是前進(jìn),那應(yīng)該怎么寫,寫在那個(gè)函數(shù)里。我看了很多,都不同,就把我弄懵了,希望大神給我哦講解下,配個(gè)例子。。。謝謝。。。。。。。。。!
回復(fù)

使用道具 舉報(bào)

ID:6985 發(fā)表于 2018-7-31 12:04 | 顯示全部樓層
頂一下,不錯(cuò)
回復(fù)

使用道具 舉報(bào)

ID:392786 發(fā)表于 2018-9-3 11:04 | 顯示全部樓層
很詳細(xì),雖然看不太懂。
回復(fù)

使用道具 舉報(bào)

ID:332225 發(fā)表于 2018-9-4 09:16 | 顯示全部樓層
好厲害!
回復(fù)

使用道具 舉報(bào)

ID:251401 發(fā)表于 2018-10-21 16:53 | 顯示全部樓層
能寫出發(fā)射和接收的數(shù)據(jù)編碼的不同就好了。
回復(fù)

使用道具 舉報(bào)

ID:247813 發(fā)表于 2018-10-21 20:49 | 顯示全部樓層
很詳細(xì),雖然看不太懂。
回復(fù)

使用道具 舉報(bào)

ID:223688 發(fā)表于 2018-10-22 08:40 | 顯示全部樓層
很詳細(xì)
回復(fù)

使用道具 舉報(bào)

ID:337913 發(fā)表于 2018-11-3 16:42 | 顯示全部樓層
厲害呀,大佬
回復(fù)

使用道具 舉報(bào)

ID:326450 發(fā)表于 2018-11-4 18:40 | 顯示全部樓層
有詳細(xì)的資料和電路么?
回復(fù)

使用道具 舉報(bào)

ID:152589 發(fā)表于 2018-11-27 08:50 | 顯示全部樓層
贊一個(gè)
回復(fù)

使用道具 舉報(bào)

ID:352449 發(fā)表于 2019-5-12 17:07 | 顯示全部樓層
還是有嗲看不懂
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表