编码格式 现有的红外遥控包括两种方式:PWM(脉冲宽度调制)和PPM(脉冲位置调制)。 两种形式编码的代表分别为NEC 和 PHILIPS的RC-5、RC-6以及将来的RC-7。 PWM(脉冲宽度调制):以发射红外载波的占空比代表“0”和“1”。为了节省能量,一般情况下,发射红外载波的时间固定,通过改变不发射载波的时间来改变占空比。例如常用的电视遥控器,TOSHIBA的TC9012,其引导码为载波发射4.5ms,不发射4.5ms,其“0”为载波发射0.56ms,不发射0.565ms,其“1”为载波发射0.56ms,不发射1.69ms。如图所示。 PPM(脉冲位置调制):以发射载波的位置表示“0”和“1”。从发射载波到不发射载波为“0”,从不发射载波到发射载波为“1”。其发射载波和不发射载波的时间相同,都为0.68ms,也就是每位的时间是固定的。 脉冲宽度调制方式的遥控芯片,典型代表为TC9012,其他类型的芯片大同小异的。这里就已TC9012型芯片来分析。 图 1 为了提高遥控器的发射具体,肯定得提高红外发射管的功率,如果给发射管发以未经调制的信号,一来发射距离会非常短;二来很容易把发射管给烧掉。所以一般我们都会将发射的信号进行调制后再发送出去。 从图1,我们可以知道,在主频为455KHz下将单个脉冲调制为37.91KHz . 调制频率 f(CAR) =1 /Tc =f(osc) /12 =455KHz /12 =37.91666……. 也就是常用的红外调制频率 38KHz 其占空比为 1/3
这是发送的一个完整帧,依次为 引导码, 用户识别码, 用户识别码反码,操作码,操作码反码。
上图的一个波形代表引导码的 4.5ms高(其实里面包含更小的调制脉冲,记住只要是红外发送的所有高电平都是经过调制的,而低电平不调制,只是让发射管截止便可,这一点很重要), 接着是4.5ms 低电平。后面跟着一个 C0,其脉冲代表 0。 下图的一个波形代表引导码的 4.5ms高, 接着是4.5ms 低电平。后面跟着一个 C0,其脉冲代表 1。 上图分别为 0 和 1 的脉冲宽带形式,其中高电平其实里面包含了更小的调制脉冲(大概是 0.56ms /(12 /455KHZ) =21 个调制脉冲)
编码的一帧长度为 108ms
大家按照上图的方法,分析数据0, 和 1 其实也是一样的原理,一个新的数据为开始总是以以个下降沿开始的,所以这就为我们的程序编写提供了便利。采用外部中断 + 定时器,便可以完整无误的刻画出遥控器发来的任何编码序列。
下面我将以一个实际的解码程序来具体分析其原理。主要是在AT89S52单片机上开发,代码非常简单,解码的核心代码仅是蓝色部分,小巧精悍。 //++++++++++++++++++++++++++++++++++//YangYong_Infrared.h #ifndef __YangYong_Infrared_H__ #ifndef uchar #ifndef uint #ifndef InfraredDatas } InfraredDatas; #define ON 0xff /*#define Lead_Code 0x01 //#define Debug_Mode ON /*#define Timer0_TH0 0xff //11.0592MHz晶振 #define Time_Counter_MAX 400 #endif //++++++++++++++++++++++++++++++++++//YangYong_Infrared.h
//++++++++++++++++++++++++++++++++++//main.c #include "reg52.h" #define uchar unsigned char extern void InfraredDatas_Judge(void); //the main fun EA=1; //开总中断 Uart_Send_Byte(0xc7); while(1) //if you have other code ,add your other code here } } //++++++++++++++++++++++++++++++++++//main.c
//++++++++++++++++++++++++++++++++++//Interrupt.c #include "reg52.h" #define uchar unsigned char void InitInterrupt_INT0(void) IT0=1; //INT1下降沿中断 //int0 interrupt } /++++++++++++++++++++++++++++++++++//Interrupt.c /++++++++++++++++++++++++++++++++++//InfraredDatas_Judge.c #include "YangYong_Infrared.h" //extern uchar DataBuffer[4]; extern InfraredDatas Infrared_Datas; extern uchar ReceiveDataSucessful; extern void Private_Function0 (void); void InfraredDatas_Judge(void) /*if( Infrared_Datas.Address0 != 0x0e ) switch( Infrared_Datas.Code ) case 0x01: Private_Function1(); case 0x02: Private_Function2(); case 0x03: Private_Function3(); case 0x04: Private_Function4(); case 0x05: Private_Function5(); case 0x06: Private_Function6(); case 0x07: Private_Function7(); case 0x08: Private_Function8(); case 0x09: Private_Function9(); case 0x0a: Private_Function10(); case 0x0b: Private_Function11(); case 0x0c: Private_Function12(); case 0x0d: Private_Function13(); case 0x0e: Private_Function14(); case 0x0f: Private_Function15(); case 0x10: Private_Function16(); case 0x11: Private_Function17(); case 0x12: Private_Function18(); case 0x13: Private_Function19(); case 0x14: Private_Function20(); case 0x15: Private_Function21(); case 0x16: Private_Function22(); case 0x17: Private_Function23(); case 0x19: Private_Function25(); case 0x1a: Private_Function26(); case 0x1b: Private_Function27(); case 0x1c: Private_Function28(); case 0x1d: Private_Function29(); case 0x1e: Private_Function30(); case 0x1f: Private_Function31(); default : break; } } } /++++++++++++++++++++++++++++++++++//InfraredDatas_Judge.c /++++++++++++++++++++++++++++++++++//Time.c #include "reg52.h" extern uint TimeCounter ; extern void ReceiveFail(void); //timer init //timer0/counter0 interrupt } /++++++++++++++++++++++++++++++++++//Time.c /++++++++++++++++++++++++++++++++++//Infrared.h #define uchar unsigned char typedef struct InfraredDatas } InfraredDatas /++++++++++++++++++++++++++++++++++//Infrared.h /++++++++++++++++++++++++++++++++++//Infrared.c #include "reg52.h" #define uchar unsigned char //uchar DataBuffer[4]; InfraredDatas Infrared_Datas; extern void Uart_Send_Byte(uchar Data); void Receive_Infrared_Datas(void) if(LeadCode ==0) #if Debug_Mode == ON #endif LeadCode =0xff; #if Debug_Mode == ON #endif ReceiveData &= 0x7f; #if Debug_Mode == ON #endif ReceiveData |= 0x80; #endif
TR0 =0; //关定时器0
/++++++++++++++++++++++++++++++++++//Infrared.c
/++++++++++++++++++++++++++++++++++//Uart.c #include "reg51.h" #define uchar unsigned char uchar SendBusy =0x00; void Uart_Send_Byte(uchar Data); void Uart_Send_Byte(uchar Data) while(SendBusy !=0 ); } //UART init TR1=1; PS =1; //uart interrupt } /++++++++++++++++++++++++++++++++++//Uart.c 在以前条件缺乏,没有数字示波器,所以调试红外超麻烦。而此红外编解码程序的解码正确率非常高。希望对大家有所帮助。 附件中将会提供完整的过程文件,直接编译便可。如有疑问,请留言。 附件中将会提供 一份常见遥控器编码格式资料。
标签:
|
|