adszmc 发表于 2011-8-4 10:49:01

无线收码程序,求解~~

最近一个小项目需要做滚动码遥控器,接收部分是电池供电的产品,外围预留接口给接收模块,这就要求滚动码接受解码部分需要低功耗要求。

载波使用315M频段的模块,已近找到了一个300UA静态电流的模块,接受部分主要功耗问题解决

解码ICmsp430G2553   价格在MSP430里面还是可以的,接受无线数据采用捕获功能,定时器时钟采用ACLK,在休眠模式3模式下,基本无需功耗。而单片机收码能时时接收,单片机休眠模式下ACLK还是能工作,这是430的强大之处。接受到正确的帧头和位码以后唤醒单片机进行解码。

帧格式(hsc300)
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_664062YIIIOI.jpg
(原文件名:1.jpg)

码的冗余度:
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_664063UXNGEU.jpg
(原文件名:2.jpg)

http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_664064FJRZXV.jpg
(原文件名:3.jpg)

http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_664065G85ZUG.jpg
(原文件名:4.jpg)


捕获模块采用ACLK为时钟,时钟为32.768khz一个步长为30.5US

现在碰到一个问题, 遥控器按键按下,收到码时有时无,无规律的,有时候一按就收到,有时候连续或是长按都收不到。示波器看收到的波行很好,基本排除是收码这个原因。调试时候。发现是没有很好的搜到同步码造成的, 在没有到遥控器时候,周围存在无线电波想干扰,接受模块会收到很多的杂波,因为采用捕获功能,捕获中断时时中断。

硬件很简单315m模块DATa脚直接接 MCU的PCA脚。

下面是程序。调试时候   很乱!


PCA捕获程序
主程序很简单,就一个初始化。


// Timer_A3 Interrupt Vector (TA0IV) handler
#pragma vector=TIMER1_A1_VECTOR
__interrupt void Timer_A(void)
{
switch( TA1IV )
{
    case2:                                  // CCR1
   {
      // P2OUT ^= BIT5;
       if(time_over==1) //接受66bit超时复位
       {
            
         TA1CCTL0|=CM0; // 1
         TA1CCTL0&=~CM1;// 0上升沿
         receive_sign=0;
         receive_end_h=0;
         receive_end_l=0;
         BitCount = 0;
         Bptr=0;
       }
       TA1CCR1 += 2000;                        // Add Offset to CCR1
       time_over=1;
      
   }
   break;
    case4: break;                           // CCR2 not used
    case 10: break;                           // overflow not used

    default:
       break;

}
}



#pragma vector=TIMER1_A0_VECTOR
__interrupt void timea0 (void)
{
   
      
      switch(receive_sign)
      {
            
         
            case 0:         //捕获到同步位高电平起始,准备捕获同步位高电平结束 +----
                                                      //                     |                              
               receive_start_h=TA1CCR0;
               
               TA1CCTL0&=~CM0;//0
               TA1CCTL0|=CM1; //1   下降沿
               
               receive_sign=1;
               
               break;
            
               
            
          case 1:          //捕获到同步位高电平结束,准备捕获同步位低电平结束
               receive_end_h   = TA1CCR0;
               receive_start_l = TA1CCR0;
               
               if(receive_end_h >= receive_start_h)
                   {
                     receive_end_h -= receive_start_h;
                   }
               else
                   {
                     receive_end_h+=(65535-receive_start_h);
                   }
               
               TA1CCTL0|=CM0; // 1
               TA1CCTL0&=~CM1;// 0上升沿
               receive_sign=2;
            
               break;
                               
                               
            case 2:         //捕获到同步位低电平结束
               receive_end_l=TA1CCR0;
               if(receive_end_l>=receive_start_l)
                   {
                     receive_end_l-=receive_start_l;
                   }
               else
                   {
                     receive_end_l+=(65535-receive_start_l);
                   }
                           
               if((receive_end_l>80) &&(receive_end_l<210)&&(receive_end_h>8)&& (receive_end_h<21) )//判断是否是同步位
                  
                   {   //是同步位准备接收数据位高电平结束
                     receive_start_h=TA1CCR0;
                     TA1CCTL0&=~CM0;// 0
                     TA1CCTL0|=CM1; // 1 下降沿
                     receive_sign=3;
                   }
               
               else
                   {//不是同步位
                     //TA1CCTL0=CM0+SCS+CAP+OUTMOD0+CCIE;//
                     TA1CCTL0|=CM0; // 1
                     TA1CCTL0&=~CM1;// 0上升沿
                     receive_sign=0;
                     receive_end_h=0;
                     receive_end_l=0;
                     BitCount=0;
                     Bptr=0;
                     time_over=0;
                   }
               break;
                       
               
                                                                      //    Th
            case 3://捕获到数据位高电平结束,准备捕获数据位低电平结束   _|-----|__
               
                  receive_end_h=TA1CCR0;
                  receive_start_l=TA1CCR0;
               
                  
               if(receive_end_h>=receive_start_h)
                   {
                     receive_end_h-=receive_start_h;
                   }
               
               
               else
                   {
                     receive_end_h+=(65535-receive_start_h);
                   }
               
               
               if((receive_end_h>6) &&(receive_end_h<50))//符合TE脉宽要求
               {
                   time_over=0;
                   TA1CCTL0|=CM0; // 1
                   TA1CCTL0&=~CM1;// 0上升沿
                   receive_sign=4;
                   _NOP();
               }
               else// 不符合TE脉宽要求退出
               {
                  //TA1CCTL0=CM0+SCS+CAP+OUTMOD0+CCIE;
                   time_over=0;
                  TA1CCTL0|=CM0; // 1
                  TA1CCTL0&=~CM1;// 0上升沿
                  
                  receive_sign=0;
                  receive_end_h=0;
                  receive_end_l=0;
                  BitCount=0;
                  Bptr=0;
                  time_over=0;
               }
               break;
            
                                                   //   Tl
            case 4:         //捕获到同步位低电平结束-|____|--
            
               receive_end_l=TA1CCR0;
               
               if(receive_end_l>=receive_start_l)
                   {
                     receive_end_l-=receive_start_l;
                   }
               else
                   {
                     receive_end_l+=(65535-receive_start_l);
                   }
               
               
               if((receive_end_l<6)&&(receive_end_l>50))//不符合TE脉宽要求
               {
               
                   //TA1CCTL0=CM0+SCS+CAP+OUTMOD0+CCIE;
                   time_over=0;
                  TA1CCTL0|=CM0; // 1
                  TA1CCTL0&=~CM1;// 0上升沿
                  
                  receive_sign=0;
                  receive_end_h=0;
                  receive_end_l=0;
                  BitCount = 0;
                  Bptr=0;
                  time_over=0;
               }
               
               
               
                else// 符合TE脉宽要求
                {
               
                  time_over=0;
                  receive_start_h=TA1CCR0;
               
               
                  TA1CCTL0&=~CM0; // 0
                  TA1CCTL0|=CM1;// 1 下 降 沿
                  
                  receive_sign=3;
                  
                  Rece_Data >>= 1;            // 左移一位

                  if( (receive_end_l>receive_end_h))
                  {
                      Rece_Data+=0x80;          // 置位为一
                  }

            
                   if( (++BitCount & 7) == 0)//满8位
                   {
                     Bptr++;               // advance one byte
                   }
                  
                   if (BitCount >= 65)//收完全部BIT位
                   {
      
                     // TA1CCTL0&=~CCIE;
                     
                     time_over=0;

                      P2OUT ^= BIT5; //led灯闪
                      //delay1_ms(100);
                                          
                      TA1CCTL0|=CM0; // 1
                      TA1CCTL0&=~CM1;// 0上升沿
                      receive_sign=0;
                      receive_end_h=0;
                      receive_end_l=0;
                      BitCount = 0;
                      Bptr=0;
                      // TA1CCTL0|=CCIE; // 1
                      TA1CCTL0=CM0+SCS+CAP+OUTMOD0+CCIE;//
                   }   
                                    
               }
                           
               break;
            default:
               TA1CCTL0|=CM0; // 1
               TA1CCTL0&=~CM1;// 0上升沿
               receive_sign=0;
               receive_end_h=0;
               receive_end_l=0;
               BitCount = 0;
               Bptr=0;
               time_over=0;
               break;
      }
}



高手路过,帮忙看一下。。。。

只要问题是 遥控器按下,收码时有时无。是不是哪里逻辑问题没搞好?

dimmers 发表于 2011-8-4 11:50:49

我没有看楼主的程序,不过我看了下要求,这个与单火线无线遥控开关的功能很接近,不过我有以下几个问题:
1,楼主没说用什么模式的无线接收电路,不过从“300UA静态电流的模块”可以判断用的是超再生的无线接收电路。不知道楼主在测试时是不是同时开几台机在测试了,如果是,可以是超再生电路引起的问题,因为超再生电路在工作时,会产生一个与接收频率一样的振荡,这个会干扰其它的接收机,造成接收不正常。
2,楼主的接受无线数据采用捕获功能也是有问题的,因为接收模块在工作时,其信号脚是一直有信号的,不管有没有发射信号,这样捕获脚会一直在捕获信号脚的信号,即使不是正确的信号。
3,不知道楼主的信号是只发一次还是发多次?其实采用无线传输信号时,都会有不可靠的问题,只是机率的问题,所以我们一般是采用多次重发,即使一次没接收到,多次重发也一点能接收到。

adszmc 发表于 2011-8-4 16:09:29

自己顶一下

zyw19987 发表于 2011-8-4 16:28:59

沙发,等高人讲课。

adszmc 发表于 2011-9-17 08:00:35

结贴,已经实现了接受。低功耗模式下(ACLK 捕获模式)



#pragma vector=TIMER1_A0_VECTOR
__interrupt void timea0 (void)
{
    switch(receive_sign)
    {
//----------------------------------------------------------------------------------//
    case 0:         //捕获到同步位低电平起始,准备捕获同步位低电平结束 +----   (下降沿中断)
      receive_start_l=TA1CCR0;
      TA1CCTL0|=CM0; // 1
      TA1CCTL0&=~CM1;// 0上升沿
      receive_sign=1;
      break;
//----------------------------------------------------------------------------------//
    case 1:          //捕获到低电平结束。(上升沿中断)
      receive_end_l   = TA1CCR0;
      receive_start_h = TA1CCR0;
      if(receive_end_l>=receive_start_l)
      {
            receive_end_l-=receive_start_l;
      }
      else
      {
            receive_end_l+=(65535-receive_start_l);
      }
      if( (receive_end_l>80) && (receive_end_l<210) )//判断是否是同步位
      {
            //是同步位准备接收数据位高电平结束
            receive_start_h=TA1CCR0;
            TA1CCTL0&=~CM0;// 0
            TA1CCTL0|=CM1; // 1 下降沿
            receive_sign=2;
      }
      else
      {
            //不是同步位
            TA1CCTL0&=~CM0;// 0
            TA1CCTL0|=CM1; // 1 下降沿
            receive_sign=0;
            receive_end_h=0;
            receive_end_l=0;
            BitCount=0;
            Bptr=0;
            time_over=0;
      }
      break;
//----------------------------------------------------------------------------------//
    case 2:         //____|------|______ 捕获结束(下降沿中断)
      receive_end_h=TA1CCR0;
      receive_start_l=TA1CCR0;
      if(receive_end_h>=receive_start_h)
      {
            receive_end_h-=receive_start_h;
      }
      else
      {
            receive_end_h+=(65535-receive_start_h);
      }
      if((receive_end_h>7) &&(receive_end_h<43))//符合TE脉宽要求
      {
            time_over=0;
            TA1CCTL0|=CM0; // 1
            TA1CCTL0&=~CM1;// 0上升沿
            receive_sign=3;
            _NOP();
      }
      else// 不符合TE脉宽要求退出
      {
            time_over=0;
            TA1CCTL0&=~CM0;// 0
            TA1CCTL0|=CM1; // 1 下降沿
            receive_sign=0;
            receive_end_h=0;
            receive_end_l=0;
            BitCount=0;
            Bptr=0;
            time_over=0;
      }
      break;
//----------------------------------------------------------------------------------//
      //   Tl
    case 3:         //捕获到同步位低电平结束-|____|--( 上升沿中断)
      receive_end_l=TA1CCR0;
      if(receive_end_l>=receive_start_l)
      {
            receive_end_l-=receive_start_l;
      }
      else
      {
            receive_end_l+=(65535-receive_start_l);
      }
      if((receive_end_l<7) || (receive_end_l>43))//不符合TE脉宽要求
      {
            TA1CCTL0&=~CM0;// 0
            TA1CCTL0|=CM1; // 1 下降沿
            receive_sign=0;
            receive_end_h=0;
            receive_end_l=0;
            BitCount = 0;
            Bptr=0;
            time_over=0;
      }
      else// 符合TE脉宽要求
      {
            time_over=0;
            receive_start_h=TA1CCR0;
            TA1CCTL0&=~CM0;// 0
            TA1CCTL0|=CM1; // 1 下降沿
            receive_sign=2;
            Rece_Data >>= 1; // 左移一位
            if( (receive_end_l>receive_end_h))
            {
                Rece_Data+=0x80;// 置位为一
            }
            if((++BitCount & 7) == 0)//满8位
            {
                Bptr++;
            }
            if (BitCount >= NBIT)//收完全部BIT位
            {
                //
                //TA1CCTL0&=~CCIE;
                time_over=0;
                // P2OUT ^= BIT5;
                b_RFfull=1;
                _BIC_SR_IRQ(LPM3_bits);// Clear LPM3 bits from 0(SR)
                TA1CCTL0&=~CM0;// 0
                TA1CCTL0|=CM1; // 1 下降沿
                receive_sign=0;
                receive_end_h=0;
                receive_end_l=0;
                BitCount = 0;
                Bptr=0;
            }
      }
      break;
//----------------------------------------------------------------------------------//
    default:
      TA1CCTL0&=~CM0;// 0
      TA1CCTL0|=CM1; // 1 下降沿
      receive_sign=0;
      receive_end_h=0;
      receive_end_l=0;
      BitCount = 0;
      Bptr=0;
      time_over=0;
      break;
    }
}

adszmc 发表于 2011-9-17 08:01:11

unsigned char lut =
{ 0,1,1,1, 0,1,0,0, 0,0,1,0, 1,1,1,0, 0,0,1,1, 1,0,1,0, 0,1,0,1, 1,1,0,0 };
//   E      2      4      7      C      5      A      3   //


/*********************************************************************************************************
** Function name:       Decode
** Descriptions:      滚动码解码核心程序
** input parameters:    解密原码KEY高四位    KEY低四位
** output parameters:   解码后的数据
** Returned value:      无
*********************************************************************************************************/
voidDecrypt(void)
{
    // uint32 lut =
    //{ 0,1,1,1, 0,1,0,0, 0,0,1,0, 1,1,1,0, 0,0,1,1, 1,0,1,0, 0,1,0,1, 1,1,0,0 };
//   E      2      4      7      C      5      A      3   //
    uint32 KEY_H,KEY_L,bitin,keybit,keybit2;
    uint16 bitlu;
    int ix;
    uint32 csr;
    csr=Buff;
    csr=csr<<8;
    csr+=Buff;
    csr=csr<<8;
    csr+=Buff;
    csr=csr<<8;
    csr+=Buff;
    KEY_H=DKEY;
    KEY_H=KEY_H<<8;
    KEY_H+=DKEY;
    KEY_H=KEY_H<<8;
    KEY_H+=DKEY;
    KEY_H=KEY_H<<8;
    KEY_H+=DKEY;
    KEY_L=DKEY;
    KEY_L=KEY_L<<8;
    KEY_L+=DKEY;
    KEY_L=KEY_L<<8;
    KEY_L+=DKEY;
    KEY_L=KEY_L<<8;
    KEY_L+=DKEY;
   
    for(ix=0; ix < 528; ix++)
    {
      //Rotate Code Shift Register
      bitin = getbit(csr,31);
      csr<<=1;
      // Get Key Bit
      keybit2=getbit(KEY_L,15);
      // Rotate Key Right
      keybit=getbit(KEY_H,31);
      KEY_H=(KEY_H<<1) | getbit(KEY_L,31);
      KEY_L=(KEY_L<<1) | keybit; // 64-bit left rotate //
      // Get result from Non-Linear Lookup Table
      bitlu = 0;
      ifbit (csr, 1) setbit(bitlu,0);
      ifbit (csr, 9) setbit(bitlu,1);
      ifbit (csr,20) setbit(bitlu,2);
      ifbit (csr,26) setbit(bitlu,3);
      ifbit (csr,31) setbit(bitlu,4);
      // Calculate Result of XOR and shift in
      csr= csr ^ bitin ^ ((csr&0x10000L)>>16) ^ ((uint32)lut) ^ keybit2;
    }
    Buff= (unsigned char)(csr&0x000000FF);
    Buff= (unsigned char)((csr>>8)&0x000000FF);
    Buff= (unsigned char)((csr>>16)&0x000000FF);
    Buff= (unsigned char)((csr>>24)&0x000000FF);
}
页: [1]
查看完整版本: 无线收码程序,求解~~