This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

msp430g2553红外遥控解码

Other Parts Discussed in Thread: MSP430G2452

红外通信的主要注意几个方面: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_cap<old_cap)//计数重新开始

         diff_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.