應(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è)值。