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

QQ登錄

只需一步,快速開始

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

[保姆級(jí)指南]郭天祥51單片機(jī)STC89C52外設(shè)-HX1838紅外接收頭使用方法

[復(fù)制鏈接]
ID:970285 發(fā)表于 2022-2-6 13:52 | 顯示全部樓層 |閱讀模式
本帖最后由 江弘源 于 2022-2-6 19:19 編輯

【“保姆級(jí)”指南】郭天祥51單片機(jī)STC89C52外設(shè)--HX1838紅外接收頭使用方法
這是我接觸的第一款沒有在郭天祥新概念書里講解的芯片,我覺得紅外線接收協(xié)議的探究難度和DS18B20旗鼓相當(dāng),大幅低于郭天祥配套的時(shí)鐘芯片(反正Intel和Motorola協(xié)議看得我暈暈的,時(shí)鐘芯片的功能也比常見的萬年歷+時(shí)鐘復(fù)雜很多),建議(像我的)初學(xué)者如果有意強(qiáng)化自己使用陌生芯片的能力,可以使用這款紅外芯片或者溫度探頭DS18B20先挑戰(zhàn)一把,再用時(shí)鐘芯片進(jìn)階研究。
前言:所有代碼在郭天祥51開發(fā)板TX-1C普通開發(fā)板測(cè)試成功。
建議《郭天祥新概念51單片機(jī)C語言教程》先攻克定時(shí)器,串口打印部分再閱讀本文。
1.紅外通訊--NEC標(biāo)準(zhǔn)協(xié)議及其拓展NEC協(xié)議(extended-NEC,下稱extNEC)
NEC通信協(xié)議是常見紅外遙控器的通訊協(xié)議。其他的通信協(xié)議還有飛利浦(Philips RC5/RC6),松下等廠家的協(xié)議等。下面重點(diǎn)介紹NEC標(biāo)準(zhǔn)協(xié)議及其拓展態(tài)。
如何表示0,1信號(hào):
0信號(hào):0.56ms低電平,之后跟著0.56ms高電平,共1.125ms
1信號(hào):0.56ms低電平,之后跟著1.68ms高電平,共2.25ms
2018071520514243.png
(ext)NEC一次發(fā)送的內(nèi)容由三部分(及其反碼組成)組成
引導(dǎo)碼:觸發(fā)低電平條件,進(jìn)入外來中斷程序處理紅外信號(hào)。先有9ms低電平再跟著4.5ms高電平。
8位地址碼(又稱“客戶碼”):一般一個(gè)遙控一碼,以標(biāo)識(shí)遙控器身份,硬件固定和軟件編程兼有(方便配對(duì)),防止遙控器的數(shù)據(jù)被錯(cuò)誤的接收器接收導(dǎo)致遙控器不小心遙控到非目標(biāo)設(shè)備的情況(串碼)。
extNEC會(huì)連續(xù)出現(xiàn)16位地址碼,標(biāo)準(zhǔn)NEC8位地址碼出現(xiàn)之后緊跟著地址碼的反碼。
8位數(shù)據(jù)碼:和遙控器的按鍵一一對(duì)應(yīng),一般由硬件固定(學(xué)習(xí)遙控器可以軟件編程,學(xué)習(xí)目標(biāo)遙控器的地址碼和數(shù)據(jù)碼),以標(biāo)識(shí)鍵位。
數(shù)據(jù)碼的反碼:用于取反之后與前面的數(shù)據(jù)碼匹配,用于檢查傳輸數(shù)據(jù)過程是否有問題。
結(jié)束碼:最后有0.56ms低電平,表示傳輸代碼結(jié)束。
連續(xù)信號(hào)引導(dǎo)碼:與引導(dǎo)碼類似,不過高電平時(shí)間變短,只有2.25ms。
我網(wǎng)上找到的大多數(shù)資料把NEC和extNEC混為一談,兩個(gè)協(xié)議之間的區(qū)別便是extNEC將原有標(biāo)準(zhǔn)協(xié)議的基礎(chǔ)上放棄了8位用于數(shù)據(jù)校驗(yàn)的地址碼反碼,轉(zhuǎn)而將地址碼由8位(256種排列組合)拓展到16位(65536種),接收和發(fā)送端的組合可以變得更多,降低串碼的可能性。
單次傳輸:引導(dǎo)碼-【地址碼-地址碼反碼】(16位地址碼)-數(shù)據(jù)碼-數(shù)據(jù)碼反碼-結(jié)束碼
連續(xù)傳輸:引導(dǎo)碼-【地址碼-地址碼反碼】(16位地址碼)-數(shù)據(jù)碼-數(shù)據(jù)碼反碼-結(jié)束碼-連續(xù)信號(hào)引導(dǎo)碼-結(jié)束碼-連續(xù)信號(hào)引導(dǎo)碼-結(jié)束碼-......
【方括號(hào)是標(biāo)準(zhǔn)NEC的內(nèi)容】(圓括號(hào)是拓展NEC的內(nèi)容)
20180715204817233.png
20180715205532977.png

我們使用的紅外接收模塊是HX1838。負(fù)責(zé)將紅外載波信號(hào)直接解碼成pwm信號(hào),方便軟件讀取。
-參考參數(shù)
O1CN01ovCM6T2CAMhzVu8FZ_!!2209549908433_看圖王.jpg
模塊含有一顆接收燈,通斷電不亮,通電并接收到載波紅外信號(hào)時(shí)閃亮。
接收原理
發(fā)射極調(diào)解載波頻率38khz的紅外信號(hào)——
接收器將紅外信號(hào)轉(zhuǎn)化為TTL電平的(ext)NEC協(xié)議信號(hào)——
由單片機(jī)軟件解碼(ext)NEC協(xié)議信號(hào)
(由軟件判斷軟件編程的地址碼是不是和遙控器預(yù)設(shè)的地址碼匹配,不是則本次接收的數(shù)據(jù)丟棄,是則說明接收端和發(fā)射端匹配,進(jìn)行下一步處理)
(軟件記錄接下來的數(shù)據(jù)碼及其緊跟著的反碼,判斷反碼的“反碼”是不是和數(shù)據(jù)碼相匹配(數(shù)據(jù)校驗(yàn)),不是則數(shù)據(jù)傳輸出現(xiàn)差錯(cuò),本次接收的數(shù)據(jù)丟棄,是則存入其他負(fù)責(zé)存儲(chǔ)數(shù)據(jù)碼的變量)
(軟件將數(shù)據(jù)碼與預(yù)設(shè)的編碼表匹配,判斷出按下的是哪個(gè)按鍵,執(zhí)行按鍵對(duì)應(yīng)的操作)
使用方法
其接口非常簡(jiǎn)單,接收器5V供電,只有三個(gè)接口:
VCC,GND和數(shù)據(jù)端口
直接把VCC和GND杜邦線懟上延伸出來的供電插針(暫時(shí)不知道有沒有反接保護(hù)),數(shù)據(jù)端口接上P3.2(外界中斷0輸入)即可。
e48fe26090fe7e26e4d85ab766ad530.jpg
039773c3f669d498f6be19d0b53adb5.jpg
P3是“準(zhǔn)雙向端口”,記得開始讀取之前先寫1。

2.研究用器材
    郭天祥TX-1C 51開發(fā)板(或者有空余的外界中斷輸入端的51最小系統(tǒng)板)
    HX1838紅外線接收頭和配套遙控

某一個(gè)寶上找個(gè)商家買到的,不到5塊錢

某一個(gè)寶上找個(gè)商家買到的,不到5塊錢

網(wǎng)上上買到的,不到5塊錢
    5個(gè)遙控器(從左到右分別是科沃斯掃地機(jī)器人遙控器,老式松下空調(diào)遙控器,模塊配套的遙控器,DVD遙控器,天貓魔盒遙控器)
655573aae8367c2b1f00f39f0cf88f6.jpg
    其中,左兩個(gè)遙控器有接收到信號(hào)(接收燈閃亮)但似乎是協(xié)議不同,串口打印不出數(shù)據(jù);第三四個(gè)遙控使用的是標(biāo)準(zhǔn)NEC協(xié)議,地址碼好像都是0(改都不改,不怕串碼么),第五個(gè)使用的是拓展NEC協(xié)議(而且遙控硬件地址碼可以編程修改)
鄙人才疏學(xué)淺,這次只能先探究接收單次信號(hào)的情況,也就是按下一次按鍵就操作一次代碼(長(zhǎng)按無動(dòng)作)的情況。
3.功能實(shí)現(xiàn)(for延時(shí)版本)
實(shí)現(xiàn)思路:
a.引導(dǎo)碼輸入端口,觸發(fā)外部中斷0,進(jìn)入中斷函數(shù),關(guān)閉外來中斷0開關(guān)防止后來的低電平使得CPU重復(fù)進(jìn)入中斷程序
b.使用while等待電平變化,同時(shí)用計(jì)時(shí)器或者for延時(shí)計(jì)算引導(dǎo)碼高/低電平延時(shí)時(shí)間,檢查是否為硬件抖動(dòng)(過很小一段時(shí)間后端口會(huì)恢復(fù)到高電平),是抖動(dòng)的話自動(dòng)“退出”(重新打開外來中斷0開關(guān)并return)防止函數(shù)卡死。不是的話說明使用while等待引導(dǎo)碼通過。
c.分四組采集數(shù)據(jù),一次八位,存儲(chǔ)在數(shù)組里
(d.01信號(hào)唯一區(qū)別是高電平時(shí)間長(zhǎng)短,用兩個(gè)while等待電平低變高再變低,數(shù)據(jù)位右移默認(rèn)為0,當(dāng)高電平時(shí)間超出某值時(shí)認(rèn)為接收到1信號(hào),用 或 運(yùn)算將最高位變?yōu)?)
(e.采集過程中也要設(shè)置防卡死“退出”口,使用while等待電平變化,同時(shí)用計(jì)時(shí)器或者for延時(shí)計(jì)算引導(dǎo)碼高/低電平延時(shí)時(shí)間,超過正常數(shù)據(jù)接受時(shí)間自動(dòng)“退出”)
f.數(shù)據(jù)碼反碼取反和數(shù)據(jù)碼比對(duì),決定是數(shù)據(jù)無效并丟棄(“退出”)還是存儲(chǔ)-
g.根據(jù)地址碼的格式判定是哪種類型NEC協(xié)議
h.正常“退出”
i.標(biāo)志位置1,啟動(dòng)printf串口打印。
有一個(gè)要點(diǎn)是防卡死“退出”口要貫穿采集數(shù)據(jù)的整個(gè)過程,防止程序死掉。
第二個(gè)要點(diǎn)是相比判斷高電平時(shí)間來判斷是0還是1,通過判斷1節(jié)代碼整體所用時(shí)間(0為1.125ms,1為2.25ms)來判斷是0是1也是可以的(好像寫出來的程序不是很穩(wěn)定)。
簡(jiǎn)介:
啟動(dòng)串口打印功能,使用中斷法讀取紅外線接收頭接收的數(shù)據(jù)碼,接收后立即用十進(jìn)制打印出來。同時(shí)判斷發(fā)射器使用的是標(biāo)準(zhǔn)還是拓展NEC協(xié)議,打印信號(hào)類型和對(duì)應(yīng)類型地址碼。
要點(diǎn)一:串口打印參數(shù):波特率9600,方式1,其他保持默認(rèn)。
要點(diǎn)二:定時(shí)器1采用八位自動(dòng)重裝模式(產(chǎn)生波特率),紅外信號(hào)對(duì)接外界中斷0輸入口(P3^2)
標(biāo)志位:
signal_input:紅外線接收頭有輸入
signal_extNEC:為1表示遙控器是拓展NEC,0為標(biāo)準(zhǔn)NEC

單片機(jī)源程序如下:
  1. #include<reg52.h>   
  2. #include<intrins.h>
  3. #include<stdio.h>
  4. #define unchar unsigned char
  5. #define unint unsigned int


  6. sbit IRIN=P3^2;
  7. unchar IRCOM[7];
  8. unchar receive_data,custom_address,extra_address;
  9. unchar signal_input,signal_extNEC;

  10. void delay(unchar x);
  11. void init(unint bps_setting);

  12. void main()
  13. {
  14.    
  15.         IRIN=1;             //I/O口初始化        
  16.         IE=0x81;            //允許總中斷中斷,使能 INT0 外部中斷
  17.         
  18.         init(0xFD);                        //波特率9600
  19.         
  20.         while(1)
  21.         {               
  22.            if(signal_input==1)
  23.                 {
  24.                         signal_input=0;
  25.                         receive_data=IRCOM[2];
  26.                         custom_address=IRCOM[0];
  27.                         extra_address=IRCOM[1];
  28.                         ES=0;
  29.                         TI=1;
  30.                         printf("The IR code you receive is %bu!\n",receive_data);
  31.                         while(!TI);
  32.                         
  33.                         if (signal_extNEC==0)
  34.                         {
  35.                                 printf("The corresponding custom address is %bu!,using standard NEC protocol.\n",custom_address);
  36.                                 while(!TI);
  37.                         }
  38.                         else if(signal_extNEC==1)
  39.                         {
  40.                                 printf("The full extent of its custom address is %bu",custom_address);
  41.                                 while(!TI);
  42.                                 printf(" %bu!,using extra NEC protocol.\n",extra_address);
  43.                                 while(!TI);
  44.                         }
  45.                         
  46.                         printf("\n");
  47.                         while(!TI);
  48.                         TI=0;
  49.                         ES=1;
  50.                 }
  51.         }
  52. }

  53. void IR_IN() interrupt 0 using 0//步驟a
  54. {
  55.         unchar j,k,N=0;

  56.         EX0 = 0;   
  57.         delay(15);
  58.         if (IRIN==1)
  59.         {
  60.                 EX0 =1;
  61.                 return;
  62.         } //軟件防抖動(dòng)
  63.                   
  64.         while (!IRIN)       //等IR變?yōu)楦唠娖,跳過9ms的前導(dǎo)低電平信號(hào)。
  65.                 delay(1);
  66.                
  67.         while (IRIN)                //等IR變?yōu)榈碗娖,跳過4.5ms的前導(dǎo)高電平信號(hào)。
  68.                 delay(1);
  69.                
  70.         //步驟b結(jié)束,c開始
  71.         
  72.         for (j=0;j<4;j++)         //收集四組數(shù)據(jù)
  73.         {
  74.                 for (k=0;k<8;k++)        //每組數(shù)據(jù)有8位
  75.                 {
  76.                                 
  77.                         while (!IRIN)          //等 IR 變?yōu)楦唠娖?br />
  78.                                 delay(1);
  79.                         while (IRIN)           //計(jì)算IR高電平時(shí)長(zhǎng)
  80.                         {
  81.                                 delay(1);
  82.                                 N++;   //計(jì)數(shù)器疊加      
  83.                                 if (N>=30)
  84.                                 {
  85.                                         EX0=1;
  86.                                         return;
  87.                                 }                  //步驟e,0.14ms計(jì)數(shù)過長(zhǎng)自動(dòng)離開。
  88.                         } //高電平時(shí)間記錄判定,即為步驟d              
  89.                         IRCOM[j]=IRCOM[j] >> 1;     //數(shù)據(jù)最高位補(bǔ)“0”
  90.                         if(N>=8)
  91.                         {
  92.                                 IRCOM[j] = IRCOM[j] | 0x80;                  //數(shù)據(jù)最高位補(bǔ)“1”
  93.                         }  
  94.                         N=0;        //步驟d結(jié)束,計(jì)數(shù)器清零,準(zhǔn)備下一位計(jì)數(shù)
  95.                 }
  96.         }
  97.         
  98.         if(IRCOM[2]!=~IRCOM[3])
  99.         {
  100.                 EX0=1;
  101.                 return;
  102.         }
  103.         //步驟f,數(shù)據(jù)校驗(yàn)
  104.         
  105.         if (IRCOM[0]==~IRCOM[1])
  106.         {
  107.                 signal_extNEC=0;
  108.         }
  109.         else
  110.         {
  111.                 signal_extNEC=1;
  112.         }//步驟g,格式判定
  113.         
  114.         signal_input=1;
  115.         EX0 = 1; //退出并啟動(dòng)步驟i
  116. }

  117. void init(unint bps_setting)
  118. {
  119.         TH1=bps_setting;
  120.         TL1=bps_setting;

  121.         TMOD=0x20;
  122.         TR1=1;
  123.         
  124.         SM0=0;
  125.         SM1=1;                //串口方式1
  126.         REN=1;
  127.         
  128.         EA=1;
  129.         ET0=1;
  130.         ES=1;
  131.         

  132. }
  133. /***************延時(shí)函數(shù)*****************************/
  134. void delay(unchar x)    //x*0.14MS
  135. {
  136.         unchar i;
  137.         while(x--)
  138.         {
  139.                 for (i = 0; i<13; i++) {}
  140.         }
  141. }

復(fù)制代碼

實(shí)驗(yàn)效果:
使用前三四個(gè)遙控的情況
92236fd49333354588b22fb763f6217.png
使用天貓魔盒遙控器的情況
b443900f1c0aa1dfd84f1bdafb88df3.png

4.后記
鄙人不常登錄論壇,可能會(huì)不定期回復(fù)問題,或者以后會(huì)考慮在這個(gè)項(xiàng)目下延伸一些內(nèi)容(stm32版本......)。
這是菜鳥的第一篇技術(shù)文章,歡迎在下面指出問題,也歡迎引用我的內(nèi)容,記得在下面吱一聲哈。

appendix:
0.引用資料
(這位老哥用的是定時(shí)器0進(jìn)行延時(shí)計(jì)數(shù),不過有個(gè)小問題就是沒有設(shè)置防卡死)
1.研究中發(fā)現(xiàn)的問題
我去查閱了淘寶給的資料,和論壇上的代碼對(duì)比了一下,
這一部分代碼竟然出奇的相似!
473a5306001686a4a77801625bccc61.png
834c9d6b43a0242d129889f9eca1d79.png
不過這段代碼好像沒什么卵用(單純是把接收到的數(shù)據(jù)不知道做什么算術(shù)運(yùn)算),刪掉也不影響串口打印,如果有大佬知道它的作用,歡迎在下面指出。
2.拋磚引玉
既然接收編碼會(huì)了,那么用軟件編程發(fā)射如何?
店家在郵寄紅外芯片和遙控器的同時(shí),還送了一顆紅外發(fā)射二極管。理論上使用51單片機(jī)調(diào)制pwm也能實(shí)現(xiàn)電子信號(hào)到紅外信號(hào)的調(diào)制。
使用單片機(jī)收發(fā)紅外線信號(hào)實(shí)現(xiàn)機(jī)器間通訊是另一個(gè)值得深挖的好問題,先按下不表。
關(guān)于連續(xù)信號(hào)的接收問題
在網(wǎng)上只找到了stm32/樹莓派版本的帶連續(xù)信號(hào)判定的代碼,如果我的文章能夠引出哪位大佬寫代碼實(shí)現(xiàn)51單片機(jī)連續(xù)信號(hào)的接收,我將感激不盡。

IR reader.zip

1.44 KB, 下載次數(shù): 33, 下載積分: 黑幣 -5

源代碼

HX1838.docx

1.98 MB, 下載次數(shù): 19, 下載積分: 黑幣 -5

技術(shù)日記本體

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

ID:624685 發(fā)表于 2022-2-8 09:43 | 顯示全部樓層
樓主辛苦了,非常詳細(xì),謝謝
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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