黃 華,李曉鋒,曾小寶
(張家界航空工業(yè)職業(yè)技術(shù)學(xué)院,湖南 張家界 427000)
紅外線是光譜中波長為0.76~1.5μm的一段不可見光,紅外光波長短、方向性好,對復(fù)雜電磁環(huán)境不敏感,通常使用的紅外發(fā)射器件(紅外發(fā)光管)與紅外接收器件(光敏二極管、三極管)的發(fā)光與受光峰值波長一般在0.8~0.94μm,二者的光譜正好重合,能夠很好的匹配[1]。利用紅外光的這種特點(diǎn),實(shí)現(xiàn)點(diǎn)對點(diǎn)的直接數(shù)據(jù)傳輸,可以獲得較高的傳輸效率及可靠性,因此廣泛用于紅外遙控系統(tǒng)。目前采用單片機(jī)實(shí)現(xiàn)紅外解碼已經(jīng)得到普遍運(yùn)用,但大多采用中斷加延時(shí)等待的方法實(shí)現(xiàn),但在實(shí)時(shí)系統(tǒng)中通常不能長時(shí)間地延時(shí)等待,這使得該方法使用范圍受到限制。筆者研究使用賽元推出的低成本單片機(jī)SC92F8463B結(jié)合有限狀態(tài)機(jī)實(shí)現(xiàn)紅外解碼,具有較少資源占用和高可靠性的特點(diǎn)。
SC92F8463B是一顆增強(qiáng)型的高速1T 8051內(nèi)核工業(yè)級集成觸控按鍵功能的Flash微控制器,指令系統(tǒng)完全兼容傳統(tǒng)8051產(chǎn)品系列。SC92F8463B內(nèi)部集成有16 Kbytes Flash ROM、1 Kbytes SRAM 、128 bytes EEPROM、最多26個(gè)GPI/O、13個(gè)IO可外部中斷、3個(gè)16位定時(shí)器、11路12位高精度ADC、6路獨(dú)立10位PWM、內(nèi)部1%高精度高頻12/6/2 MHz振蕩器和4%精度低頻128K振蕩器、可外接晶體振蕩器、一個(gè)UART,一個(gè)UART/SPI/IIC三選一通信口SSI。SC92F8463B具有非常優(yōu)異的抗干擾性能和性能極好的觸控按鍵性能,非常適合應(yīng)用于各種使用場合的觸控按鍵和主控控制,如大小智能家電和智能家居、物聯(lián)網(wǎng)、無線通訊、游戲機(jī)等工業(yè)控制和消費(fèi)應(yīng)用領(lǐng)域。
不同公司在紅外遙控中采用了不同的編碼格式,其中比較常用的是NEC標(biāo)準(zhǔn)。遙控器采用頻率為38 kHz、占空比為1/3的紅外光發(fā)射編碼信號,編碼信號由引導(dǎo)碼、客戶碼、客戶反碼、數(shù)據(jù)碼和數(shù)據(jù)反碼組成。引導(dǎo)碼由9 ms的載波和4.5 ms的SPACE信號組成??蛻舸a及客戶反碼16位、數(shù)據(jù)碼及數(shù)據(jù)反碼16位,共32位,客戶碼用于區(qū)別不同的紅外遙控設(shè)備,防止不同機(jī)種遙控碼的相互干擾,后16位為8位的操作碼和8位的操作反碼,用于核對數(shù)據(jù)是否接收正確,接收端依據(jù)數(shù)據(jù)碼的值判斷應(yīng)該執(zhí)行何種操作。NEC協(xié)議典型的編碼脈沖如圖1所示。
在編碼信號中,邏輯1采用560μs的載波和1.69 μs的SPACE信號表示,邏輯0采用560μs的載波和560μs的SPACE信號組成,如圖2、圖3所示。
圖1 NEC標(biāo)準(zhǔn)的紅外碼
圖2 邏輯1的定義
圖3 邏輯0的定義
NEC協(xié)議還規(guī)定,若按鍵超過108 ms仍未松開,將每隔108 ms發(fā)送一個(gè)Repeat Code信號,信號由9ms的起始碼和2.5 ms的SPACE信號組成,如圖4所示。
圖4 Repeat Code的定義
本設(shè)計(jì)采用一體化紅外接收頭接收紅外遙控信號,接收頭檢測到38kHz的載波信號后,將輸出高電平,因此紅外解碼的關(guān)鍵是檢查接收頭輸出引腳的電平變化,并識別信號高低電平持續(xù)時(shí)間。
本方案中使用SC92F8463B的外部中斷檢測引腳電平變化,在后臺啟動一個(gè)定時(shí)器用于計(jì)時(shí)。SC92F8463B的外部中斷相對于傳統(tǒng)51單片機(jī)的優(yōu)點(diǎn)在于可以設(shè)置為下降沿、上升沿和雙沿觸發(fā),在中斷處理程序中,清0計(jì)時(shí)器,并改變觸發(fā)邊沿設(shè)置,在下一次觸發(fā)中斷時(shí),計(jì)時(shí)器的計(jì)數(shù)值就是一個(gè)電平的持續(xù)時(shí)間。采用有限狀態(tài)機(jī)進(jìn)行紅外解碼時(shí),需要根據(jù)紅外遙控協(xié)議設(shè)計(jì)多個(gè)狀態(tài),每一個(gè)狀態(tài)代表已經(jīng)檢測到某一個(gè)信號,在中斷服務(wù)程序中,根據(jù)當(dāng)前的狀態(tài)和電平持續(xù)時(shí)間來判斷是否協(xié)議規(guī)定時(shí)間,并轉(zhuǎn)移到新的狀態(tài)。
根據(jù)NEC的編碼規(guī)范,筆者設(shè)計(jì)出如圖5所示的紅外解碼狀態(tài)圖。圖中IDLE_STATE狀態(tài)代表空閑,沒有檢測到紅外信號。下降沿觸發(fā)中斷,轉(zhuǎn)移到RECEIVE 9MS LEADING狀態(tài),該狀態(tài)代表已經(jīng)檢測到紅外信號,并期待9ms的引導(dǎo)電平,RECEIVE 4.5 ms SPACE狀態(tài)代表已經(jīng)接收到9ms LEADING,期待4.5ms的SPACE信號,Receive 32bit Data狀態(tài)作為一個(gè)過渡狀態(tài),進(jìn)入到1、0 Identtify狀態(tài),判斷SPACE的長度進(jìn)而識別邏輯1或0,32bit識別完成后,回到IDLE_STATE狀態(tài),完成一次紅外解碼,設(shè)置標(biāo)志變量,通知用戶程序處理紅外遙控命令[2]。狀態(tài)圖中也引入了RECEIVE Repaeat Code用于識別重復(fù)按鍵信號。
圖5 紅外解碼狀態(tài)圖
根據(jù)狀態(tài)圖,可以較容易地實(shí)現(xiàn)紅外解碼的中斷處理函數(shù)。關(guān)鍵代碼如下所示,因?yàn)槠拗?,所附代碼中省略了部分狀態(tài)的實(shí)現(xiàn)。代碼中有幾點(diǎn)值得特別說明,第一,每次中斷通過取反INT1F、INT1R改變了中斷觸發(fā)的邊沿;第二,電平持續(xù)時(shí)間是通過讀取TH0、TL0實(shí)現(xiàn)的;第三,電平持續(xù)時(shí)間判斷是將其與一個(gè)范圍比較,以提高程序的抗干擾能力。
void irdecode_isr(void) interrupt 2
{
static unsigned char ir_receive_bits=0;
unsigned char i=0;
uint16_t interval=MAKEWORD(TH0,TL0);//捕捉兩次中斷之間的時(shí)間
TL0=0;TH0=0;//清零計(jì)數(shù)器,
INT1F^=(1<<0);//改變電平觸發(fā)邊沿
INT1R^=(1<<0);
switch(ir_decode_state)
{
case eIR_IDLE://此狀態(tài)下,引腳為高電平,等待下降沿觸發(fā)中斷
ir_decode_state=eIR_LEADING_9MS;
break;
case eIR_LEADING_9MS:
if(interval>8000 && interval<10000){
ir_decode_state=eIR_LEADING_4MS5;
}else{
ir_decode_state=eIR_IDLE;
}
break;
...
case eIR_IDENTIFY_1or0:
i=ir_receive_bits>>3;
ir_receive_buffer[i]>>=1;
if(interval>1380&&interval<1980)
{//1.6785ms
ir_receive_buffer[i]|=0x80;
}
++ir_receive_bits;
ir_decode_state=eIR_32BIT_DATA;
break;
}
}
本紅外解碼方案采用有限狀態(tài)機(jī)技術(shù),避免了長時(shí)間的延時(shí),有效地提高了系統(tǒng)的實(shí)時(shí)性;方案使用的硬件資源只有一個(gè)雙沿觸發(fā)的外部中斷引腳和一個(gè)定時(shí)器資源,這在各種低成本單片機(jī)中都是標(biāo)配硬件資源,可移植性強(qiáng)。