无线收码程序,求解~~
最近一个小项目需要做滚动码遥控器,接收部分是电池供电的产品,外围预留接口给接收模块,这就要求滚动码接受解码部分需要低功耗要求。载波使用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;
}
}
高手路过,帮忙看一下。。。。
只要问题是 遥控器按下,收码时有时无。是不是哪里逻辑问题没搞好? 我没有看楼主的程序,不过我看了下要求,这个与单火线无线遥控开关的功能很接近,不过我有以下几个问题:
1,楼主没说用什么模式的无线接收电路,不过从“300UA静态电流的模块”可以判断用的是超再生的无线接收电路。不知道楼主在测试时是不是同时开几台机在测试了,如果是,可以是超再生电路引起的问题,因为超再生电路在工作时,会产生一个与接收频率一样的振荡,这个会干扰其它的接收机,造成接收不正常。
2,楼主的接受无线数据采用捕获功能也是有问题的,因为接收模块在工作时,其信号脚是一直有信号的,不管有没有发射信号,这样捕获脚会一直在捕获信号脚的信号,即使不是正确的信号。
3,不知道楼主的信号是只发一次还是发多次?其实采用无线传输信号时,都会有不可靠的问题,只是机率的问题,所以我们一般是采用多次重发,即使一次没接收到,多次重发也一点能接收到。 自己顶一下 沙发,等高人讲课。 结贴,已经实现了接受。低功耗模式下(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;
}
} 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]