紅外 IR 協議原理分析

1、概述:
對多種紅外遙控器的信號進行分析,其發出的紅外指令中,引導碼各不相同,而且後面的控制指令也有較大差別,甚至指令碼的位數也不相同,原因是這些紅外設計沒有遵守相同的紅外標準。但是其基本思想是相同的,即採用不同週期和不同佔空比的脈衝分別表示邏輯0及1,只要根據期佔空比及脈衝週期進行解析即可得到具體的按鍵碼值。

2、協議種類:
市面上基本上有如下幾大類協議:
NEC with simple repeat code 
NEC with full repeat code 
TC9012 
松下7051碼
SONY碼
RC5/RC6A

3、協議datasheet表(引用hisi整理的統計表)
NEC with simple repeat code 碼


NEC with full repeat code 碼


TC9012和SONY碼:


4、數據格式
基本上紅外都是以38MHz作爲載波頻率,即每一位時間爲1.12ms或2.25ms

NEC with simple repeat code數據格式由START(引導碼)+數據碼+burst突發幀三部分組成
發送單個幀格式:


發送重複幀格式,收到第一個完整幀數據後,接下來收到的數據幀由簡化的引導碼和burst信號組成




其它的編碼本質上都差不多,例如松下7051編碼:
遙控器紅外發射信號的編碼格式:引導碼+設備碼+鍵碼+循環延時

引導碼 = 3640us (高電平)+ 1800us(低電平)
"高電平"爲紅外線載波調製,"低電平"爲無紅外線載波調製。 

設備碼 = 32位: 
格式 = 碼0(S)8位 + 碼1(Z)8位 + 碼2(Y)8位 + 碼3(X)8位; 

鍵值碼 = 16位: 
格式 = 數據碼0(8位)+數據碼1(8位); 
邏輯'0':= 380us (高電平)+ 380us(低電平); 
邏輯'1'= 380us (高電平)+ 1350us(低電平); 

循環延時=50ms,其誤差≤5%;


表示先檢測到引導碼,然後進入開始統計設備碼及鍵值碼共48位,最後按下不入進入repeat模式進行延時50ms。


5、基本編程方法
1、註冊ISR中斷
   request_irq(IR_IRQ_NO, (irq_handler_t)Ir_Isr, IRQF_DISABLED, NULL, HI_NULL);
2、處理Ir_Isr函數,根據寄存器IR_RCV狀態將獲得的鍵值(高低電平值)寫入隊列(data_l,data_h)
3、在定時器中處理隊列數據,如每隔10ms或者50ms時間檢測並將隊列值送入到ir decode器中
4、ir decode處理,本質就是比較高低電平持續時間確定出具體的鍵值



/* d1 寄存器中讀取的值,d2爲協議定義的標準值,margin爲誤差碼值 */
#define FACTOR        15/100
static inline int pulse_eq_margin(unsigned int d1, unsigned int d2, unsigned int margin)
{
return ((d1 > (d2 - margin)) && (d1 < (d2 + margin)));
}


首先判定引導碼:
3640us (高電平)+ 1800us(低電平)引導碼
pulse_eq_margin(data_l,header_pulse,header_pulse*FACTOR)
pulse_eq_margin(data_l,header_space,header_space*FACTOR)


然後再根據其狀態進行取值
比如松下7051碼可定義如下狀態:
IR_STATE_INACTIVE, // 空閒狀態
IR_STATE_HEADER_SPACE,
IR_STATE_BIT_PULSE,
IR_STATE_BIT_SPACE,
IR_STATE_FRAME_PULSE,
IR_STATE_FRAME_SPACE,
IR_STATE_REPEAT_PULSE,
IR_STATE_REPEAT_SPACE,


定義的重要數據結構如下:
unsigned int wanted_bits;        /* 需要等待接收的位數,比如7051就需要接收48位*/
  unsigned int header_pulse;       /* Unit:μs 3640*/
  unsigned int header_space;       /* Unit:μs 1800*/
unsigned int bit0_pulse;         /* Unit:μs 380*/
unsigned int bit0_space;/* Unit:μs 380*/
unsigned int bit1_pulse;/* Unit:μs 380*/
unsigned int bit1_space;/* Unit:μs 1350*/
unsigned int frame_units;/* Unit:μs 380*/
unsigned int frame_end_space;    /* more than frame_end_space 50ms即 50000μs*/
unsigned int repeat_pulse;    /* no repeat 0 ex>NEC:9000*/
unsigned int repeat_space;/* no repeat 0 ex>NEC:2250*/


然後就是求值:
if(pulse_eq_margin(data_time,bit1_space,frame_units>>1)){
data->bits |= (unsigned long long)(((unsigned long long)1)<<data->count)
}
其中bits用於保存鍵值,只有出現邏輯'1'時才須對其賦值,count用於計算位於STATE_BIT_SPACE累加值

其中會涉及到一些較細節的知識就不在此複述了,提供一種思路給大家,都有規律可偱。


原文地址:http://blog.csdn.net/andyhuabing/article/details/7717200


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章