最简单详细的红外解码程序

合集下载

红外遥控解码流程图

红外遥控解码流程图

pic12f1822接收红外信号解码流程图单片机初始化
高电平 1.125 2.25低电平表示还在引导码高电平
高电平表示还在引导码9mS高电平结束,4.5mS低电平
高电平上,
高电平表示信号没来继续等待,高电位是红外接收头的电平
解码的关键是如何识别“0”和“1”,从位的定义我们可以
发现“0”、“1”均以0.56ms的低电平开始,不同的是高电
据高电平的宽度区别“0”和“1”。

如果从0.56ms低电平过
后,开始延时,0.56ms以后,若读到 的电平为低,说明该位为“0”,反之则为“1”,为了可靠起见,延时必须比
0.56ms长些,但又不能超过1.12ms,否则如果该位为“0”,
读到的已 是下一位的高电平,因此取(1.12ms+0.56ms)/2=0.84ms最为可靠,一般取0.88ms左右均可。

头的电平
mS。

(完整word版)红外编码解码程序(word文档良心出品)

(完整word版)红外编码解码程序(word文档良心出品)

红外编码解码程序,我写的是:发送模块通过按键,发送出相应键值的编码,接收模块接收到信号后解码该键值,并点亮相应的状态灯(新手,高手勿喷)//************************* 单片机红外发射******************************* #include<reg52.h> sbit ir=P 1人3;sbit k1= P2A5;sbit k2=P2M;sbit k3=P2A3;sbit k4=P2A2;sbit k5=Pil;unsigned int count, set_count; bit irflag,keyflag; unsigned char irsys[]={0x00,0xff}; unsigned char irdata,ircode;void delay(unsigned int a){unsigned char i;while(--a!=0) for(i=300;i>0;i--);}void keyscan(){/*if(k1==0){delay(10);if(k1==0){keyflag=1;while(!k1);irdata=0x01;}*/ if(k2==0) {delay(10); if(k2==0) {keyflag=1;while(!k2); irdata=0x02;}{delay(10); if(k3==0) {keyflag=1;while(!k3); irdata=0x03;} if(k4==0){delay(10); if(k4==0) {keyflag=1;while(!k4); irdata=0x04;} if(k5==0){delay(10); if(k5==0) {keyflag=1;while(!k5); irdata=0x05;void ir_sendbyte() // 红外发送一个字节数据{ unsigned char i; for(i=0;i<8;i++) //发送8 位数据{set_count=43; //发送编码中的0.56ms 高电平irflag=1;count=0;TR0=1; while(count<set_count);TR0=0;if(ircode&0x01) set_count=130; // 判断红外编码最低位,若为 1 则 1.69ms 的低电平else set_count=43; // 为0 则0.565ms 的低电平irflag=0;count=0;TR0=1; while(count<set_count);TR0=0; ircode=ircode>>1;}}void ir_send(){set_count=346; //发送编码中的引导码(4.5ms高电平+4.5ms低电平)irflag=1;count=0;TR0=1;while(count<set_count);set_cou nt=346; //发送编码中的 4.5ms低电平irflag=0;count=0;TR0=1;while(count<set_count);TR0=0; ircode=irsys[0];ir_sendbyte();ircode=irsys[1];ir_sendbyte();ircode=irdata; //发送8 位数据码ir_sendbyte();ircode=~irdata; // 发送8 位数据反码ir_sendbyte();set_count=43; //发送编码中的0.56ms高电平irflag=1;count=0;TR0=1;while(count<set_count);TR0=0;irflag=0;/*delay(23); //延时23ms (编码中的23ms低电平)set_count=346; //发送编码中的引导码(4.5ms高电平+4.5ms低电平) irflag=1;count=0;TR0=1; while(count<set_count);TR0=0; set_count=346; irflag=0;count=0;TR0=1;while(count<set_count);TR0=0;*/ set_count=43;irflag=1;count=0;TR0=1;while(count<set_count);TR0=0;irflag=0;delay(23);}void timer0_init(){EA=1;TMOD=0x02;//定时0 8 位自动重装模式ET0=1;TH0=0xe6; //定时13us,38K 红外矩形波,晶振24M TL0=0xe6; }void main(){timer0_init();count=0;ir=0;irflag=0;while(1){keyscan(); if(keyflag) {delay(10); ir_send(); delay(500); keyflag=0;delay(100);}}}void timer0() interrupt 1 {count++;if(irflag==1)ir=~ir; // 有发射标志,则发射38khz 的矩形波elseir=0;红外接收**************************** //*************************#include<reg52.h>#define uchar unsigned char #define uint unsigned intsbit led仁P2A1;sbit led2=卩2人2;sbit led3=卩2人3;uchar irtime;uchar startflag;uchar irdata[33];uchar bitnum;uchar irreceok;uchar ircode[4]; uchar irprosok;void display();void timer0init(){TMOD=0x02;TH0=0x00;TL0=0x00;ET0=1;EA=1;TR0=1;void int0init(){IT0=1;EX0=1; EA=1;}}void irpros(){uchar k,i,j;uchar value;k=1;for(j=0;j<4;j++){for(i=0;i<8;i++){ value=value>>1; if(irdata[k]>6){value=value | 0x80;}k++;if(k>33)k=1;}ircode[j]=value;}irprosok=1;}void main(){ timer0init(); int0init(); while(1) { if(irreceok) { irpros(); irreceok=0;} display();}void display()switch(ircode[2]){case 0x05:led1=1; led2=1; led3=1; break;case 0x02:led1=0;led2=1; led3=1; break;case 0x03:led2=0; led1=1; led3=1; break;case 0x04:led3=0;led1=1;led2=1; break;//case 0x01: 备用}void timer0 () interrupt 1 { irtime++;}void int0 () interrupt 0 {if(startflag){if(irtime>32) // 检测引导码{bitnum=0;}irdata[bitnum]=irtime;irtime=0;bitnum++;if(bitnum==33){bitnum=0;irreceok=1;startflag=0;}else{startflag=1; irtime=0;}}。

红外脉冲解码程序

红外脉冲解码程序

单片机红外脉冲解码电路采用共阴极四位数码管;8050开关三极管;STC89C52单片机;12M晶振。

C51程序/*红外脉冲破解程序。

脉冲波长用四位数码管以十六进制显示。

脉冲个数用四位数码管以十进制显示。

*/#include<reg52.h>sbit show=P2^4;sbit back=P2^5;sbitNshow=P2^6;unsignedint box[46];unsigned char code Num[]={0xEB,0x41,0xB3,0xBA,0x78,0xDA,0xDB,0xA8,0xFB,0xFA,0xF9,0x5B,0xC3,0x3B,0xD3,0xD1,0x04}; //数码管1-F 显示的花样程序(根据数码管的接线方法的不同,花样码也会不同)unsigned char Nu[4];unsigned char k=0; //脉冲计数判断unsigned char e=0; //脉冲总数存储unsigned char y=0; //数码管显示第几个脉冲unsignedintA,w;voidshow_led(void);voidwait_short(void);void four_led(unsigned char led) //四个数码管用十六进制显示脉冲长度。

{Nu[1]=box[led]%16;Nu[2]=(box[led]/16)%16;Nu[3]=(box[led]/256)%16;Nu[4]=box[led]/4096;}void main(){P2=0XF0;EA=1;EX0=1;IT0=1;ET0=1;TMOD=0x01;TR0=0;TH0=0;TL0=0;y=0;k=0;e=0;while(1)if(Nshow==0) //检查显示的脉冲数数码管用十进制显示{Nu[1]=y%10;Nu[2]=(y/10)%10;Nu[3]=(y/100)%10;Nu[4]=(y/1000)%10;A=3000;while(A--)show_led();four_led(y);}//================================================================================ if(back==0) //回看脉冲长度{A=10000;while(A--);if(y>=1){y=y-1;four_led(y);}else{y=0 ;four_led(y);}four_led(y); //巩固A=400;while(A--)show_led();four_led(y);}//========================================================================== if(show==0) //下一个脉冲长度{P2=0XF0;P1=0X00;A=10000;while(A--);if(y<e){y=y+1;four_led(y);}else{Nu[1]=16;Nu[2]=16;Nu[4]=16;A=400;while(A--)show_led();y=0;four_led(y);}four_led(y); //巩固A=400;while(A--)show_led();four_led(y);}//=============================================================================== show_led();}while(1);}void Int0_Routine() interrupt 0 using 0 //下降沿中断{TR0=0;box[k]=TH0*256+TL0;TH0=0;TL0=0;TR0=1;if(k==0)e=0;e=e+1;k=k+1;}void time_int() interrupt 1 using 0 //计数器中断{TR0=0;box[k]=TH0*256+TL0;TH0=0;TL0=0;k=0; //计数器溢出K归零准备下一个脉冲信号的接受y=0; // 计数器溢出脉冲结束数码管开始显示第0个脉冲four_led(y);}void show_led(void) //数码管显示数值{if(Nu[4]!=0){P1=Num[Nu[1]];wait_short();P2=0xF2;P1=Num[Nu[2]];wait_short();P2=0xF4;P1=Num[Nu[3]];wait_short();P2=0xF8;P1=Num[Nu[4]];wait_short();}else{if(Nu[3]!=0){P2=0xF1;P1=Num[Nu[1]];wait_short();P2=0xF2;P1=Num[Nu[2]];wait_short();P2=0xF4;P1=Num[Nu[3]];wait_short();}else{if(Nu[2]!=0){P2=0xF1;P1=Num[Nu[1]];wait_short();P2=0xF2;P1=Num[Nu[2]];wait_short();}else{P2=0xF1;P1=Num[Nu[1]];wait_short();}}}void wait_short(void) //消岐延时{w=40;while(w--);}解码结果。

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

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

一文教会你红外线遥控器软件解码程序
红外线一开始发送一段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;//接受数据缓冲。

红外解码程序详解

红外解码程序详解

红外遥控解码程序设计——————基于uPD6121红外编码制式红外传感系统是目前应用最为广泛的遥控系统,一个红外遥控系统可分为发射和接收两部分组成,发射端称之为红外遥控器,一般由矩阵键盘,红外编码调制芯片和红外发射管组成;接收端用一体化红外接收头即可,这个东东内置光电放大器和解调部分,信号接收之后一般很微弱须放大后才可解码,为有效发射出去得先托付在载波上所以需经历调制、解调的过程,其实对于发射部分主要工作在于编码,而对于编码方式只有几种主流方式,而目前国内大部分均为uPD6121编码方式(日本NEC公司搞出来的。

),所以我们只须弄清楚这种编码的时序,即可写出万能的红外解码程序,只要是基于这种编码方式的遥控器(家里的电视、空调、电扇遥控器)都可以用该程序来解码(这点也充分证明了C语言的高移植性啊。

)这种编码的格式其实很简单,开头是一个引导码,人家芯片在编码时将其设计成9ms的高电平和4.5ms的低电平,也就是说你必须跳过这段引导码之后才会接收到数据,第一个问题来了:为什么要加这段引导码?因为红外传感是非常容易受到干扰的,如果直接传送数据很可能并非发送端的信号,很可能来自其他辐射,后面设计程序时会遇到这个问题。

所以我们在写程序时在引导码时可以加入检测代码,如果是引导码则继续接收,否则跳出。

第二个问题就是:接收数据时我们用外部中断接收,这是考虑到CPU 的执行效率,如果你在主函数里接收数据,就好比CPU一直在问:你接收到数据没?你接收到没?..很明显不靠谱,和串口通信一样,接收数据用中断这是经验,有利于单片机的执行效率。

第三个要注意的就是红外接收端和编码发送的数据是反向的!这点很重要,我看很多资料没有写明这点,让很多童鞋疑惑不解,也就是说引导码编码时确实是9ms高电平和4.5ms 的低电平,但是到了接收端是9ms的低电平和4.5ms的高电平,所以我们在解码时就得注意引导码高电平出现的顺序。

对于编码格式,引导码后接了4个字节的数据,前两个字节为用户码和用户反码,简单点说就是器件地址;后两字节为操作码和操作反码,就是我们真正需要的数据。

万能遥控器红外解码C程序

万能遥控器红外解码C程序

for(i=2;i>0;i--)
for(j=230;j>0;j--) ;
}
/***************************延时4.5ms子程序**********************/
void Delay4_5ms(void)
{uchar i,j;
for(i=10;i>0;i--)
for(j=225;j>0;j--) ;
if(IRsignal==1) //如果IRsignal是"1",则向右移入一位"1"
{Delay1ms();
CodeTemp=CodeTemp|0x80;
if(j<8) CodeTemp=CodeTemp>>1;
}
else
if(j<8)CodeTemp=CodeTemp>>1;//如果IRsignal是"0",则向右移一位,自动补"0"
{while(IRsignal==0);
Delay4_5ms();
//跳过持续4.5ms的高电平
for(i=0;i<4;i++)
//分别读取4个字节
{for(j=1;j<=8;j++)
//每个字节8个bit的判断
{ while(IRsignal==0);
//等待上升沿
Delay0_9ms();
//从上升沿那一时刻开始延时0.9ms,再判断IRsignal
/* 前16位为8位用户码及其反码,后16位为8位的操作码及其反码
*/
/* 以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示"0"; */

红外解码方案

红外解码方案

红外解码方案1. 红外发射的原理遥控器部分的工作原理较为简单,主要就是编码IC 通过三极管进行放大调变,然后将此电信号(脉冲波)经有红外发射管(940nm 波长)转变为光信号发射出去。

现在国产遥控器的电路主要有:455kHz 晶振,编码IC ,放大三极管,发射管等主要几个电子原件组成;通常使用38kHz 载波,这样可以提高红外线的抗干扰能力,避免大气中的红外线干扰。

调制载波频率一般在30kHz 到60kHz 之间,大多数使用的是38kHz ,占空比1/3的方波,这是由发射端所使用的455kHz 晶振所决定的。

在发射端要对晶振进行整数分频,分频系数一般取12,所以455kH z÷12≈37.9kH z≈38kHz 。

2.红外接收的原理红外接收头内部结构主要由光电二极管+红外接收IC 组成,工作原理为:光电二极管(俗称接收管)其接收到红外发射管发射出的光信号后转换为电信号(为微安级的电流),此电信号输入到接收IC 内部经过放大--增益--滤波--解调变--整形还原,还原遥控器给出的原始编码,通过接收头信号输出脚输入到后面的代码3. 几种编码格式3.1 NEC 制NEC 制的数据格式分为引导码、16位用户码(地址码)、8位数据码、8位数据反码构成。

用户码或数据码中的每一个位可以是位‘1’,也可以是位‘0’。

区分‘0’和‘1’是利用脉冲的时间间隔来区分,这种编码方式称为脉冲位置调制方式(PPM)(注意NEC每一位的长度不一样,1.125ms或者2.25ms)。

按键保持按下状态时每发送完整的一帧数据后,再发送重复码,再到按键被松开。

此芯片用两种不同的重复码,当用户码的C0位为1时用一种,C0位为0时使用另一种。

3.2RC5制RC5编码相对NEC编码简单一些。

RC5编码有2位起始位(为‘1’)、1位控制、5位系统码(地址码)、6位指令码,一共14位数据。

在这个协议里所有位是平等的长度都等于1.778ms,位时间的一半填满脉冲是36KHz的载波,另外一半被闲置。

红外遥控解码程序

红外遥控解码程序

红外遥控解码程序红外接收头的型号有很多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”表⽰。

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

#include<reg52.h> //包含头文件名
sbit IRIN=P3^2; //定义红外接收头的外部接口,即外部中断0
sbit BEEP=P1^5; //定义蜂鸣器接口,我的在P1^5
unsigned char IRCOM[7]; //定义数组,用来存储红外接收到的数据
void delay(unsigned char x)
{ //延时子程序unsigned char i; //延时约x*0.14ms
while(x--) //不同遥控器应设置不同的参数
{for(i=0;i<13;i++){}} //参数的选择咱们先不管,先看这个
}
void beep()
{
unsigned char i; //蜂鸣器发声子程序
for(i=0;i<100;i++)
{
delay(4); //这个得看你的蜂鸣器内部是否有振荡源
BEEP=~BEEP;
} //如果没有振荡源就应该输入脉冲信号
BEEP=1;
}
void IR_IN() interrupt 0 using 0 //外部中断0程序
{
unsigned char j,k,n=0; //先定义变量,记住n=0
EX0=0; //禁止中断,以免再次进入中断
delay(15); //延时0.14ms*15=2.1ms
if(IRIN==1) //如果在这期间有高电平说明
{ //信号不是来自遥控的,返回主程序
EX0=1;
return;
}
while(!IRIN){delay(1);} //死循环,等待9ms前导低电平信号的结束for(j=0;j<4;j++) //一共有4组数据
{
for(k=0;k<8;k++) //每组数据有8位
{
while(IRIN){delay(1);} //死循环,等待4.5ms前导高电平的结束
while(!IRIN){delay(1);} //等待0.56ms低电平的结束,准备采集数据,
while(IRIN) //开始采集数据
{
delay(1); //延时0.14ms,每过0.14ms时n就加1
n++; //用n记录一共有多少个0.14ms
if(n>=30) //如果超过0.14ms*30=4.2ms
{ //说明是乱码,放弃不要
EX0=1;
return;}
}
IRCOM[j]=IRCOM[j]>>1; //右移1位,xxxx xxxx变成0xxx xxx
//我们先认为这一位数据是0,现在已经送入一位数据了
/*你肯定知道_cror_(x,1)和x>>1的区别吧*/
if(n>=8){IRCOM[j]=IRCOM[j]|0x80;}//但是如果不是0呢,
//0xxx xxxx和0x80相或后变成了1xxx xxxx
//这样这一们数据就被记录为1了
/*想一下这里为什么是8呢,0.14ms*8=1.12ms,知道了吧*/
/*这样反复执行8次,8位数据就存在IRCOM[j]中了*/
/*外层再循环4次,4*8=32位数据码全都在IRCOM[0],IRCOM[1],IRCOM[2],IRCO M[3]中了*/
n=0; //n计数后一定要记得清0,否则下一次就不能准确计数了
}
}
if(IRCOM[2]!=~IRCOM[3]) //这里我们判断数据码和数据反码是不是相反{ //因为相反才是正确的,否则就放弃
EX0=1;
return;}
beep();
EX0=1; //记得开中断,你可以去掉这句话试一试
}
void main()
{
IE=0x81;
TCON=0X01;
BEEP=1;
IRIN=1;
while(1);
}
怎么样,你看懂了吗?
作者:任杰。

相关文档
最新文档