您的位置 首页 编程

PIC单片机的红外遥控与解码

今天玩红外遥控的解码!先了解红外接收的原理:遥控器使用方便,功能多.目前已广泛应用在电视机、VCD、DVD、空调等各种家用电器中,且价格…

今日玩红外遥控解码

先了解红外接纳的原理:

遥控器运用方便,功用多.现在已广泛应用在电视机、VCD、DVD、空调等各种家用电器中,且价格便宜,市场上十分简单买到。假如能将遥控器上许多的按键解码出来.用作单片机体系的输入.则处理了惯例矩阵键盘线路板过大、布线杂乱、占用I/O口过多的弊端。并且经过运用遥控器,操作时可完成人与设备的别离,然后愈加方便运用。

一、编码格局
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、按键的编码

当一个键按下超越36ms,振动器使芯片激活,将发射一组108ms的编码脉冲,这108ms发射代码由一个开端码(9ms),一个成果码(4.5ms),低8位地址码(9ms~18ms),高8位地址码(9ms~18ms),8位数据码(9ms~18ms)和这8位数据的反码(9ms~18ms)组成。假如键按下超越108ms仍未松开,接下来发射的代码(连发代码)将仅由开端码(9ms)和完毕码(2.5ms)组成。

当咱们按下遥控器的按键时,遥控器将宣布如图2的一串二进制代码,咱们称它为一帧数据。依据各部分的功用。可将它们分为5部分,分别为引导码、地址码、地址码、数据码、数据反码。遥控器发射代码时.均是低位在前。高位在后。由图2剖析能够得到.引导码高电平为4.5ms,低电平为4.5ms。当
接纳到此码时.表明一帧数据的开端。单片机能够预备接纳下面的数据。地址码由8位二进制组成,共256种.图中地址码重发了一次。主要是加强遥控器的可靠性.假如两次地址码不相同.则阐明本帧数据有错.应丢掉。不同的设备能够具有不同的地址码.因而。同种编码的遥控器只需设置地址码不同,也不会彼此搅扰。图中的地址码为十六进制的0EH(留意低位在前)。在同一个遥控器中.一切按键宣布的地址码都是相同的。数据码为8位,可编码256种状况,代表实践所按下的键。数据反码是数据码的各位求反,经过比较数据码与数据反码.可判别接纳到的数据是否正确。假如数据码与数据反码之间的联系不满足相反的联系.则本次遥控接纳有误.数据应丢掉。在同一个遥控器上.一切按键的数据码均不相同。在图2中,数据码为十六进制的0CH,数据反码为十六进制的0F3H(留意低位在前).两者之和应为0FFH。

接连码


二、单片机遥控接纳电路
红外遥控接纳可选用较早的红外接纳二极管加专用的红外处理电路的办法。如CXA20106,此种办法电路杂乱,现在一般不选用。较好的接纳办法是用一体化红外接纳头,它将红外接纳二极管、扩大、解调、整形等电路做在一同,只要三个引脚.分别是+5V电源、地、信号输出。常用的一体化接纳头的外形及引脚见图3和图4。红外接纳头的信号输
出接单片机的INTO或INTl脚.典型电路如图5所示.图中增加了一只PNP型三极管对输出信号进行扩大。

针对遥控器端(解码端,接纳端对对此取反即可)
引导码:9ms高+4.5ms低
体系码:体系码1+体系码2(由界说凹凸电平的”0″和”1″组成)
数据码:数据码1+数据反码(由界说凹凸电平的”0″和”1″组成)
剩下码:108ms-引导码占用时刻-体系码占用时刻-数据码占用时刻.
假如按”键”的时刻超越108ms,遥控器还会发射重发码:
重发码(108ms)的格局如下:
9ms高+2.25ms低+0.56ms高+96.19ms低

衔接电路图:

下面开端写程序:

#ifndef MAIN_H
#define MAIN_H
#include

#define bitset(var,bitno)(var |=1<#define bitclr(var,bitno)(var &=~(1<

#define uint unsigned int
#define uchar unsigned char

//界说承受帧状况
#define IR_IDLE 0x01
#define IR_START 0x02
#define IR_ADD 0x03
#define IR_ADDINV 0x04
#define IR_DATA 0x05
#define IR_DATAINV 0x06

#define ms_168 0x0600
#define ms_th 0x08CA
#define ms_9 0x0800
#define ms_306 0x0B00
#define ms_125 0x1300
#define ms_15 0x15F9
//void DelayMS(uint ms);//毫秒级延时函数
//void Delay10US(uint us);//10微秒级延时函数
void init_all() ;

#endif

#include “main.h”
#include “t232.h”

typedef struct frame1
{
uint add ;
uint addinv ;
uchar data ;
uchar datainv ;
uchar ir_state ;
uint count ;
uint temp ;
uchar ready ;
} ir_frame ;

void int_delay(uint count)
{
while(count–) ;
}
//define global variable
ir_frame frame ;

void interrupt main_int()
{

if(INTF&INTEDG)
{
GIE=0 ;
INTF=0 ;
TMR1ON=0;
frame.count=TMR1H*256+TMR1L;
TMR1H=0;
TMR1L=0;
TMR1ON=1;

switch(frame.ir_state)
{
case IR_IDLE :
if(frame.count>0x2000)//避免搅扰
frame.ir_state=IR_START ;
break ;
case IR_START :
if(frame.ready==1)//没有处理,等候
{
frame.ir_state=IR_IDLE ;
return ;
}
if((frame.count>ms_125)&&(frame.count{
frame.add=0 ;
frame.addinv=0 ;
frame.data=0 ;
frame.datainv=0 ;
frame.ir_state=IR_ADD ;
frame.temp=1 ;
frame.ready=0 ;

}
else if((frame.count>ms_9)&&(frame.count{
frame.ready=1 ;
frame.ir_state = IR_IDLE ;

}
else//噪声?
{
frame.ir_state = IR_IDLE ;
}
break ;
case IR_ADD :
if(frame.count<0x280)//噪声?
return ;
if((frame.count>ms_168))//高电平?
frame.add|=frame.temp ;

frame.temp=frame.temp<<1 ;
if(frame.temp==0x2000)//13位OK?
{
frame.ir_state=IR_ADDINV ;
frame.temp=1 ;
}
break ;
case IR_ADDINV :
//int_delay(75) ;
//if(RB0)
if(frame.count<0x280)
return ;
if((frame.count>ms_168))
frame.addinv|=frame.temp ;

frame.temp=frame.temp<<1 ;
if(frame.temp==0x2000)//13位OK?
{
frame.ir_state=IR_DATA ;
frame.temp=1 ;
}
break ;
case IR_DATA :
if(frame.count<0x280)//噪声
return ;
if((frame.count>ms_168))//高电平
frame.data|=frame.temp ;

frame.temp=frame.temp<<1 ;
if(frame.temp==0x0100)//8位 finished ?
{
frame.ir_state=IR_DATAINV ;
frame.temp=1 ;
}
break ;
case IR_DATAINV :
if(frame.count<0x280)
return ;
if((frame.count>ms_168))
frame.datainv|=frame.temp ;

frame.temp=frame.temp<<1 ;
if(frame.temp==0x0080)//7 位 finished?
{
frame.temp=frame.temp<<1 ;
int_delay(75) ;//延时等候最终一位的电平
if(RB0)
frame.datainv|=frame.temp ;
if((frame.data|frame.datainv==0xff)&&(frame.add==0x011F))
{
frame.ready=1 ;
}
frame.ir_state=IR_IDLE ;
}
break ;
default :
break ;
}
GIE=1 ;
}
}

void init_all()
{
init_232() ;
//init_hongwai() ;
INTCON=0 ;
INTE=1;//开RB电平中止
PEIE=1;
INTEDG=1 ;
TRISB0=1;//RB4为输入
T1CON=0 ;
TMR1H=0xAA ;
TMR1L=0xBB ;
frame.ir_state=IR_IDLE ;
GIE=1 ;
ADCON0=0x06 ;
TRISA0=0 ;
}
void main()
{
const char str[]= “hello world !” ;

init_all() ;
send_str(str) ;//测验串口
while(1)
{

if(frame.ready==1)
{
put_char(frame.data) ;
frame.ready=0 ;
}

}
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/biancheng/276649.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部