红外线遥控器解码程序

合集下载

采用HS0038对万能红外电视遥控器的解码(C51源码)

采用HS0038对万能红外电视遥控器的解码(C51源码)
if (IRsignal==1) //如果0.9ms后IRsignal=1,说明不是引导码
{k=10;break;} /*budong/
else if(k==9) //如果持续了10×0.9ms=9ms的低电平,说明是引导码
{while(IRsignal==0);
/************************* 说 明 *********************************/
/* 以一个9ms的低电平和4.5ms的高电平为引导码,后跟32位二进制代码 */
/* 前16位为8位用户码及其反码,后16位为8位的操作码及其反码 */
}
IRcode[i]=CodeTemp;
CodeTemp=0;
}
Delay();
}
}
EA=1;
}
/**************************主程序*************************/
IRcode[3]=0x00;
P0=IRcode[3];
while(1);
}
}
/************************中断0解码服务子程序**********************/
void int0(void) interrupt 0 using 2
{
EA=0;/*不懂/
for(k=0;k<10;k++)
{Delay0_9ms();
for(j=18;j>0;j--)
for(k=20;k>0;k--) ;
}
/***************************延时1ms子程序**********************/

一文教会你红外线遥控器软件解码程序

一文教会你红外线遥控器软件解码程序

一文教会你红外线遥控器软件解码程序
红外线一开始发送一段13.5ms的引导码,引导码由9ms的高电平和4.5ms的低电平组成,跟着引导码是系统码,系统反码,按键码,按键反码,如果按着键不放,则遥控器则发送一段重复码,重复码由9ms的高电平,2.25ms的低电平,跟着是一个短脉冲。

#includeat89x52.h
#defineNULL0x00//数据无效
#defineRESET0X01//程序复位
#defineREQUEST0X02//请求信号
#defineACK0x03//应答信号,在接收数据后发送ACK信号表示数据接收正确,
也位请求信号的应答信号
#defineNACK0x04//应答信号,表示接收数据错误
#defineBUSY0x05//忙信号,表示正在忙
#defineFREE0x06//空闲信号,表示处于空闲状态
#defineREAD_IR0x0b//读取红外
#defineSTORE_IR0x0c//保存数据
#defineREAD_KEY0x0d//读取键值
#defineRECEIVE0Xf400//接收缓冲开始地址
#defineSEND0xfa00//发送缓冲开始地址
#defineIR0x50//红外接收缓冲开始地址
#defineHEAD0xaa//数据帧头
#defineTAIL0x55//数据帧尾
#defineSDAP1_7
#defineSCLP1_6
unsigned char xdata *buf1;//接受数据缓冲。

红外遥控器软件解码及其应用

红外遥控器软件解码及其应用

红外遥控器软件解码及其应用红外遥控器软件解码及其应用摘要:通过对红外遥控器各按键发送冲波形的分析可以识别码型,从而为软件解码提供依据。

本文以实例介绍红外遥控器与单片机的硬件接口,并从原理出发给出软件解码的方法。

这是一个可以直接引用的成功例子,同时也为各类红外遥控器在单片机控制产品中的开发应用提供了一个非常实用的参考。

关键词:遥控器软件解码单片机在单片机控制产品的开发应用中,为了向控制系统软件控制命令,键盘往往是不可缺少的。

传统方法是利用并行输入/输出接口芯片扩展一个键盘接口,或者直接利用单片机的并行端口进行扩展。

在某些应用环境下,这种方式2个弊端:①键盘和控制系统连在一起,不灵活,环境适应性差;②浪费单片机的端口,且硬件成本较高。

使用红外遥控器作为控制系统的输入设备,具有成本低、灵活方便的特点。

本文目的就在于介绍软件解码研究的一般方法和红外遥控器进行二次开发的应用技术。

该方法已在多个应用系统设计中成功地实现,效果良好。

红外遥控器是一种非常容易买到,且价格便宜的产品,种类很多,但它们都是配合某种特定电子产品的(如各种电视机、VCD、空调器等),由专用CPU解码,作为一般的单片机控制系统能直接使用。

使用现成遥控器作为控制系统的输入,需要解决如下几个问题:如何接收红外遥控信号;如何识别红外遥控信号;解码软件的设计。

其它的问题都是非本质的,例如遥控器面板功能键标注的问题,可自行设计、重印即可。

1红外遥控信号的接收接收电路可以使用集成红外接收器成品。

接收器包括红外接收管和信号处理IC.接收器对外只有3个引脚:Vcc、GND和1个脉冲信号输出PO.与单片机接口非常方便,如图1所示。

①Vcc接系统的电源正极(+5V);②GND接系统的地线(0V);③脉冲信号输出接CPU的中断输入引脚(例如8031的13脚INT1)。

采取这种连接方法,软件解既可工作于查询方式,也可工作于中断方式。

2脉冲流分析要了解一个未知的遥控器,首先要分析其脉冲流,从而了解其脉冲波形特征(以何种方式携带“0”、“1”信息),进而了解其编码规律。

利用AVR(M8)的输入捕获(ICP)对万能红外线遥控器进行解

利用AVR(M8)的输入捕获(ICP)对万能红外线遥控器进行解

利用A VR(M8)的输入捕获(ICP)对万能红外线遥控器进行解码本实例程序为自创,若转载请注明出处,谢谢!小弟不久前买了一个科朗公司出版的万能电视遥控器RM-2008,用作对设备的红外遥控,折腾了几天,今天终于弄清楚了如何对该遥控器进行解码,很开心,所以把成果与各位大虾分享,有什么错误的地方请指正。

万能遥控器在使用前一般要进行设置,针对RM-2008这款万能遥控,设置方法如下:先按住“设置”键不放,再按下“电源”(“开/关”)键,工作指示灯亮起,然后释放两键,在此时进入代码输入状态,依次键入0 0 0 指示灯熄灭,设置成功!说明一下:0 0 0 编码是日立公司初期的红外编码方式,也就是网上到处都通用的红外编码方式(如下图),另外本程序只能对此编码进行解码数据头的时间:Th=9+4.5=13.5ms数据“0”的时间:T0=0.565+0.56=1.125ms数据“1”的时间:T1=1.685+0.56=2.245ms本程序通过使用输入捕获功能(ICP)捕捉红外信号的高电平脉宽,达到解码的目的;如果捕获到的脉宽是4.5ms 则表示此信号为同步码,如果捕获到的脉宽是1.685ms 的话则表示“1”否则表示“0”测试电路如下:使用DNW 串口调试软件时的效果/////////////////////////////////只有一个文件main.c/////////////////////////////////// #include <avr/io.h>#include <avr/signal.h>#include <avr/interrupt.h>#include <avr/wdt.h>#include <util/delay.h>#include <stdio.h>/*----------------------遥控操作值--------------------*/// key code (hex)#define Key_1 0x01#define Key_2 0x02#define Key_3 0x03#define Key_4 0x04#define Key_5 0x05#define Key_6 0x06#define Key_7 0x07#define Key_8 0x08#define Key_9 0x09#define Key_0 0x00#define Menu 0x5c // 菜单#define Menu_up 0x56 // 菜单上#define Menu_down 0x57 // 菜单下#define Menu_left 0x5f // 菜单左#define Menu_right 0x5b // 菜单右#define Menu_ok 0x16 // 菜单确认#define Channel_up 0x1b // 频道+ #define Channel_down 0x1f // 频道- #define Sound_up 0x1e // 音量+ #define Sound_down 0x1a // 音量- #define Open_Close 0x12 // 开/关#define Mute 0x10 // 静音#define Pic_in_pic 0x51 //画中画#define Standard 0x58 // 制式#define Return 0x52 // 返回#define Times 0x0b // 倍数#define Screen 0x16 // 屏幕#define Audio 0x1d // 伴音#define NICAM 0x13 // 丽音#define TV_Vedio 0x0f // 电视/视频#define Sleep 0x0e //睡眠/*----------------------常用参数定义-------------------*/ #define P0 0#define P1 1#define P2 2#define P3 3#define P4 4#define P5 5#define P6 6#define P7 7#define FREQ 8 //定义单片机工作频率为8M#define uint unsigned int#define uchar unsigned char#define Start_T1 TCCR1B|=_BV(CS11);TCNT1=0//复位预计分频器并开启定时器T1#define Stop_T1 TCCR1B&=~_BV(CS11) //关闭定时器T1/*-----------------IR信号指示灯操作函数---------*/#define EN_IR_LED DDRB|=_BV(P1)#define CLR_IR_LED PORTB&=~_BV(P1)#define SET_IR_LED PORTB|=_BV(P1)/*----------------------某些端口操作-------------------*/volatile unsigned char i,j,k;volatile unsigned long IRcode; //定义一个长度为4字节的无符号long 类型变量来存储代码volatile unsigned char *IRcodePointer ; //定义一个无符号的单字节指针变量,//用此地址变量来分别读取IRCode的//4个字节其中操作码为IRcodePointer[2]//用户码为IRcodePointer[0]volatile unsigned char IRReceiveEffective=0; //IR信号接收有效当程序响应接收以后请马上清零这样才会继续接收下一IR码volatile unsigned char IRReceiveCurrentBit=0; //IR信号当前接收位0时表示第0位即同步码(4.5ms高电平)volatile unsigned int Pulse_length=0; //捕获的脉冲宽度volatile unsigned char ICP_Parity=0; //捕获中断奇偶次计数1时为偶次并在此时判断脉宽volatile unsigned char Received_Key_Temp; //红外接收操作键缓存const unsigned char String[]={"You Have Press Key : "};/*----------------------串口定义-------------------*/unsigned char SetPrintfConvertMode=0; //使用printf作其他转换,并非输出到UARTvoid Uart_Init(void);int System_putchar(char c, FILE *stream);int System_getchar(FILE *stream);FILE mystd = FDEV_SETUP_STREAM(System_putchar,System_getchar,_FDEV_SETUP_RW);/*----------------------常用函数定义------------------*/void delay_nms(unsigned int ms) //N ms延时函数{for(i=0;i<ms;i++)_delay_loop_2(FREQ*250);}/*----------------------系统初始化函数定义------------------*/void IO_INIT(void){PORTB|=_BV(P0); //设置ICP引脚内部上拉经过试验验证,上拉会提高红外接收灵敏度}ISR(TIMER1_COMPA_vect){IRReceiveCurrentBit=0;//重置IR接收位为第0位,为下次接收做准备TIMSK&=~_BV(OCIE1A); //关闭溢出中断TCCR1B|=_BV(ICES1); //设置输入捕获上升沿有效ICP_Parity=0;Stop_T1;CLR_IR_LED;}ISR(TIMER1_CAPT_vect){if(!IRReceiveEffective){if(ICP_Parity==0){ICP_Parity++;TIMSK|=_BV(OCIE1A);TCCR1B&=~_BV(ICES1); //设置输入捕获下降沿有效Start_T1 ;}else{Stop_T1;ICP_Parity=0;TCCR1B|=_BV(ICES1);//设置输入捕获上升沿有效Pulse_length=ICR1;if(IRReceiveCurrentBit==0){if(Pulse_length>=3500&&Pulse_length<5500)// 如果是引导码(4.5ms) 进入下一个bit的读取IRReceiveCurrentBit++;}else if(IRReceiveCurrentBit<33) //接收32位数据{IRcode>>=1;if(Pulse_length<1900&&Pulse_length>1400) //判断是否为1 ( 1.685 ms) IRcode|=0x80000000;IRReceiveCurrentBit++;if(IRReceiveCurrentBit==33){IRReceiveCurrentBit=0; //重置IR接收位为第0位,为下次接收做准备if(IRcodePointer[0]==(unsignedchar)(~IRcodePointer[1])&&IRcodePointer[2]==(unsignedchar)(~IRcodePointer[3])){SET_IR_LED; //开启IR信号指示灯IRReceiveEffective=1; //数据有效}delay_nms(5); //因为32位数据后面还有一个信号上跳变,所以要适当延时,延时0.65ms以上即可}}}}}/////////////////////////////////////////////////////////////////int main(void){wdt_disable();IO_INIT();Uart_Init();TCCR1B=_BV(WGM12)|_BV(CS11);//采用8分频这样的话TCNT1的计数时基为1usOCR1A=8000; //TCNT1 计数上限设置IR接收超时这里设置8msTIMSK|=_BV(TICIE1);//开启输入捕获中断TCCR1B|=_BV(ICES1);//输入捕获上升沿有效EN_IR_LED; //IR信号指示灯允许CLR_IR_LED; //关闭IR信号指示灯IRcodePointer=&IRcode;sei();while(1){if(IRReceiveEffective){Received_Key_Temp=IRcodePointer[2];//把接收到的操作键放入缓存IRReceiveEffective=0; //允许下一次接收switch(Received_Key_Temp){case Key_1 : printf("\n%sKey_1",String);break;case Key_2 : printf("\n%sKey_2",String);break;case Key_3 : printf("\n%sKey_3",String);break;case Key_4 : printf("\n%sKey_4",String);break;case Key_5 : printf("\n%sKey_5",String);break;case Key_6 : printf("\n%sKey_6",String);break;case Key_7 : printf("\n%sKey_7",String);break;case Key_8 : printf("\n%sKey_8",String);break;case Key_9 : printf("\n%sKey_9",String);break;case Key_0 : printf("\n%sKey_0",String);break;case Menu : printf("\n%sMenu",String);break;case Menu_up : printf("\n%sMenu_up",String);break;case Menu_down : printf("\n%sMenu_down",String);break;case Menu_left : printf("\n%sMenu_left",String);break;case Menu_right : printf("\n%sMenu_right",String);break;case Menu_ok : printf("\n%sMenu_ok",String);break;case Channel_up : printf("\n%sChannel+",String);break;case Channel_down : printf("\n%sChannel-",String);break;case Sound_up : printf("\n%sSound+",String);break;case Sound_down : printf("\n%sSound-",String);break;case Open_Close : printf("\n%sOpen_Close",String);break;case Mute : printf("\n%sMute",String);break;case Standard : printf("\n%sStandard",String);break;case Return : printf("\n%sReturn",String);break;case Times : printf("\n%sTimes",String);break;//case Screen : printf("\n%sScreen",String);break;//Screen 与menu_ok 值相同case Audio : printf("\n%sAudio",String);break;case NICAM : printf("\n%sNICAM" ,String);break;case TV_Vedio : printf("\n%sTV_Vedio",String);break;case Sleep : printf("\n%sSleep",String);break;case Pic_in_pic : printf("\n%sPic_in_pic",String);break;default:printf("\n%sOther Key 0x%x",String,Received_Key_Temp);break;}CLR_IR_LED; //处理完数据以后关闭IR信号指示灯}}}/*----------------------串口函数实体------------------*/void Uart_Init(void){UCSRB=_BV(RXEN)|_BV(TXEN);UBRRL=25; //8M 19200stdout=&mystd;stdin=&mystd;}int System_putchar(char c, FILE *stream){if(SetPrintfConvertMode==1){}else{if (c == '\n')System_putchar('\r', stream);loop_until_bit_is_set(UCSRA, UDRE);UDR = c;}return 0;}int System_getchar( FILE *stream){loop_until_bit_is_set(UCSRA,RXC);return UDR;}/////////////////////////////////程序结束////////////////////////////。

红外线遥控解码接收程序-C语言

红外线遥控解码接收程序-C语言
delay1000()
{
uchar i,j;
i=5;
do{j=95;
do{j--;}
while(j);
i--;
}while(i);
}
/*---------------------------延时882us子程序-----------------------*/
date[i]>>=1;
date[i]=date[i]|0x80;
}
} //1位数据接收结束
} //32位二进制码接收结束
/*-----------------------红外解码程序(核心)-----------------*/
/*----------------------------------------------------------*/
void IR_decode()
{
uchar i,j;
//在STC12C5410上运用红外线解码程序.主要的问题在于延迟上。
#include <regx51.h>
#define uchar unsigned char
#define uint unsigned int
#define IR_RE P3_2
bit k=0; //红外解码判断标志位,为0则为有效信号,为1则为无效
红外线遥控解码接收程序-C语言
#include <regx51.h>
#define uchar unsigned char
#define uint unsigned int
#define IR_RE P3_2
bit k=0; //红外解码判断标志位,为0则为有效信号,为1则为无效

红外遥控器程序及原理、程序

红外遥控器程序及原理、程序
Data=1;//收到数据 1 } else if(Tim>=10 && Tim<50) {
Data=0;//收到数据 0 }
if(Ok==1) {
hw_jsm<<=1; hw_jsm+=Data;
if(Num>=32)
{ hw_jsbz=1; break }
EXTI_ClearITPendingBit(EXTI_Line15); }
printf_init(); //printf 初始化
while(1)
{
if(hw_jsbz==1) //如果红外接收到
{
hw_jsbz=0;
//清零
printf("红外接收码 %0.8X\r\n",hw_jsm); //打印
hw_jsm=0;
//接收码清零
}
}
}
1.1 红外遥控简介简介 红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低, 成本低,易实现等显著优点,被诸多电子设备特别是家用电器广泛采用,并越来越多的应用 到计算机系统中。 由于红外线遥控不具有像无线电遥控那样穿过障碍物去控制被控对象的能力,所以,在 设计红外线遥控器时,不必要像无线电遥控器那样,每套(发射器和接收器)要有不同的遥控 频率或编码(否则,就会隔墙控制或干扰邻居的家用电器),所以同类产品的红外线遥控器, 可以有相同的遥控频率或编码,而不会出现遥控信号“串门”的情况。这对于大批量生产以 及在家用电器上普及红外线遥控提供了极大的方面。由于红外线为不可见光,因此对环境影 响很小,再由红外光波动波长远小于无线电波的波长,所以红外线遥控不会影响其他家用电 器,也不会影响临近的无线电设备。 红外遥控的编码目前广泛使用的是: NEC Protocol 的 PWM(脉冲宽度调制)和 Philips RC-5 Protocol 的 PPM(脉冲位置调制)。 普中科技 STM32 开发板配套的遥控器使用的是 NEC 协议,其特征如下: 1、 8 位地址和 8 位指令长度; 2、地址和命令 2 次传输(确保可靠性) 3、 PWM 脉冲位置调制,以发射红外载波的占空比代表“ 0”和“ 1”; 4、载波频率为 38Khz; 5、位时间为 1.125ms 或 2.25ms; NEC 码的位定义:一个脉冲对应 560us 的连续载波,一个逻辑 1 传输需要 2.25ms ( 560us 脉冲+1680us 低电平),一个逻辑 0 的传输需要 1.125ms( 560us 脉冲+560us 低 电平) 。而遥控接收头在收到脉冲的时候为低电平,在没有脉冲的时候为高电平,这样, 我们在接收头端收到的信号为:逻辑 1 应该是 560us 低+1680us 高,逻辑 0 应该是 560us 低+560us 高。 NEC 遥控指令的数据格式为:同步码头、地址码、地址反码、控制码、控制反码。同步 码由一个 9ms 的低电平和一个 4.5ms 的高电平组成,地址码、地址反码、控制码、控制 反 码均是 8 位数据格式。按照低位在前,高位在后的顺序发送。采用反码是为了增加传输的 可靠性(可 用于校验)。 2.数据码格式 数据格式包括了引导码、用户码、数据码和数据码反码,编码总占 32 位。数据反码是数据 码反相后的编码,编码时可用于对数据的纠错。注意:第二段的用户码也可以在遥控应用电 路中被设置成第一段用户码的反码。

遥控器红外解码数码管显示

遥控器红外解码数码管显示
void tim0_isr (void) interrupt 1 using 1
{
irtime++; //用于计数2个下降沿之间的时间
}
/*------------------------------------------------
外部中断0中断处理
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
sbit IR=P3^2; //红外接口标志
#define DataPort P0 //定义数据端口程序中遇到DataPort则用P0替换
sbit LATCH1=P2^2;//定义锁存使能端口段锁存
{
for(j=1;j<=8;j++) //处理1个字节8位
{
cord=irdata[k];
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
value|=0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcord[i]=value;
value=0;
}
irpro_ok=1;//处理完毕标志位置1
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main(void)

红外遥控解码程序

红外遥控解码程序

红外遥控解码程序红外接收头的型号有很多HS0038 VS838等功能⼤致相同,只是引脚封装不同。

红外接收有⼏种统⼀的编码⽅式,采样哪种编码⽅式取决于遥控器使⽤的芯⽚,接收头收到的都是⼀样的。

电视遥控器使⽤的是专⽤集成发射芯⽚来实现遥控码的发射,如东芝TC9012,飞利浦AA3010T等,通常彩电遥控信号的发射,就是将某个按键所对应的控制指令和系统码(由0和1组成的序列),调制在38KHz的载波上,然后经放⼤、驱动红外发射管将信号发射出去。

不同公司的遥控芯⽚,采样的遥控码格式也不⼀样,较普遍的有两种,⼀种NEC标准,⼀种是PHILIPS标准。

NEC标准:遥控载波的频率为38KHz(占空⽐1:3)当某个键按下时,系统⾸先发射⼀个完整的全码,如果按键超过108ms仍未松开,接下来发射的代码(连发代码)将由起始码(9ms)和结束码(2.5ms)组成。

⼀个完整的全码 = 引导码 +⽤户码 +⽤户码 + 数据码 + 数据码 + 数据反码。

其中,引导码⾼电平9ms,低电平4.5ms;系统码8位,数据码8位,共32位;其中前16位为⽤户识别码,能区别不同的红外遥控设备,以防⽌不同的机种遥控码互相⼲扰。

后16位为8位的操作码和8位的操作反码,⽤于核对数据是否接收准确。

收端根据数据码做出应该执⾏上⾯动作的判断。

连发代码是在持续按键时发送的码。

它告知接收端。

某键是在被连续的按着。

NEC标准下的发射码表⽰发射数据0时⽤”0.56ms⾼电平 + 0.565ms低电平 = 1.125ms”表⽰;数据1⽤”⾼电平0.56ms + 1.69ms = 2.25ms”表⽰。

遥控器发射信号:需要注意的是:当⼀体化接收头收到38kHz红外信号时,输出端输出低电平,否则为⾼电平。

所以⼀体化接收头输出的波形和发射波形是反向的PHILIPS标准:载波频率38KHz:没有筒,点按键时,控制码1和0之间切换,若持续按键,则控制码不变。

⼀个全码 = 起始码’11’ +控制码 + ⽤户码 + ⽤户码数据0⽤“低电平1.778ms + ⾼电平1.778ms”表⽰;数据1⽤“⾼电平1.778ms + 低电平1.778ms”表⽰。

红外解码程序

红外解码程序

红外解码程序本篇介绍红外解码的原理和程序的写法。

下面来看一下,红外线是如何编码的。

下面来具体说一下,解码的原理,每按一下遥控器的一个按键,遥控器就会发出32个“0”“1”代码(当然是通过高低电平的占空比来判断是0还是1的),具体是0,1是如何编码的上面图片中有介绍,和一个引导码,引导码的作用是告诉处理器,接下来将要开始发送代码,我们在编写程序时,当检测到引导码时,就应该准备接受数据了。

32位代码中的前16位是用户识别码,不同的遥控器不相同,防止互相干扰的,后16是8为数据码,和8位数据反码。

接下来开始介绍如何解码程序的编写。

程序中用到了两个中断,一个是定时器中断,一个是外部中断。

定时器中断用来准确计时,判断接受的代码是0还是1,外部中断用来准确确定定电平到来的时刻,然后开始计时。

/*********************************************************函数功能:红外解码,用八位数码管显示红外线的按键码,便于红外控制测试环境:hot 51学习板编译环境:keil4整理人:张家越QQ:435835181整理时间:2011-04-03************************************************************/#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code seg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0 x6f,0x77,0x7c,0x39,0x5E,0x79,0x71 };//0-f的段选码unsigned char code seg_we[]={0,1,2,3,4,5,6,7};uchar irtime,startflag,bitnum,irreceok;uchar irdata[33];uchar irprosok;uchar display[8];uchar ircode[8] ;sbit led1=P0^1;sbit led2=P0^2;/******************************************************************** ****函数功能:延时函数,在数码管显示时使用,不需要很精确********************************************************************* ****/void delay_50us(uint t){uchar j;for(;t>0;t--)for(j=19;j>0;j--);}/******************************************************************** ******函数的功能:定时器0的初始化********************************************************************* *****/void timer0init(){TMOD=0x02; //设置定时器工作在方式2TH0=0x00; //TL0=0x00; //设置定时器的初值ET0=1; //开定时器中断TR0=1; // 打开定时器EA=1; //开总中断}/******************************************************************** ****外部中断1的初始化********************************************************************* **/void int1init(){IT1=1; //设置触发方式为上升沿EX1=1; //开外部中断1EA=1; //开总中断}/******************************************************************** **定时器0的功能函数,每中断一次irtime++,用于计时********************************************************************* **/void timer0() interrupt 1{irtime++; //定时器中断一次irtime++,用于计时}/******************************************************************** ***外部中断0的处理函数,每当有低电平数据过来时,中断一次,(使用次中断的前提是,信号线必需接在外部中断0上面,也就是P3^2口),函数功能是,把信号从高低电平变成时间的代码放入irdata【】中********************************************************************* ***/void int1() interrupt 2{if(startflag){if(irtime>32) //一组代码检测完毕{bitnum=0;}irdata[bitnum]=irtime; //把检测到的时间送到数组irdata【】中去irtime=0;bitnum++;if(bitnum==33) //如果检测到bitnum=33,说明32位用户码已经检测完毕{bitnum=0; //将bitnum清零以便重新计数irreceok=1; //接收完毕标志位置一}}else //(此函数先进入else语句,跳过引导码的检测){startflag=1; //将开始标志位置一irtime=0; //设置时间初值为零irreceok=1; //接收完毕标志位置一}}/******************************************************************** *****函数功能:把irdata【】中的时间代码转换成二进制代码存放在ircode【】中********************************************************************* *****/void irpros(){uchar k=1,value,j,i;for(j=0;j<4;j++){for(i=0;i<8;i++){value=value>>1; //右移7次(第一次是00,相当于没有移位)if(irdata[k]>6) //循环8次{value=value|0x80;}k++;}ircode[j]=value;}irprosok=1;}/******************************************************************** ********函数的功能是:将ircode【】中的二进制代码转换成为16进制代码便于在数码管上显示******************************************************************* ********/void irwork(){display[0]=ircode[0]/16;display[1]=ircode[0]%16;display[2]=ircode[1]/16;display[3]=ircode[1]%16;display[4]=ircode[2]/16;display[5]=ircode[2]%16;display[6]=ircode[3]/16;display[7]=ircode[3]%16;}/******************************************************************** ****函数功能:用数码管显示解码结果********************************************************************* ***/void display1(){uchar i;for(i=0;i<8;i++){P2=seg_we[i];P0=seg_du[display[i]];delay_50us(40);}}void main(){timer0init(); //定时器初始化int1init(); //外部中断初始化while(1){if(irreceok) //判断数据接收完毕(数组中存储的是高低电平的时间){irpros(); //执行处理函数,将高低电平时间转化成16进制的0,1代码,存放在数组中irreceok=0; //标志清零}if(irprosok) //处理函数执行完毕,{irwork(); //将存储的16进制代码分离,便于数码管显示irprosok=0; //标志清零}display1();}}//在最后我再分析一下程序的编写思路,便于大家理解,一旦有按键按下,接受管接收到引导码,进入外部中断,并将高低电平的时间放入irdata【】数组中,接受完毕标志位置一,判断接受标志位,为1,进行处理函数,将高低电平转换成16进制数,处理标志位置一,判断处理标志位,为1,执行分离函数,将16进制数分离,便于数码管显示,分离完毕后显示。

用单片机解码红外遥控器

用单片机解码红外遥控器

用单片机解码红外遥控器遥控器使用方便,功能多.目前已广泛应用在电视机、VCD、DVD、空调等各种家用电器中,且价格便宜,市场上非常容易买到。

如果能将遥控器上许多的按键解码出来.用作单片机系统的输入.则解决了常规矩阵键盘线路板过大、布线复杂、占用I/O口过多的弊病。

而且通过使用遥控器,操作时可实现人与设备的分离,从而更加方便使用。

下面以TC9012编码芯片的遥控器为例。

谈谈如何用常用的51系统单片机进行遥控的解码。

一、编码格式1、0和1的编码遥控器发射的信号由一串O和1的二进制代码组成.不同的芯片对0和1的编码有所不同。

通常有曼彻斯特编码和脉冲宽度编码。

TC9012的O和1采用PWM方法编码,即脉冲宽度调制,其O码和1码如图1所示(以遥控接收输出的波形为例)。

O码由O.56ms低电平和0.56ms高电平组合而成.脉冲宽度为1.12ms.1码由0.56ms低电平和1.69ms高电平组合而成.脉冲宽度为2.25ms。

在编写解码程序时.通过判断脉冲的宽度,即可得到0或1。

2、按键的编码当我们按下遥控器的按键时,遥控器将发出如图2的一串二进制代码,我们称它为一帧数据。

根据各部分的功能。

可将它们分为5部分,分别为引导码、地址码、地址码、数据码、数据反码。

遥控器发射代码时.均是低位在前。

高位在后。

由图2分析可以得到.引导码高电平为4.5ms,低电平为4.5ms。

当接收到此码时.表示一帧数据的开始。

单片机可以准备接收下面的数据。

地址码由8位二进制组成,共256种.图中地址码重发了一次。

主要是加强遥控器的可靠性.如果两次地址码不相同.则说明本帧数据有错.应丢弃。

不同的设备可以拥有不同的地址码.因此。

同种编码的遥控器只要设置地址码不同,也不会相互干扰。

图中的地址码为十六进制的0EH(注意低位在前)。

在同一个遥控器中.所有按键发出的地址码都是相同的。

数据码为8位,可编码256种状态,代表实际所按下的键。

数据反码是数据码的各位求反,通过比较数据码与数据反码.可判断接收到的数据是否正确。

红外遥控器解码程序

红外遥控器解码程序

//===================================================================== //// 红外遥控器解码程序演示//// 本程序主要将现在比较常用TX1300遥控器进行解码,将解码后的数据通过P2端////口的数码管显示出来,为了更好的看到运行过程,特加了三个指示灯用来指示当////前运行状态.P10主要用来闪亮,表示程序正在运行,P11则用来表示接收到数据, ////P12表示触发内部的定时器操作.P13的闪亮表示正确接收完一个数据. //// 程序运行效果: 打开本机电源开关,可以看到P10不停的闪动,按下遥控器的数////字键,数码管则显示相应的数字键(1-9).可以看到P11,P12在显示后呈亮状态.则////可以接收下一个数据,在上面过程中可以看到P13闪亮了一下.表明上次正确接收////到数据. ////---------------------------------------------------------------------//// 开发日期: 2009/01/30 研发单位:上海腾芯实业有限公司//#include <reg52.h> //包含51单片机相关的头文件#define uint unsigned int //重定义无符号整数类型#define uchar unsigned char //重定义无符号字符类型uchar code LedShowData[]={0x03,0x9F,0x25,0x0D,0x99, //定义数码管显示数据0x49,0x41,0x1F,0x01,0x19};//0,1,2,3,4,5,6,7,8,9uchar code RecvData[]={0x07,0x0A,0x1B,0x1F,0x0C,0x0D,0x0E,0x00,0x0F,0x19};uchar IRCOM[7];static unsigned int LedFlash; //定义闪动频率计数变量unsigned char RunFlag=0; //定义运行标志位bit EnableLight=0; //定义指示灯使能位/***********完成基本数据变量定义**************/sbit S1State=P1^0; //定义S1状态标志位sbit S2State=P1^1; //定义S2状态标志位sbit B1State=P1^2; //定义B1状态标志位sbit IRState=P1^3; //定义IR状态标志位sbit RunStopState=P1^4; //定义运行停止标志位sbit FontIRState=P1^5; //定义FontIR状态标志位sbit LeftIRState=P1^6; //定义LeftIR状态标志位sbit RightIRState=P1^7; //定义RightIRState状态标志位/*************完成状态指示灯定义*************/sbit S1=P3^2; //定义S1按键端口sbit S2=P3^4; //定义S2按键端口/*************完成按键端口的定义*************/sbit LeftLed=P2^0; //定义前方左侧指示灯端口sbit RightLed=P0^7; //定义前方右侧指示灯端口/*************完成前方指示灯端口定义*********/sbit LeftIR=P3^5; //定义前方左侧红外探头sbit RightIR=P3^6; //定义前主右侧红外探头sbit FontIR=P3^7; //定义正前方红外探头/*************完成红外探头端口定义***********/sbit M1A=P0^0; //定义电机1正向端口sbit M1B=P0^1; //定义电机1反向端口sbit M2A=P0^2; //定义电机2正向端口sbit M2B=P0^3; //定义电机2反向端口/*************完成电机端口定义***************/sbit B1=P0^4; //定义话筒传感器端口sbit RL1=P0^5; //定义光敏电阻端口sbit SB1=P0^6; //定义蜂鸣端口/*********完成话筒,光敏电阻,蜂鸣器.端口定义**/sbit IRIN=P3^3; //定义红外接收端口/*********完成红外接收端口的定义*************/#define ShowPort P2 //定义数码管显示端口extern void ControlCar(uchar CarType); //声明小车控制子程序void delayms(unsigned char x) //0.14mS延时程序{unsigned char i; //定义临时变量while(x--) //延时时间循环{for (i = 0; i<13; i++) {} //14mS延时}}void Delay() //定义延时子程序{ uint DelayTime=30000; //定义延时时间变量while(DelayTime--); //开始进行延时循环return; //子程序返回}void IR_IN() interrupt 2 using 0 //定义INT2外部中断函数{unsigned char j,k,N=0; //定义临时接收变量EX1 = 0; //关闭外部中断,防止再有信号到达delayms(15); //延时时间,进行红外消抖if (IRIN==1) //判断红外信号是否消失{EX1 =1; //外部中断开return; //返回}while (!IRIN) //等IR变为高电平,跳过9ms 的前导低电平信号。

红外遥控器软件解码及其应用

红外遥控器软件解码及其应用

红外遥控器软件解码及其应用摘要:通过对红外遥控器各按键发送冲波形分析可以识别码型,从而为软件解码提供依据。

本文以实例介绍红外遥控器与单片机硬件接口,并从原理出发给出软件解码方法。

这是一个可以直接引用成功例子,同时也为各类红外遥控器在单片机控制产品中开发应用提供了一个非常实用参考。

关键词:遥控器软件解码单片机在单片机控制产品开发应用中,为了向控制系统软件控制命令,键盘往往是不可缺少。

传统方法是利用并行输入/输出接口芯片扩展一个键盘接口,或者直接利用单片机并行端口进行扩展。

在某些应用环境下,这种方式2个弊端:①键盘和控制系统连在一起,不灵活,环境适应性差;②浪费单片机端口,且硬件成本较高。

使用红外遥控器作为控制系统输入设备,具有成本低、灵活方便特点。

本文目就在于介绍软件解码研究一般方法和红外遥控器进行二次开发应用技术。

该方法已在多个应用系统设计中成功地实现,效果良好。

红外遥控器是一种非常容易买到,且价格便宜产品,种类很多,但它们都是配合某种特定电子产品(如各种电视机、VCD、空调器等),由专用CPU解码,作为一般单片机控制系统能直接使用。

使用现成遥控器作为控制系统输入,需要解决如下几个问题:如何接收红外遥控信号;如何识别红外遥控信号;解码软件设计。

其它问题都是非本质,例如遥控器面板功能键标注问题,可自行设计、重印即可。

1 红外遥控信号接收接收电路可以使用集成红外接收器成品。

接收器包括红外接收管和信号处理IC。

接收器对外只有3个引脚:Vcc、GND和1个脉冲信号输出PO。

与单片机接口非常方便,如图1所示。

①Vcc接系统电源正极( 5V);②GND接系统地线(0V);提示请看下图:③脉冲信号输出接CPU中断输入引脚(例如803113脚INT1)。

采取这种连接方法,软件解既可工作于查询方式,也可工作于中断方式。

2 脉冲流分析要了解一个未知遥控器,首先要分析其脉冲流,从而了解其脉冲波形特征(以何种方式携带“0”、“1”信息),进而了解其编码规律。

keilc51红外遥控解码程序

keilc51红外遥控解码程序

keilc51红外遥控解码程序keil c51红外遥控解码程序本keil c51程序适用uPC1621/uPC1622及兼容的红外遥控器芯片,占用外部中断0和定时器1,以中断方式解码,节省系统资源,以查询方式检测遥控信号是否有效.解码思路:红外线经一体化接受头解码放到后送到单片机的外部中断0,单片机设置外部中断下降沿触发,T0和T1为16位定时器,T0在系统启动后定时5ms.T1在外部中断0启动后开始定时,初值为0,每次在INT0中断后先读T1计数值,并重设初值为0,而且判断T1的计数值,18.unsigned char IR_repeat=0;19.unsigned char IR_ready=0;20.unsigned char IR_poweron=0;21.//bit ir_done=0;22.// time constants23.unsigned int IRtimer=0; // IR timeout24.25.//cpu初始化26.void cpu_init(void)27.{28.TMOD=0X11; // T0 and T1 十六位定时29.TH0=0xee; //fosc=11.0592M,timer=5ms30.TL0=0x00;31.TR0=1; // run timer 0;32.TF0=0;33.34.ET0=1; // enable tmr 0 overflow interrupt35.IT0=1; // int0 edge sensitive36.EX0=1; // enable "int0"37.EA=1; // global interupt enable38.}39.40.//T0中断41.void tmrint() interrupt 142.{43.TH0=0xee;44.TL0=0x00;45.if (IRtimer) //IR接收超时46.--IRtimer; //47.else48.{49.IRstate=IR_idle;50.// IR_poweron=0;51.}52.}53.54.//Fosc=11.0592MHz55.#define msec_12p5 0x2d0056.#define msec_15 0x360057.#define msec_9 0x206658.//#define msec_9 0x106659.#define msec_2p5 0x90060.#define msec_0p9 0x33d61.#define msec_1p68 0x61062.63.64.//void IRint() interrupt 0(void)65.66.//When the IR receive pin goes low and interrupt is ge nerated67.// IR is collected by starting timer 2 in the first falling edge of the pin68.// then on every other falling edge, the timer value i s saved and the timer restarted .69.// the captured time is then used to get the IR data70.// a "start of data" is 13.5Msec,a "1" is 2.25Msec,a "0" i s 1.12 msec and a "repeat" is 11.25msec.71.// the counter increments at 1.085 Usec72.// I allow a fairly large tolerance to time jitter but there are no false triggers seen.73.74.void IRint() interrupt 075.{76.static unsigned char bits;77.unsigned short time;78.switch(IRstate)79.{80.case IR_idle:81.TL1=0;82.TH1=0;83.TR1=1;84.IRstate=IR_waitstart;85.IRtimer=26;86.break;87.case IR_waitstart: //P2_4=!P2_4;88.TR1=0;89.time=TH1;90.time =(time <<8)+TL1;;91.TL1=0;92.TH1=0;93.TR1=1;94.if ((time > msec_12p5)&&(time < msec_15)) // greate r than 12.5Msec & less than 15 msec = start code95.{96.IRaddr=0;97._IRaddr=0;98.IRdata=0;99._IRdata=0;100.bits=1;101.IRstate=IR_getaddr;102.}103.else if ((time > msec_9)&&(time < msec_12p5))// les s than 12.5Msec and greater than 9 msec =Repeat code 104.{105.IR_repeat=2;106.IRstate=IR_idle;107.}108.else109.{ // to short, bad data just go to idle110.IRstate=IR_idle;111.}112.break;113.case IR_getaddr: // P2_4=!P2_4;114.TR1=0;115.time=TH1;116.time =(time <<8)+TL1;;117.TL1=0;118.TH1=0;119.TR1=1;120.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle121.{122.IRstate=IR_idle;123.break;124.}125.if (time>msec_1p68)// greater than 1.68Msec is a 1126.{127.IRaddr|= bits;128.}129.bits=bits<<1;130.if (!bits)131.{132.IRstate=IR_getaddrinv;133.bits=1;134.}135.break;136.case IR_getaddrinv: //P2_4=!P2_4;137.TR1=0;138.time=TH1;139.time =(time <<8)+TL1;;140.TL1=0;141.TH1=0;142.TR1=1;143.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle144.{145.IRstate=IR_idle;146.break;147.}148.if (time>msec_1p68)// greater than 1.68Msec is a 1 149.{150._IRaddr|= bits;151.}152.bits=bits<<1;153.if (!bits)154.{155.IRstate=IR_getdata;;156.bits=1;157.}158.break;159.case IR_getdata:160.TR1=0;161.time=TH1;162.time =(time <<8)+TL1;;163.TL1=0;164.TH1=0;165.TR1=1;166.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle167.{168.IRstate=IR_idle;169.break;170.}171.if (time>msec_1p68)// greater than 1.68Msec is a 1172.{173.IRdata|= bits;174.}175.bits=bits<<1;176.if (!bits)177.{178.IRstate=IR_getdatainv;179.bits=1;180.}181.break;182.case IR_getdatainv:183.TR1=0;184.time=TH1;185.time =(time <<8)+TL1;;186.TL1=0;187.TH1=0;188.TR1=1;189.if ((time>msec_2p5)||(time<msec_0p9)) // if > 2.5mse c or shorter than .9Msec bad data , go to idle190.{191.IRstate=IR_idle;192.break;193.}194.if (time>msec_1p68)// greater than 1.68Msec is a 1 195.{196._IRdata|= bits;197.}198.bits=bits<<1;199.if (!bits) // we have it all , now we make sure it i s a NEC code from the CHS IR transmitter200.{ // make sure address,~address are correc t , data ,~data are correct and address is 0.201.IR_ready=((IRaddr^_IRaddr)==0xff)&&((IRdata^_IRda ta)==0xff)&&(IRaddr==0);202.if(IR_ready)203.{204.IRstate=IR_idle;205.}206.}207.break;208.default:209.IRstate=IR_idle;210.break;211.}212.}213.214.void main(void) 215.{216.cpu_init();217.while(1)218.{219.if(IR_ready)220.{221.IR_ready=0;222.switch(IRdata) 223.{224.case 0x45: //1 225.//your code226.break;227.case 0x44: //3 228.//your code229.break;230.case 0x43: //4 231.//your code232.break;233.case 0x08: //prev 234.//your code235.break;236.case 0x5a: //next 237.//your code238.break;239.default:240.break;241.&n bsp; } 242.}243.}。

红外遥控解码程序

红外遥控解码程序

1./*************************************************************************2.** 红外遥控器解码程序(采用中断)----基于SM0038接收芯片3.**说明:采用P2.0口中断,可通过修改IR_IN和P2来切换中断口的选择.4.**使用方法: 当IR_FLAG==1时,表示有键按下,全局变量IR_KeyValue是键号.5.** IR_KeyValueN--按键非码;IR_KeyValueSB--遥控器识别码6.** IR_UK--用户自定义的键号7.** 使用此模块时应先执行 IR_Init()8.**使用示例: if(IR_FLAG==1)9.** {10.** IR_FLAG=0;//每次使用时须将标志位清零.11.** Display_Int(IR_KeyValue,0x90);12.** }13.*************************************************************************/14.15.16.#include "ir_key.h"17.#include "delay.h"18./**********************以下是本程序中使用到的全局变量********************/19.unsigned char IR_BitCnt=0;20.unsigned char IR_KeyValue=10; //按键码(始值不能为按键号中包含的值)21.unsigned char IR_UK=0; //用户定义的键号22.unsigned char IR_KeyValueN=0; //按键非码;按键码+按键非码=0xff23.long int IR_KeyValueSB=0; //遥控器识别码.24.unsigned char IR_FLAG = 0; //有键按下时此标志为125.26./*****************************************************************************27.**此结构休是为键号转换用,IR_KV为遥控器本身的键号,IR_UK为用户自定义的按键号28.*****************************************************************************/29. struct IR_KEY30.{31. unsigned char IR_KV;//遥控器自身键码32. unsigned char IR_UV;//user's value33.};34./*****************************************************************************35.**通过修改结构体数组中的值来设定遥控器的键号.36.*******************************************************************************/37.struct IR_KEY IR_UserKEY[IR_NUM]=38.{39. {68,1},{71,2},{14,3},{72,4},{73,5},{81,6},{10,7},{80,8},{74,9},{83,10},40. {18,11},{84,12},{78,13},{75,14},{3,15},{21,16},{86,17},{67,18},{2,19},{76,20},41. {82,21},{79,22},{70,23},{77,24},{69,25},{6,26},{66,27},{65,28},{64,29},{22,30},42. {85,31},{23,32},{9,33},{13,34},{87,35},{15,36},{8,37},{25,38},{24,39},{11,40},43. {0,41},{4,42},{16,43},{19,44},{5,45},{1,46},{17,47},{95,48},{94,49},{30,50},{26,51}44.};45.46.47./*************************************************************************48.**函数名称: IR_DELAY49.**功能描述: 用于延时.50.**调用模块: delay.h51.**全局变量: 无52.****************************************************************************/53.void IR_DELAY(unsigned int delayTime)54.{55. DELAY(delayTime);//延时8MS56.}57.58.59./*************************************************************************60.**函数名称: IR_Init61.**功能描述: 端口初始化设置,在main函数里面应先执行此函数62.**输入变量:无63.**返回值:无64.**调用模块:无65.**全局变量: IR_IN66.****************************************************************************/67.void IR_Init(void)68.{69. P2DIR &=~IR_IN; //端口设置为输入方向70. P2IE |= IR_IN; //使能中断71. P2IES |= IR_IN; //下降沿中断72. P2IFG &=~IR_IN; //为避免程序运行后直接进中断,此处需先将中断标志位清零73. _EINT();74.}75.76.77./*************************************************************************78.**函数名称: IR_getkey79.**功能描述: 读取遥控器键值,包括识别码,非码80.**输入变量: 无81.**返回值: 无82.**调用模块: IR_DELAY();83.**全局变量: IR_Delay_8MS,IR_Delay8MS,IR_IN84.****************************************************************************/85.void IR_getkey(void)86.{87. P2IFG &=~IR_IN;88. P2IE &=~IR_IN;89. /**********以下是判断中断是由按键引起的***************/90. IR_DELAY(IR_Delay_8MS); //延时0.8MS91. if(P2IN & IR_IN) goto IR_NXT;92. IR_DELAY(IR_Delay8MS); //延时8MS93. if(!(P2IN & BIT0)) goto IR_NXT;94. while(!(P2IN & IR_IN));//等待变高95. IR_DELAY(8900); //延时5MS左右96. if(P2IN & IR_IN) goto IR_NXT;97. IR_FLAG = 0;98. /********以下是读取16位识别码*******************/99. IR_KeyValueSB=0;100. for(IR_BitCnt=0;IR_BitCnt<16;IR_BitCnt++)101. {102. while(!(P2IN & IR_IN));//WAIT HIGH103. IR_KeyValueSB >>=1;104. IR_DELAY(IR_Delay_8MS);105. if(P2IN & IR_IN)106. IR_KeyValueSB |=0x80;107. else108. IR_KeyValueSB &=0x7f;109. while(P2IN & IR_IN);//WAIT LOW110. }111. /***********以下是读取8位的键码*******************/ 112. IR_KeyValue=0;113. for(IR_BitCnt=0;IR_BitCnt<8;IR_BitCnt++)114. {115. while(!(P2IN & IR_IN));//WAIT HIGH116. IR_KeyValue >>=1;117. IR_DELAY(IR_Delay_8MS);118. if(P2IN & IR_IN)119. IR_KeyValue |=0x80;120. else121. IR_KeyValue &=0x7f;122. while(P2IN & IR_IN);//WAIT LOW123.124. }125. /************以下是读取8位的非码****************/ 126. IR_KeyValueN=0;127. for(IR_BitCnt=0;IR_BitCnt<8;IR_BitCnt++)128. {129. while(!(P2IN & IR_IN));//WAIT HIGH130. IR_KeyValueN >>=1;131. IR_DELAY(IR_Delay_8MS);132. if(P2IN & IR_IN)133. IR_KeyValueN |=0x80;134. else135. IR_KeyValueN &=0x7f;136. while(P2IN & IR_IN);//WAIT LOW137.138. }139. for(unsigned char i=0;i<20;i++)140. IR_DELAY(IR_Delay8MS);141.IR_NXT:P2IFG &=~IR_IN;142.P2IE |=IR_IN;143.144.IR_FLAG=1;145.}146.147.148./********************************************************* ****************149.**函数名称: IR_getUK150.**功能描述: 根据得到的IR_KeyValue从IR_UserKEY表中查出对应的用户自定义的键值151.**输入变量: 无152.**返回值: 无153.**调用模块: 无154.**全局变量: IR_BitCnt,IR_NUM,IR_UserKEY,IR_KeyValue,IR_UK155.********************************************************** ******************/156.void IR_getUK(void)157.{158.159. for(IR_BitCnt=0;IR_BitCnt<IR_NUM;IR_BITCNT++) pre < **** *************************************************************** ********** **以下是SM0038输入信号引脚的中断函数. *********************************************************** ***************** } IR_UK="IR_UserKEY[IR_BitCnt].IR_UV;" if(IR_ BitCnt="=IR_NUM)" return; { if(IR_KeyValue="=IR_UserKEY[IR_BitC nt].IR_KV)">160.<SCRIPT src="/inc/gg_read2.js"></SCRIPT>。

用查询方式实现车载MP3红外遥控器解码程序

用查询方式实现车载MP3红外遥控器解码程序

用查询方式实现车载MP3红外遥控器解码程序/************************************************************** *******************************程序名:用查询方式实现车载MP3红外遥控器解码程序编写人:编写时间: 2010年8月8日硬件支持: AT89S51 外部12MHZ晶振接口说明:P1.1口接红外接收管,P1.3口接蜂鸣器,P2口数码管位选,P0口数码管段位,将按键的码值通过P0口的8个LED显示出来修改日志:NO.1-/************************************************************** *******************************ORG 0000HJMP MAINMAIN:JNB P1.1,IR ;遥控扫描LJMP MAIN ;在正常无遥控信号时,一体化红外接收头输出是高电平,程序一直在循环。

;====================================== ===========; 解码程序;====================================== ===========IR:;以下对遥控信号的9000微秒的初始低电平信号的识别MOV R6,#10IR_SB:ACALL DELAY882 ;调用882微秒延时子程序JB P1.1,IR_ERROR ;延时882微秒后判断P1.1脚是否出现高电平如果有就退出解码程序DJNZ R6,IR_SB ;重复10次,目的是检测在8820微秒内如果出现高电平就退出解码程序;以上完成对遥控信号的9000微秒的初始低电平信号的识别。

JNB P1.1, $ ;等待高电平避开9毫秒低电平引导脉冲ACALL DELAY2400 ;延时4.74毫秒避开4.5毫秒的结果码mov r7,#16 ;忽略前16位系统识别码jjja:jnb p1.1,$lcall DELAY882mov c,p1.1jnc uuuaLCALL DELAY1000 ;检测到高电平1的话延时1毫秒等待脉冲高电平结束uuua:djnz r7,jjjamov r1,#1AHMOV R2,#2PP:MOV R3,#8JJJJ: JNB P1.1,$ ;等待地址码第一位的高电平信号LCALL DELAY882 ;高电平开始后用882微秒的时间尺去判断信号此时的高低电平状态MOV C,P1.1 ;将P1.1引脚此时的电平状态0或1存入C中JNC UUU ;如果为0就跳转到UUULCALL DELAY1000 ;检测到高电平1的话延时1毫秒等待脉冲高电平结束UUU: MOV A,@R1 ;将R1中地址的给ARRC A ;将C中的值0或1移入A中的最低位MOV @R1,A ;将A中的数暂时存放在R1数值的内存中DJNZ R3,JJJJ ;接收满8位换一个内存INC R1DJNZ R2,PPMOV A,1aHCPL ACJNE A,1BH,IR_ERRORJMP IR_GOTOIR_ERROR:;错语退出LJMP MAIN ;退出解码子程序;====================================== ===========;遥控执行部份;=================================================IR_GOTO:MOV A,1AHMOV P0,A ;将按键的键值通过P0口的8个LED显示出来! CLR P2.0CLR P1.3 ;蜂鸣器鸣响-嘀嘀嘀-的声音,表示解码成功LCALL DELAY2400LCALL DELAY2400LCALL DELAY2400SETB P1.3 ;蜂鸣器停止;清除遥控值使连按失效MOV 1AH,#00HMOV 1BH,#00HMOV 1CH,#00HMOV 1DH,#00HLJMP MAIN;-----------------延时子程序--------------;DELAY882: MOV R4,#20 ;延时子程序1,精确延时882微秒D1: MOV R5,#20DJNZ R5,$DJNZ R4,D1RETDELAY2400: MOV R4,#10; ;延时子程序2,精确延时4740微秒D2: MOV R5,#235DJNZ R5,$DJNZ R4,D2RETDELAY1000: MOV R4,#2 ;延时程序3,精确延时1000微秒D3:MOV R5,#248DJNZ R5,$DJNZ R4,D3RETEND。

红外线遥控器解码程序

红外线遥控器解码程序

红外线遥控器解码程序红外线遥控是目前使用最广泛的一种通信和遥控手段。

由于红外线遥控装置具有体积小、功耗低、功能强、成本低等特点,因 而,继彩电、录像机之后,在录音机、音响设备、空凋机以及玩具等其它小型电器装置上也纷纷采用红外线遥控。

工业设备中, 在高压、辐射、有毒气体、粉尘等环境下,采用红外线遥控不仅完全可靠而且能有效地隔离电气干扰。

1 红外遥控系统通用红外遥控系统由发射和接收两大部分组成,应用编/解码专用集成电路芯片来进行控制操作,如图 1 所示。

发射部分 包括键盘矩阵、编码调制、LED 红外发送器;接收部分包括光、电转换放大器、解调、解码电路。

2 遥控发射器及其编码遥控发射器专用芯片很多,根据编码格式可以分成两大类,这里我们以运用比较广泛,解码比较容易的一类来加以说明, 现以日本 NEC 的 uPD6121G 组成发射电路为例说明编码原理。

当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码 也不同。

这种遥控码具有以下特征:采用脉宽调制的串行码,以脉宽为 0.565ms、间隔 0.56ms、周期为 1.125ms 的组合表示二进制的“0”;以脉宽为 0.565ms、 间隔 1.685ms、周期为 2.25ms 的组合表示二进制的“1”,其波形如图 2 所示。

上述“0”和“1”组成的 32 位二进制码经 38kHz 的载频进行二次调制以提高发射效率,达到降低电源功耗的目的。

然后 再通过红外发射二极管产生红外线向空间发射,如图 3 所示。

UPD6121G 产生的遥控编码是连续的 32 位二进制码组,其中前 16 位为用户识别码,能区别不同的电器设备,防止不同机 种遥控码互相干扰。

该芯片的用户识别码固定为十六进制 01H;后 16 位为 8 位操作码(功能码)及其反码。

UPD6121G 最多额 128 种不同组合的编码。

遥控器在按键按下后,周期性地发出同一种 32 位二进制码,周期约为 108ms。

红外遥控解码

红外遥控解码

红外遥控解码作者:佚名来源:不详录入:Admin更新时间:2008-7-26 19:43:29点击数:3【字体:】编者按:以下是网友编写的遥控解码程序!一种用延时等待的解码方法,比较容易理解,但缺点是占用CPU运行时间,第二种方法用定时器和外中断的解码方法,初学不易理解,但优点也很明显,第二种方法如果能解决连发解码就比较完美,更完善的红外遥控解码程序,请参考本站TOPAV-2008,TOP51-2005所配程序。

解码方法一;//单片机接收红外解读程序\\;硬件结构:8951,P0口数码管段码,P2.0-P2.3为位,P1为8个LED;P3.2为红外接收头,P2.7蜂鸣器,晶振12M;适用UPD6121 6122芯片接收;---------------------------------------------------------ORG 0000HAJMP MAIN ;转入主程序ORG 0003H ;外部中断P3.2脚INT0入口地址AJMP INT ;转入外部中断服务子程序(解码程序);以下为主程序进行CPU中断方式设置MAIN: SETB EA ;打开CPU总中断请求SETB IT0 ;设定INT0的触发方式为脉冲下降沿触发SETB EX0 ;打开INT0中断请求AJMP $;以下为进入P3.2脚外部中断子程序,也就是解码程序INT: CLR EA ;暂时关闭CPU的所有中断请求MOV R6,#10SB: ACALL YS1 ;调用882微秒延时子程序JB P3.2,EXIT ;延时882微秒后判断P3.2脚是否出现高; 电平如果有就退出解码程序DJNZ R6, SB ;重复10次,目的是检测在8820微秒内;如果出现高电平就退出解码程序;以上完成对遥控信号的9000微秒的初始低电平信号的识别。

JNB P3.2, $ ;等待高电平避开9毫秒低电平引导脉冲ACALL YS2 ;延时4.74毫秒避开4.5毫秒的结果码MOV R1,#1AH ;设定1AH为起始RAM区MOV R2,#4;PP: MOV R3,#8JJJJ: JNB P3.2,$ ;等待地址码第一位的高电平信号LCALL YS1 ;高电平开始后用882微秒的时间尺去判断信;号此时的高低电平状态MOV C,P3.2 ;将P3.2引脚此时的电平状态0或1存入C中JNC UUU ;如果为0就跳转到UUULCALL YS3;UUU: MOV A,@R1 ;将R1中地址的给ARRC A ;将C中的值0或1移入A中的最低位MOV @R1,A ;将A中的数暂时存放在R1中DJNZ R3,JJJJ ;接收地址码的高8位INC R1 ;对R1中的值加1,换下一个RAMDJNZ R2,PP ;接收完16位地址码和8位数据码和8位数据反; 码,存放在1AH/1BH/1CH/1DH的RAM中MOV A,1CH ;比较数据码和数据反码是否正确?CPL AXRL A,1DH ;将1CH的值取反后和1DH比较不同则无效丢弃,核对数据是否准确JNZ EXITMOV DPTR,#TAB ;表头地址送指针MOV A,1DHANL A,#0FH ;相与,得到低四位码MOV C A,@A+DPTRMOV 1EH,A ;查表得表码存入1EHMOV A,1DHSWAP AANL A,#0FHMOV C A,@A+DPTRMOV 1FH,A ;查表得高四位码存入1FMOV R7,#20HDISP:MOV P0,1FH ;送数码管显示CLR P2.1ACALL YS2SETB P2.1MOV P0,1EHCLR P2.2ACALL YS2SETB P2.2MOV P1,1DH ;将按键的键值通过P1口的8个LED显示出来!CLR P2.7 ;蜂鸣器鸣响-嘀嘀嘀-的声音,表示解码成功LCALL YS2SETB P2.7 ;蜂鸣器停止DJNZ R7,DISPEXIT: SETB EA ;允许中断RETI ;退出解码子程序YS1: MOV R4,#20 ;延时子程序1,精确延时882微秒D1: MOV R5,#20DJNZ R5,$DJNZ R4,D1RETYS2: MOV R4,#10 ;延时子程序2,精确延时4740微秒D2: MOV R5,#235DJNZ R5,$DJNZ R4,D2RETYS3: MOV R4,#2 ;延时程序3,精确延时1000微秒D3:MOV R5,#248DJNZ R5,$DJNZ R4,D3RETTAB: DB 0C0H,0DEH,0A2H,8AH,9CH,89H,81H,0DAH,80H,88H,90H,85H,0E1H,86H,0A1H,0B1H;数据表,0-9-A-F END你的解码程序和我现在用的解码程序大体是一样的,我自己实际做了一下,发现按下遥控器,接收到红外信号后,数码管闪的厉害。

单片机的红外遥控器解码原理与实现

单片机的红外遥控器解码原理与实现

单片机的红外遥控器解码原理与实现红外遥控器是我们日常生活中常见的电子设备,它通过使用红外线信号与接收器进行通信。

而在这个过程中,单片机起到了解码的重要作用。

本文将介绍单片机解码红外遥控器的原理以及实现方法。

一、红外遥控器的工作原理红外遥控器是一种使用红外线进行通信的设备,它主要由发送器和接收器两部分组成。

发送器将指令数据转换为红外脉冲信号并发送出去,接收器通过接收红外线信号并将其转换为电信号,进而解码为可识别的指令。

而单片机则负责接收并解码红外信号,将其转化为具体的操作。

二、单片机解码红外信号的原理单片机解码红外信号主要分为两个步骤:红外信号的接收和信号的解码处理。

1. 红外信号的接收单片机通过外部的红外接收器接收红外信号。

红外接收器可以通过外部电路将接收到的红外信号转换为电压信号,然后通过单片机的IO 口输入。

2. 信号的解码处理接收到的红外信号经过IO口输入后,单片机需要对信号进行解码处理。

解码的过程涉及到红外信号的标准化和解析。

对于常见的红外遥控器协议,单片机需要能够识别其编码方式,确定其协议格式。

这些协议通常包含了引导码、地址码和指令码等信息。

在解析红外信号时,单片机首先需要识别引导码。

引导码是红外信号的起始标志,通常由高、低电平组成,表示编码的开始。

单片机通过判断引导码的时间长度来确定信号的开始。

接下来,单片机需要识别地址码和指令码。

地址码是用来区分不同的红外遥控器设备,指令码则表示具体的操作指令。

单片机通过判断地址码和指令码的高、低电平时间长度来确定具体的操作。

三、单片机解码红外信号的实现方法单片机解码红外信号有多种实现方法,以下是一种简单的实现示例。

首先,需要连接红外接收器到单片机的IO口,将接收到的信号输入到单片机。

接收到的信号可以通过外部中断的方式触发单片机的中断服务程序。

然后,在中断服务程序中,单片机需要根据红外协议的规则,判断引导码、地址码和指令码的时间长度。

利用计时器或延时函数可以实现对信号时间的测量。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

资料整理自互联网,版权归原作者! 欢迎访问 新势力单片机,嵌入式
专业技术论坛:
红外线遥控器解码程序
Wang1jin 收藏. 交流论坛: / 推荐网站: 个人博客:
红外线遥控是目前使用最广泛的一种通信和遥控手段.由于红外线遥控装置具有体积小,功耗低,功能强,成本低等特点,因 而,继彩电,录像机之后,在录音机,音响设备,空凋机以及玩具等其它小型电器装置上也纷纷采用红外线遥控.工业设备中, 在高压,辐射,有毒气体,粉尘等环境下,采用红外线遥控不仅完全可靠而且能有效地隔离电气干扰.
1 红外遥控系统
通用红外遥控系统由发射和接收两大部分组成,应用编/解码专用集成电路芯片来进行控制操作,如图 1 所示.发射部分 包括键盘矩阵,编码调制,LED 红外发送器;接收部分包括光,电转换放大器,解调,解码电路.
2 遥控发射器及其编码
遥控发射器专用芯片很多,根据编码格式可以分成两大类,这里我们以运用比较广泛,解码比较容易的一类来加以说明, 现以日本 NEC 的 uPD6121G 组成发射电路为例说明编码原理.当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码 也不同.这种遥控码具有以下特征:
采用脉宽调制的串行码,以脉宽为 0.565ms,间隔 0.56ms,周期为 1.125ms 的组合表示二进制的"0";以脉宽为 0.565ms, 间隔 1.685ms,周期为 2.25ms 的组合表示二进制的"1",其波形如图 2 所示.
个人博客:
电子综合站点:


资料整理自互联网,版权归原作者! 欢迎访问 新势力单片机,嵌入式
专业技术论坛:
上述"0"和"1"组成的 32 位二进制码经 38kHz 的载频进行二次调制以提高发射效率,达到降低电源功耗的目的.然后 再通过红外发射二极管产生红外线向空间发射,如图 3 所示.
UPD6121G 产生的遥控编码是连续的 32 位二进制码组,其中前 16 位为用户识别码,能区别不同的电器设备,防止不同机 种遥控码互相干扰.该芯片的用户识别码固定为十六进制 01H;后 16 位为 8 位操作码(功能码)及其反码.UPD6121G 最多额 128 种不同组合的编码.
遥控器在按键按下后,周期性地发出同一种 32 位二进制码,周期约为 108ms.一组码本身的持续时间随它包含的二进制 "0"和"1"的个数不同而不同,大约在 45~63ms 之间,图 4 为发射波形图.
当一个键按下超过 36ms,振荡器使芯片激活,将发射一组 108ms 的编码脉冲,这 108ms 发射代码由一个起始码(9ms), 一个结果码(4.5ms),低 8 位地址码(9ms~18ms),高 8 位地址码(9ms~18ms),8 位数据码(9ms~18ms)和这 8 位数据的反码 (9ms~18ms)组成.如果键按下超过 108ms 仍未松开,接下来发射的代码(连发代码)将仅由起始码(9ms)和结束码(2.5m s)组成.
代码格式(以接收代码为准,接收代码与发射代码反向)
①位定义
个人博客:
电子综合站点:


资料整理自互联网,版权归原作者! 欢迎访问 新势力单片机,嵌入式
专业技术论坛:
②单发代码格式
③连发代码格式
注:代码宽度算法:
16 位地址码的最短宽度:1.12×16=18ms
易知 8
16 位地址码的最长宽度:2.24ms×16=36ms
位数据代码及其 8 位反代码的宽度和不变:(1.12ms+2.24ms)×8=27ms
∴32
位代码的宽度为(18ms+27ms)~(36ms+27ms)
个人博客:
电子综合站点:


资料整理自互联网,版权归原作者! 欢迎访问 新势力单片机,嵌入式
专业技术论坛: 1. 解码的关键是如何识别"0"和"1",从位的定义我们可以发现"0","1"均以 0.56ms 的低电平开始,不同的是高电平 的宽度不同,"0"为 0.56ms,"1"为 1.68ms,所以必须根据高电平的宽度区别"0"和"1".如果从 0.56ms 低电平过后,开始 延时,0.56ms 以后,若读到的电平为低,说明该位为"0",反之则为"1",为了可靠起见,延时必须比 0.56ms 长些,但又不 能超过 1.12ms,否则如果该位为"0",读到的已是下一位的高电平,因此取(1.12ms+0.56ms)/2=0.84ms 最为可靠,一般取 0. 84ms 左右均可.
2. 根据码的格式,应该等待 9ms 的起始码和 4.5ms 的结果码完成后才能读码.
如果邮购我们开发的 51 单片机试验板和扩展元件的网友, 可以获得如上图所示的红外遥控手柄, 这种遥控器的编码格式符合上 面的描述规律, 而且价格低廉,有 32 个按键, 按键外形比较统一,如果用于批量开发,可以把遥控器上贴膜换成你需要的字符, 这为开发产品提供了便利.
接收器及解码
一体化红外线接收器是一种集红外线接收和放大于一体,不需要任何外接元件,就能完成从红外线接收到输出与 TTL 电 平信号兼容的所有工作,而体积和普通的塑封三极管大小一样,它适合于各种红外线遥控和红外线数据传输.
下面是一个对 51 实验板配套的红外线遥控器的解码程序, 它可以把上图 32 键的红外遥控器每一个按键的键值读出来, 并 且通过实验板上 P1 口的 8 个 LED 显示出来,在解码成功的同时并且能发出"嘀嘀嘀"的提示音.
这是站长最新用单片机 AT89C51 制作的 30 路红外遥控器, 遥控器就是自家的 VCD 遥控器,接收板用了 5 片 CD4069 作为输出 缓冲隔离,当按下遥控器 30 个按键中的一个,接收板对应的一个触点会变成高电平,松开按键,立即恢复成低电平,和 TTL 兼容.
最下面给大家介绍几个下载资料的地方: 51 学习专区: / USB 学习专区: / CAN 学习专区:
个人博客: 电子综合站点:


资料整理自互联网,版权归原作者! 欢迎访问 新势力单片机,嵌入式
专业技术论坛:
AVR 学习专区: / FPGA 学习专区: / STM32 学习专区: / ARM 学习专区: / DSP 学习专区: / PIC 学习专区: / DIY 电子制作专区: / GPS 学习专区: / GUI 学习专区: / EDA 软件学习专区: / 电源学习专区: /
个人博客: 电子综合站点:











相关文档
最新文档