搜索
bottom↓
回复: 5

无线收码程序,求解~~

[复制链接]

出0入0汤圆

发表于 2011-8-4 10:49:01 | 显示全部楼层 |阅读模式
最近一个小项目需要做滚动码遥控器,接收部分是电池供电的产品,外围预留接口给接收模块,这就要求滚动码接受解码部分需要低功耗要求。

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

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

帧格式(hsc300)

(原文件名:1.jpg)

码的冗余度:

(原文件名:2.jpg)


(原文件名:3.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 )
  {
    case  2:                                  // 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;
    case  4: 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[Bptr] >>= 1;              // 左移一位

                  if( (receive_end_l>receive_end_h))
                    {
                      Rece_Data[Bptr]+=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;
        }
}



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

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

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

出0入0汤圆

 楼主| 发表于 2011-8-4 16:09:29 | 显示全部楼层
自己顶一下

出0入0汤圆

发表于 2011-8-4 16:28:59 | 显示全部楼层
沙发,等高人讲课。

出0入0汤圆

 楼主| 发表于 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[Bptr] >>= 1; // 左移一位
            if( (receive_end_l>receive_end_h))
            {
                Rece_Data[Bptr]+=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;
    }
}

出0入0汤圆

 楼主| 发表于 2011-9-17 08:01:11 | 显示全部楼层
unsigned char lut[32] =
{ 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:      无
*********************************************************************************************************/
void  Decrypt(void)
{
    // uint32 lut[32] =
    //{ 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[3];
    csr=csr<<8;
    csr+=Buff[2];
    csr=csr<<8;
    csr+=Buff[1];
    csr=csr<<8;
    csr+=Buff[0];
    KEY_H=DKEY[7];
    KEY_H=KEY_H<<8;
    KEY_H+=DKEY[6];
    KEY_H=KEY_H<<8;
    KEY_H+=DKEY[5];
    KEY_H=KEY_H<<8;
    KEY_H+=DKEY[4];
    KEY_L=DKEY[3];
    KEY_L=KEY_L<<8;
    KEY_L+=DKEY[2];
    KEY_L=KEY_L<<8;
    KEY_L+=DKEY[1];
    KEY_L=KEY_L<<8;
    KEY_L+=DKEY[0];
   
    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[bitlu]) ^ keybit2;
    }
    Buff[0]= (unsigned char)(csr&0x000000FF);
    Buff[1]= (unsigned char)((csr>>8)&0x000000FF);
    Buff[2]= (unsigned char)((csr>>16)&0x000000FF);
    Buff[3]= (unsigned char)((csr>>24)&0x000000FF);
}
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-19 00:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表