打印
[MCU]

基于MSP430F149的红外解码

[复制链接]
546|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
两只袜子|  楼主 | 2020-12-3 09:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人最近在用MSP430F149调试红外遥控,型号是SM0038吧.
之前就试过几种方法,但是就是没办法解码.今天的这个也是,
所以在这里希望各位不管是路过的还是走过的,希望能指教一下这个程序的问题,谢谢.

这个程序采用上升沿和下降沿都捕获,P1_2口输入.之后用P5口输出在流水灯中显示.(SCLK = MCLK = 1M)

#include

void int_clk();//系统时钟初始化
void int_cap();//捕获设置
void capturedata();//捕获红外数据
int setdata();//捕获数据处理(有返回值)
unsigned char a[4],haha,flag;
unsigned char h_time[32],l_time[32],Lead_h_time,Lead_l_time;
/*------------------------------------------------------------------------------
函数功能:设置MCLK=SCLK=1M
入口参数:无
返回值:无
------------------------------------------------------------------------------*/
void int_clk()
{
  unsigned char i ;
  BCSCTL1 &= ~XT2OFF ;
  BCSCTL2 |= SELM1 + SELS + DIVM_3 + DIVS_3 ;
  do
  {
    IFG1 &= ~ OFIFG ;
    for(i=0;i<100;i++)
      _NOP();
  }
  while((IFG1&OFIFG)!=0);
    IFG1 &= ~ OFIFG ;
}
/*------------------------------------------------------------------------------
函数功能:捕获初始化
入口参数:无
返回值:无
------------------------------------------------------------------------------*/
void int_cap()
{
   
   P1SEL |= BIT2 ;//输入口为P1_2
   TACCTL1 |= CM_3 + SCS +  CAP + CCIE + CCIS_0 ;//上下降沿都捕获模式
   TACTL |= TASSEL_2 + MC_1 ;//时钟选择SCLK8M 每个时钟周期为1/1000000 增计数模式
}
/*------------------------------------------------------------------------------
函数功能:主函数
入口参数:无
返回值:无
------------------------------------------------------------------------------*/
void main()
{
    WDTCTL = WDTPW + WDTHOLD;// Stop watchdog timer to prevent time out reset
    int_clk();  
    int_cap();
    _EINT();//开全局中断
    while(1)
    {
      capturedata();
      while(haha==1)
      {
        while(setdata())
        {
          P5DIR = 0xff ;
          P5OUT = a[2];
        }
      }
    }
}
/*------------------------------------------------------------------------------
函数功能:捕获中断
入口参数:无
返回值:无
------------------------------------------------------------------------------*/
#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A()
{
  switch(TAIV)
  {
    case 2 : {flag++;}//捕获中断次数
    case 4 :break;
    case 10:break;
  }
}
/*------------------------------------------------------------------------------
函数功能:捕获数据
入口参数:无
返回值:无
------------------------------------------------------------------------------*/
void capturedata()
{
  //初始化红外编码数据
  if(flag==2)
  {
    Lead_l_time = CCR1 ;//引导码低电平时间
    TAR = 0 ;//计数器清零
  }
  if(flag==3)
  {
    Lead_h_time = CCR1 ;//引导码高电平时间
    TAR = 0 ;//计数器清零  
  }
restart:  
  while((flag>3)&&(flag%2==0))//当flag==4,6,.....66
  {
    l_time[flag] = CCR1 ;
    TAR = 0 ;//计数器清零  
      if(flag==66){break;}//退出循环
      goto restart ;
  }
  while((flag>3)&&(flag%2!=0))//当flag==5,7,.....67
  {
    h_time[flag] = CCR1 ;
    TAR = 0 ; //计数器清零  
      if(flag==67){haha=1;break;}//如果是第67次中断,则退出,此时数据已经捕获完毕
      goto restart ;  
  }
}
/*------------------------------------------------------------------------------
函数功能:对捕获到得数据进行处理
入口参数:无
返回值:1或者0
------------------------------------------------------------------------------*/
int setdata()
{
  unsigned char temp ,i,j;
  if((Lead_l_time>9500)||(Lead_l_time<8500)||(Lead_h_time>4200)||(Lead_h_time<4800))  //如果不是引导码 返回0
  {return 0 ;}
  for(i=0;i<4;i++)
  {
    switch(i)
    {
      case 0 : flag = 4;j=18; break;
      case 1 : flag = 20;j=34; break;
      case 2 : flag = 36;j=50; break;
      case 3 : flag = 52;j=66; break;
      default:break;
    }
    for(;flag<=j;flag+=2)
    {
      temp=temp>>1;//右移到最高位
      if((l_time[flag]<520)||(Lead_l_time)>620){return 0 ;}//键码的低电平时间不在560范围内,返回0
        if((h_time[flag+1]>520)&&(h_time[flag+1]<620)){temp&=0x7f;}//如果高电平时间大概为560 则为0
          if((h_time[flag+1]>1500)&&(h_time[flag+1]>1900)){temp|=0x80;}//如果高电平时间大概为1680 则为1
    }   
    a=temp;
  }
            if(a[2]==~a[3])return 1;
}

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2055

主题

7455

帖子

10

粉丝