微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 基于MSP430的红外遥控器解码

基于MSP430的红外遥控器解码

时间:11-28 来源:互联网 点击:
遥控发射器专用芯片很多,根据编码格式可以分成两大类,这里我们以运用比较广泛,解码比较容易的一类来加以说明,现以日本NEC的uPD6121G组成发射电路为例说明编码原理(一般家庭用的DVD、VCD、音响都使用这种编码方式)。当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码也不同。这种遥控码具有以下特征:

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



当一个键按下超过36ms,振荡器使芯片激活,将发射一组108ms的编码脉冲,这108ms发射代码由一个引导码(9ms),一个结果码(4.5ms),低8位地址码(9ms~18ms),高8位地址码(9ms~18ms),8位数据码(9ms~18ms)和这8位数据的反码(9ms~18ms)组成。如果键按下超过108ms仍未松开,接下来发射的代码(连发码)将仅由起始码(9ms)和结束码(2.25ms)组成。



接收电路可以使用一种集红外线接收和放大于一体的一体化红外线接收器,不需要任何外接元件,就能完成从红外线接收到输出与TTL电平信号兼容的所有工作,而体积和普通的塑封三极管大小一样,它适合于各种红外线遥控和红外线数据传输。
接收器对外只有3个引脚:Out、GND、Vcc与单片机接口非常方便



① 脉冲信号输出接,直接接单片机的IO 口。
② GND接系统的地线(0V);
③ Vcc接系统的电源正极(3~5V);


以上信息来自搜集的资料和自己的整理(方便大家学习)


以下是我的解码程序(参考C51的程序的成功移植)


注意:红外解码对时间延时的精度要求比较高,很难一次成功,需要耐心调试,修改着色部分的数字大小.


//利用两位数码管显示遥控器的编码值


//如遥控器上的0~9对应在数码管上显示00~09


#include


#define wei1_1 P1DIR|=BIT7;P1OUT|=BIT7//数码管低位置高
#define wei1_0 P1DIR|=BIT7;P1OUT&=~BIT7//数码管低位置低
#define wei2_1 P1DIR|=BIT6;P1OUT|=BIT6//数码管高位置高
#define wei2_0 P1DIR|=BIT6;P1OUT&=~BIT6//数码管高位置低
#define duan_out P2DIR=0xff//数码管段选P2口设为输出
#define IR_DIR_IN P1DIR&=~BIT0//红外接收头P1.0设置为输入,


#define IRIN (P1IN&BIT0)//红外接收头输入值
#define duan P2OUT//数码管段选为P2口
char dat[8];
char seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xC6,0xa1,0x86,0x8e};


//函数声明
void InitSys();
void display();


void delay(unsigned char x) //延时子程序(x*0.14MS)
{
unsigned char i,j;
while(x--)
{
for (i = 20; i>0; i--)
for(j=5;j>0;j--);
}
}


void delay_1ms(unsigned int nValue)//delay 1ms at 8M
{
unsigned int nCount;
unsigned int ii;
unsigned int jj;
nCount = 1592;
for(ii = nValue;ii > 0;ii--)
{
for(jj = nCount;jj > 0;jj--)
_NOP();
}
}


void delay_5us(unsigned int nValue)//delay 5us at 8M
{
unsigned int ii;
for(ii = nValue;ii > 0;ii--)
{
_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();
}
}


int main( void )
{


WDTCTL = WDTPW + WDTHOLD; //关闭看门狗


InitSys(); //初始化
delay_1ms(1);
for(;;)
display();


}


/*****************************************************************************
系统初始化
******************************************************************************/
void InitSys()
{
unsigned int i;


BCSCTL1 &= ~XT2OFF;

do
{
IFG1 &= ~ OFIFG ;
for ( i = 0 ; i < 100 ; i ++ )
_NOP();
}


while ( IFG1&OFIFG != 0 );
BCSCTL2 |= SELM_2 + SELS ;


P1IE=BIT0; //P1.0中断功能打开
P1IES|=BIT0; //P1.0下降沿触发中断
IR_DIR_IN; //PI.0设置为输入

duan_out; //P2设置为输出

_EINT(); //打开全局中断控制
}
/*****************************************************************************
端口1中断函数
******************************************************************************/
#pragma vector="PORT1"_VECTOR
__interrupt void Port1()
{
char i,j,k,n=0;
if((P1IFG&BIT0) == BIT0)
{
P1IFG &= ~BIT0; //清除P1.0中断标志
P1IE &=~BIT0; //关闭P1.0中断功能
I1:
for (i=0;i<4;i++)
{
if (IRIN==0) break;
if (i==3) {P1IE|=BIT0;return;}
}
delay(20);
if (IRIN==1) goto I1; //确认IR信号出现
while(!IRIN); //等待IR变为高电平

for (j=0;j<4;j++)
{
for (k=0;k<8;k++)
{
while (IRIN) //等 IR 变为低电平
{delay_5us(28);}
while (!IRIN) //等 IR 变为高电平
{delay_5us(28);}
while (IRIN) //计算IR高电平时长
{
delay_5us(28);
n++;
if (n>=30){P1IE|=BIT0;return;}
}
dat[j]=dat[j] >> 1;
if (n>=11) {dat[j] = dat[j]|0x80;}
n="0";
}
}
if (dat[2]!=~dat[3]) {P1IE|=BIT0;return;}//此句刚开始可以屏蔽,见到效果后再尝试打开校验
dat[5]=dat[2] & 0x0F;
dat[6]=dat[2] & 0xF0;
dat[6]=dat[6] >> 4;
//beep();
P1IE|=BIT0;
}
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top