您的当前位置:首页正文

msp430g2553红外遥控解码

2020-03-11 来源:榕意旅游网
忙了一天多的MSP430单片机的红外通信终于测试成功了!!这也把我自己的USB音乐遥控器改为用红外通信来,因为我手头上刚好有个car MP3的遥控器。当然这其中也出现一些问题以及解决问题的思路,我认为红外通信的主要注意几个方面:430单片机的时钟配置(我选择内部DCO,为了准确的定时器捕获脉冲)、红外通信协议的数据格式(用户数据是从高到低还是从低到高?)、430单片机的一些寄存器配置。

程序如下:

#include \"msp430g2452.h\"

typedef unsigned int uint;

typedef unsigned char uchar;

uint ir_data[33];//存放解码数据(16位用户码+8位数据码+8位数据反码)

uchar ir_code[4];//存放解码数据

uchar irok=0;//数据接收标志位

uint new_cap=0;

uint old_cap=0;

uint diff_cap=0;

uchar data_sign=0;

void clk_init(void);//时钟初始化

void timera_init (void);

void IR_data_pros (void);

void main( void )

{

uint i;

// Stop watchdog timer to prevent time out reset

WDTCTL = WDTPW + WDTHOLD;

for(i = 0; i < 0xFFFF; i++){};

_BIS_SR(OSCOFF);

if(CALBC1_1MHZ==0xff||CALDCO_1MHZ==0xff)

{

while(1);

}

clk_init();

timera_init(); //定时器初始化

_EINT(); //开总中断开关

while(1)

{

if(irok) //数据接收是否完毕?

{

irok=0; //是、清标志位

IR_data_pros(); //红外数据处理函

//if(ir_code[2]==(~(ir_code[3])))

// P1OUT ^=BIT6;//绿灯

//else P1OUT ^=BIT0;//红灯

P2OUT=ir_code[2]>>4;

}

}

}

/*************************************************************/

void clk_init(void)

{

DCOCTL=CALDCO_8MHZ; /* DCOCTL Calibration Data for 8MHz */

BCSCTL1=CALBC1_8MHZ;//使MCLK=DCOCTL=8MHz

BCSCTL2 |=SELM_0+DIVS_0+DIVM_0; //使MCLK=SMCLK=DCO=8M

}

/*************************************************************/

void timera_init (void)

{

P2DIR=0xff;

P2OUT=0x00;

P1DIR &=~BIT1; //设置P1.1为输入

//P1DIR |=BIT6+BIT0;

//P1OUT &=~BIT6;

//P1OUT &=~BIT0;

P1SEL |= BIT1; //设置P1.1为CCI0A输入

TACTL=TASSEL_2+MC_2+TACLR+ID_3; //timera_clk=SMclk=1MHz、连续计数模式、1分频

CCTL0=CM_2+SCS+CCIS_0+CAP+CCIE;

//下降沿捕获、同步捕获、选择输入为CCI0A、捕获模式、开捕获中断

}

/*********************红外数据处理函数**************************/

void IR_data_pros (void)

{

uchar i,j,count=1,value=0; // count=1 、作用是清除引导码

for(i=0;i<4;i++)

{

value=0;

for(j=0;j<8;j++)

{

value>>=1; //用户码和数据码均是低位在前,高位在后

if(ir_data[count]>1700) //判断捕获时间是否大于1.7MS

value|=0x80; //若 >1.7MS,则为1、若 <1.7MS,则为0

count++;

}

ir_code[i]=value; //存放用户码和数据码

}

}

/********************Timer_A中断服务程序*************************/

#pragma vector=TIMER0_A0_VECTOR

__interrupt void timera (void)

{

static uchar index=0;

new_cap=TACCR0;

if(data_sign==0)

{

data_sign=1;

old_cap=new_cap;

return ;

}

if(new_capdiff_cap=65536-old_cap+new_cap;

else diff_cap=new_cap - old_cap;

if(diff_cap>7000) {index=0; } //检测引导码

ir_data[index++]=diff_cap; //存捕获的差异值,既是数据

if(index==33) //数据接收完毕

{

index=0;

data_sign=0;

irok=1; //数据接收标志置位

}

old_cap=new_cap;

}

使用定时器A的捕获模式来计算脉冲宽度,来区分1或者0.

因篇幅问题不能全部显示,请点此查看更多更全内容