| 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累加值
 其中会涉及到一些较细节的知识就不在此复述了,提供一种思路给大家,都有规律可偱。
 
 |