歡迎您光臨本站 登入註冊首頁

紅外遙控解碼器

admin @ 2014-03-26 , reply:0

概述

    你家裡是否有一個電視機遙控器或者空調機遙控器呢?你是否也想讓它遙控其他的電器甚至讓它遙控您的電腦呢?那好,跟我一起做這個“紅外遙控解碼器&r……

     你家裡是否有一個電視機遙控器或者空調機遙控器呢?你是否也想讓它遙控其他的電器甚至讓它遙控您的電腦呢?那好,跟我一起做這個“紅外遙控解碼器”。
     該小製作所需要的元件很少:單片機TA89C2051一隻,RS232介面電平與TTL電平轉換心片MAX232CPE 一隻,紅外接收管一隻,晶振11.0592MHz,電解電容10uF4隻,10uF一隻,電阻1K1個,300歐姆左右1個,瓷片電容30P2個。發光二極體8個。價錢不足20元。

電路原理:
    主控制單元是單片機AT89C2051,中斷口INT0跟紅外接受管U1相連,接收紅外信號的脈衝,8個發光二極體作為顯示解碼輸出(也可以用來擴展接其他控制電路),U3是跟電腦串列口RS232相連時的電平轉換心片,9、10腳分別與單片機的1、2腳相連,(1腳為串列接收,2腳為串列發送),MAX232CPE的7、8腳分別接電腦串列口的2(接收)腳、3(發送腳)。晶振採用11.0592MHz,這樣才能使得通訊的波特率達到9600b/s,電腦一般默認值是9600b/s、8位數據位、1位停止位、無校驗位。
 
    電路就這麼簡單了,現在分析具體的編程過程吧。
    如圖所示,panasonic遙控器的波形是這樣的(經過反覆測試的結果)。
 
    開始位是以3.6ms低電平然後是3.6ms高電平,然後數據表示形式是0.9ms低電平0.9ms高電平周期為1.8ms表示“0”, 0.9ms低電平 2.4ms高電平周期為3.3ms表示“1”,編寫程序時,以大於3.4ms小於3.8ms高電平為起始位,以大於2.2ms小於2.7ms高電平表示“1”,大於0.84ms小於1.11ms高電平表示“0”。因此,我們主要用單片機測量高電平的長短來確定是“1”還是“0”即可。定時器0的工作方式設置為方式1:mov tmod,#09h,這樣設置定時器0即是把GATE置1,16位計數器,最大計數值為2的16次方個機器周期,此方式由外中斷INT0控制,即INT0為高時才允許計數器計數。比如:
jnb p3.2,$
jb p3.2,$
clr tr0
這3條指令就可以測量一個高電平,接下來讀取計數值TH0,TL0就可以分辨是起始位還是“1”或“0”。在確定碼錶之前,您可以使用P0口的8個發光二極體來顯示編碼,16位編碼分兩次顯示:
mov p0,keydata
acall delay_1s ;//1ms延時子程序
mov p0,keydata+1
ljmp main
根據P0相繼的兩次顯示的編碼,記錄每個按鍵的編碼,形成編碼表,即遙控器編碼的解碼完畢。碼錶確定之後,以後接收到遙控器的編碼之後,就與碼錶比較,找到匹配的碼項,並把該碼項對應的順序號輸出到P0口,同時也把順序號向串列口輸出到電腦,電腦接收該數據後由串口軟體決定如何處理。
     程序不長,下面是完整的程序和註釋:(先看流程圖)
 
keydata equ 30h ;//該地址和31H地址用來存放遙控器按鍵編碼。
org 00h
main:
 mov keydata,#0 ;// 清零
 mov tmod ,#09h       ;//設置定時0方式1,GATE=1
      mov  r7,#0  ;//計數器,用來計數是否滿8位
 mov  r6,#0  ;//計數器,用來計數是否滿2位元組(解16位編碼)
 jb p3.2,$  ;//是否為低電平
again:    ;//如果為低,繼續往下面執行
 mov tl0,#0  ;//清零TL0
 mov th0,#0  ;//清零TH0
 setb tr0  ;//開啟定時器0
 jnb p3.2,$  ;//等待高電平到來
 jb p3.2,$ ;//高電平到來,此時開始計數
 clr tr0 ;//高電平結束,停止計數
 mov a,th0 ;//讀取th0 值,TL0忽略不計 
 clr c  ;//
 subb a,#12 ;//
 jc again ;//th0<12則轉,即小於3.4ms,你可以算一下這個時間
 mov a,#14 ;//
 clr c  ;//
 subb a,th0 ;//和14比較,如果TH0>14則大於3.8ms
        jc again    ;//大於3.8ms,從新再檢測
nextbit:  ;//起始位找到了,然後下一位
 mov tl0,#0 ;//
 mov th0,#0 ;//
 setb tr0 ;//啟動定時器
 jnb p3.2,$ ;//等待高電平
 jb p3.2,$  ;//高電平到來,此時開始計數
 clr tr0 ;//高電平結束,停止計數
 mov a,th0 ;//讀取計數值,TL0忽略不計
 clr c  ;//
 subb a,#8 ;//th0和8比較
 jc next  ;;;;//若 <2.2ms則轉,再判斷是否大於0.84ms
 mov a,#10 ;//再跟10比較
 clr c  ;//
 subb a,th0 ;//
 jc again ;;;;;;;//若 >2.7ms,則放棄,從新檢測
 mov a,keydata ;// 符合大於2.2ms 小於2.7ms,即為“1”
 setb c        ;//C = 1
 rrc a  ;//把1移位進A
 mov keydata,a ;//保存
 inc r7  ;//計數器加1
 cjne r7,#8,nextbit ;//是否滿8位
 inc r6   ;//計數加1
 cjne r6,#2,last8 ;//是否滿兩位元組
 sjmp seach  ;//不滿兩位元組,再新採集
last8:    ;//滿1位元組,再接下來第二位元組
 mov keydata+1,a ;//把第一位元組編碼數據保存到31h里
 mov r7,#0  ;//計數器R7清零
 sjmp nextbit  ;//繼續採集數據
next:      ;//小於2.2ms時轉到這裡
 mov a,th0  ;//讀取計數值TH0
 swap a   ;//高4位與低4位對換
 mov r1,a  ;//保存到R1
 anl tl0,#0f0h  ;//取TL0高4位,低4位忽略不計
 mov a,tl0  ;//
 clr c   ;//
 rrc a  ;//
 rrc a  ;//
 rrc a  ;//
 rrc a  ;//
 add a,r1 ;//
 mov r1,a ;//
 subb a,#30 ;//以上幾行是把TH0的低4位和TL0的高4位合併為1位元組作為計數值
 jc nextbit ; //判斷是否 <0.84ms,是則放棄,繼續採集
 mov a,r1 ;//否
 clr c  ;//
 cjne a,#64,continue   ;//跟64比較
continue:  ;//
 jnc nextbit ;  //a>64表示採樣值 >1.11ms  放棄
 mov a,keydata  ;//否則 ,符合位“0”
 clr c          ;//C  = 0
 rrc a   ;//把零右移進A
 mov keydata,a  ;//保存
 inc r7   ;//計數器加1
 cjne r7,#8,nextbit ;//是否滿8位
 inc r6   ;//計數器加1
 cjne r6,#2,last_8 ;//是第一位元組已經滿
 sjmp seach  ;//
last_8:    ;//如果為第二位元組
 mov keydata+1,a ;//則保存第一位元組到31h
 mov r7,#0  ;//清零R7
 sjmp nextbit  ;//
seach:    ;//匹配按鍵編碼
 mov r0,#-2  ;//按鍵編碼位元組個數計數器
 mov r1,#-1  ;//按鍵順序計數器
seach1:   ;//
        inc r0  ;//
seach2:   ;//
 inc r0   ;//
 inc r1   ;//
 cjne r1,#29,compare ;//是否R1=29 
 sjmp exit0  ;//
compare:   ;//開始匹配
  mov a,r0  ;//
 mov dptr,#keycode ;//地址指針指向碼錶首址
 movc a,@a+dptr ;//取碼
 cjne a,keydata,seach1 ;//比較
 inc r0   ;//R0+1,再比較下一位元組(每個按鍵編碼為2位元組)
 mov a,r0  ;//
 ;mov dptr,#keycode ;//
 movc a,@a+dptr ;//比較
 cjne a,keydata+1,seach2 ;//是否匹配,不匹配則繼續跟下一位元組比較
 mov p1,r1         ;//如果匹配,把按鍵順序號輸出到p1
send:    ;//
 mov tmod,#20h     ;   //設置timer 1,mode 2
 mov tl1,#0fdh  ;//設置定時器初值
 mov th1,#0fdh  ;//
 mov scon,#01010000b;//以上設置,即設置串口波特率係數為:9600,8,1,0
 setb tr1  ;//啟動定時器1
loop_s:  ;//
 mov sbuf,r1    ;//把R1(按鍵順序號)輸出到串口
 jnb ti,$  ;//等待是否發送完畢
 clr ti   ;//發送完畢,清零TI
exit0:    ;//
ljmp main   ;//循環

keycode:   ;//每兩位元組代表一個按鍵的編碼
db 11111000b,00000000b,    11111100b,00000000b,    11111001b,11000000b
db 11111100b,11000000b,    11111010b,00000000b,    11111010b,00100000b
db 11111010b,01000000b,    11111010b,01100000b,    11111010b,10000000b
db 11111010b,10100000b,    11111010b,11000000b,    11111010b,11100000b
db 11111011b,00000000b,    11111011b,00100000b,    11111011b,01000000b
db 11111011b,01100000b,    11111111b,01100000b,    11111111b,10100000b
db 10001100b,10001110b,    10001101b,11101110b,    10001100b,10101110b
db 10001101b,11001110b,    11111000b,11100000b,    11111100b,10000000b
db 11111100b,01000000b,    11111001b,10100000b,    11111100b,10100000b
db 11111100b,01100000b
end
---------------------------------------------------------------------------------
各種遙控器編碼不同,如果你採用的是其他遙控器,修改幾個參數即可(當然按鍵的編碼表肯定不同了),即計數器的值不同,不過有的遙控器有機器碼(機器碼每個按鍵都是一樣的),此時可以跳過機器碼的採集。最後有一點想提一下的是,剛開始不知道遙控器的編碼是比較麻煩的,筆者在“雙龍電子“網站下載了個音效卡示波器,用他可以一目了然觀看遙控器的波形,測量其脈衝寬度,有了它確實方便很多,該軟體可以到雙龍公司網站http://www.sl.com.cn/免費下載使用。如果你想用遙控器遙控電腦,你可以自己編寫一個接受串列口應用軟體,或者你可以直接下載使用Girder這個軟體,該軟體是專門為串口遙控器做的,很好用,下載地址為:http://www.girder.nl/,你可以利用這個軟體定義遙控器來遙控你電腦移動滑鼠、鍵盤操作、上網瀏覽、打開播放器、關機等。


[admin via 研發互助社區 ] 紅外遙控解碼器已經有5241次圍觀

http://cocdig.com/docs/show-post-43557.html