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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6636|回復: 1
打印 上一主題 下一主題
收起左側

[保姆級指南]郭天祥51單片機STC89C52外設-HX1838紅外接收頭使用方法

[復制鏈接]
跳轉到指定樓層
樓主
本帖最后由 江弘源 于 2022-2-6 19:19 編輯

【“保姆級”指南】郭天祥51單片機STC89C52外設--HX1838紅外接收頭使用方法
這是我接觸的第一款沒有在郭天祥新概念書里講解的芯片,我覺得紅外線接收協議的探究難度和DS18B20旗鼓相當,大幅低于郭天祥配套的時鐘芯片(反正Intel和Motorola協議看得我暈暈的,時鐘芯片的功能也比常見的萬年歷+時鐘復雜很多),建議(像我的)初學者如果有意強化自己使用陌生芯片的能力,可以使用這款紅外芯片或者溫度探頭DS18B20先挑戰一把,再用時鐘芯片進階研究。
前言:所有代碼在郭天祥51開發板TX-1C普通開發板測試成功。
建議《郭天祥新概念51單片機C語言教程》先攻克定時器,串口打印部分再閱讀本文。
1.紅外通訊--NEC標準協議及其拓展NEC協議(extended-NEC,下稱extNEC)
NEC通信協議是常見紅外遙控器的通訊協議。其他的通信協議還有飛利浦(Philips RC5/RC6),松下等廠家的協議等。下面重點介紹NEC標準協議及其拓展態。
如何表示0,1信號:
0信號:0.56ms低電平,之后跟著0.56ms高電平,共1.125ms
1信號:0.56ms低電平,之后跟著1.68ms高電平,共2.25ms

(ext)NEC一次發送的內容由三部分(及其反碼組成)組成
引導碼:觸發低電平條件,進入外來中斷程序處理紅外信號。先有9ms低電平再跟著4.5ms高電平。
8位地址碼(又稱“客戶碼”):一般一個遙控一碼,以標識遙控器身份,硬件固定和軟件編程兼有(方便配對),防止遙控器的數據被錯誤的接收器接收導致遙控器不小心遙控到非目標設備的情況(串碼)。
extNEC會連續出現16位地址碼,標準NEC8位地址碼出現之后緊跟著地址碼的反碼。
8位數據碼:和遙控器的按鍵一一對應,一般由硬件固定(學習遙控器可以軟件編程,學習目標遙控器的地址碼和數據碼),以標識鍵位。
數據碼的反碼:用于取反之后與前面的數據碼匹配,用于檢查傳輸數據過程是否有問題。
結束碼:最后有0.56ms低電平,表示傳輸代碼結束。
連續信號引導碼:與引導碼類似,不過高電平時間變短,只有2.25ms。
我網上找到的大多數資料把NEC和extNEC混為一談,兩個協議之間的區別便是extNEC將原有標準協議的基礎上放棄了8位用于數據校驗的地址碼反碼,轉而將地址碼由8位(256種排列組合)拓展到16位(65536種),接收和發送端的組合可以變得更多,降低串碼的可能性。
單次傳輸:引導碼-【地址碼-地址碼反碼】(16位地址碼)-數據碼-數據碼反碼-結束碼
連續傳輸:引導碼-【地址碼-地址碼反碼】(16位地址碼)-數據碼-數據碼反碼-結束碼-連續信號引導碼-結束碼-連續信號引導碼-結束碼-......
【方括號是標準NEC的內容】(圓括號是拓展NEC的內容)



我們使用的紅外接收模塊是HX1838。負責將紅外載波信號直接解碼成pwm信號,方便軟件讀取。
-參考參數

模塊含有一顆接收燈,通斷電不亮,通電并接收到載波紅外信號時閃亮。
接收原理
發射極調解載波頻率38khz的紅外信號——
接收器將紅外信號轉化為TTL電平的(ext)NEC協議信號——
由單片機軟件解碼(ext)NEC協議信號
(由軟件判斷軟件編程的地址碼是不是和遙控器預設的地址碼匹配,不是則本次接收的數據丟棄,是則說明接收端和發射端匹配,進行下一步處理)
(軟件記錄接下來的數據碼及其緊跟著的反碼,判斷反碼的“反碼”是不是和數據碼相匹配(數據校驗),不是則數據傳輸出現差錯,本次接收的數據丟棄,是則存入其他負責存儲數據碼的變量)
(軟件將數據碼與預設的編碼表匹配,判斷出按下的是哪個按鍵,執行按鍵對應的操作)
使用方法
其接口非常簡單,接收器5V供電,只有三個接口:
VCC,GND和數據端口
直接把VCC和GND杜邦線懟上延伸出來的供電插針(暫時不知道有沒有反接保護),數據端口接上P3.2(外界中斷0輸入)即可。


P3是“準雙向端口”,記得開始讀取之前先寫1。

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

網上上買到的,不到5塊錢
    5個遙控器(從左到右分別是科沃斯掃地機器人遙控器,老式松下空調遙控器,模塊配套的遙控器,DVD遙控器,天貓魔盒遙控器)

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

單片機源程序如下:
  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.         } //軟件防抖動
  63.                   
  64.         while (!IRIN)       //等IR變為高電平,跳過9ms的前導低電平信號。
  65.                 delay(1);
  66.                
  67.         while (IRIN)                //等IR變為低電平,跳過4.5ms的前導高電平信號。
  68.                 delay(1);
  69.                
  70.         //步驟b結束,c開始
  71.         
  72.         for (j=0;j<4;j++)         //收集四組數據
  73.         {
  74.                 for (k=0;k<8;k++)        //每組數據有8位
  75.                 {
  76.                                 
  77.                         while (!IRIN)          //等 IR 變為高電平
  78.                                 delay(1);
  79.                         while (IRIN)           //計算IR高電平時長
  80.                         {
  81.                                 delay(1);
  82.                                 N++;   //計數器疊加      
  83.                                 if (N>=30)
  84.                                 {
  85.                                         EX0=1;
  86.                                         return;
  87.                                 }                  //步驟e,0.14ms計數過長自動離開。
  88.                         } //高電平時間記錄判定,即為步驟d              
  89.                         IRCOM[j]=IRCOM[j] >> 1;     //數據最高位補“0”
  90.                         if(N>=8)
  91.                         {
  92.                                 IRCOM[j] = IRCOM[j] | 0x80;                  //數據最高位補“1”
  93.                         }  
  94.                         N=0;        //步驟d結束,計數器清零,準備下一位計數
  95.                 }
  96.         }
  97.         
  98.         if(IRCOM[2]!=~IRCOM[3])
  99.         {
  100.                 EX0=1;
  101.                 return;
  102.         }
  103.         //步驟f,數據校驗
  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; //退出并啟動步驟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. /***************延時函數*****************************/
  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. }

復制代碼

實驗效果:
使用前三四個遙控的情況

使用天貓魔盒遙控器的情況


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

appendix:
0.引用資料
(這位老哥用的是定時器0進行延時計數,不過有個小問題就是沒有設置防卡死)
1.研究中發現的問題
我去查閱了淘寶給的資料,和論壇上的代碼對比了一下,
這一部分代碼竟然出奇的相似!


不過這段代碼好像沒什么卵用(單純是把接收到的數據不知道做什么算術運算),刪掉也不影響串口打印,如果有大佬知道它的作用,歡迎在下面指出。
2.拋磚引玉
既然接收編碼會了,那么用軟件編程發射如何?
店家在郵寄紅外芯片和遙控器的同時,還送了一顆紅外發射二極管。理論上使用51單片機調制pwm也能實現電子信號到紅外信號的調制。
使用單片機收發紅外線信號實現機器間通訊是另一個值得深挖的好問題,先按下不表。
關于連續信號的接收問題
在網上只找到了stm32/樹莓派版本的帶連續信號判定的代碼,如果我的文章能夠引出哪位大佬寫代碼實現51單片機連續信號的接收,我將感激不盡。

IR reader.zip

1.44 KB, 下載次數: 33, 下載積分: 黑幣 -5

源代碼

HX1838.docx

1.98 MB, 下載次數: 19, 下載積分: 黑幣 -5

技術日記本體

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:624685 發表于 2022-2-8 09:43 | 只看該作者
樓主辛苦了,非常詳細,謝謝
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美国产一区二区 | 亚洲国产午夜 | 欧美精品一区二区在线观看 | 成人在线视频网 | 欧美精品在线一区二区三区 | 欧美激情欧美激情在线五月 | 91小视频在线 | 欧美综合一区二区 | 欧美在线高清 | 中文字幕乱码亚洲精品一区 | 亚洲欧美综合 | 九色在线视频 | 欧美日一区 | 亚洲风情在线观看 | 992人人草| 337p日本欧洲亚洲大胆鲁鲁 | 国产精品视频一区二区三区四区国 | 九色在线观看 | 777zyz色资源站在线观看 | 久久综合av | 成人精品视频在线观看 | 台湾a级理论片在线观看 | 99综合网| 91精品国产91久久久久久吃药 | 久久精品中文字幕 | 亚洲美女视频 | 亚洲人成人一区二区在线观看 | 日韩精品一二三 | 午夜精品在线观看 | 国产情侣啪啪 | 亚洲成av | 欧美亚洲视频在线观看 | 免费久久久| 91亚洲精| www.日韩免费| 欧美在线a| 国产欧美一区二区三区另类精品 | 欧美三级网站 | 日韩精品一区二区三区中文在线 | 国产精品成人一区二区三区 | 在线色网 |