求助 差分曼码解码
本帖最后由 yongjia 于 2020-4-11 12:24 编辑https://img.alicdn.com/imgextra/i1/22769004/O1CN01Xue7hm2GNsln1P1Ea_!!22769004.jpg
示波器抓的波形,
自己写的AVR差分曼彻斯特解码程序,差分曼码一个周期约240uS,半个周期约120uS
按协议,一个周期内电平没有变化为1,有变化为0
使用AVR单片机的ICP捕获电平跳变脉冲中断,Timer计时判断是半个周期还是一个周期。
仿真看bit_array数组的值,也反复调时间范围,结果都不对,
用示波器看截取到的波形数据又是对的,求助高手指点迷津.
#pragma vector=TIMER1_CAPT_vect //定时器T1输入捕捉中断服务程序
__interrupt void timer1(void)
{
ICR1L = TCNT2;
if(test_end == 0) //未完成接收255Bit数组
{
if(Flag)
{
Flag = 0;
TCNT2 = 0;
ICR1L = 0;
}
if( (ICR1L >= 37) && (ICR1L <= 43) ) // ICR1L= 40 是 240US 1个周期,1个周期无变化为1
{
bit_array = 1;
bit_no++;
TCNT2 = 0;
Flag = 0;
}
if( (ICR1L >= 16) && (ICR1L <= 22)) // ICR1L= 19是120us半个周期,一个周期有变化为0
{
bit_array = 0;
Flag = 1;
TCNT2 = 0;
bit_no++;
}
}
if(bit_no >= 255) //接收完255个数
{
bit_no = 0;
test_end = 1; //设置完成标志=1
}
TCCR1B ^= (1<<ICES1); //反相下次沿触发
} 本帖最后由 yongjia 于 2020-4-11 11:53 编辑
if(bit_no134 >= 255)
{
bit_no134 = 0;
test_end134 = 1; // 设置完成标志=1 大于0.75T 小于1.25T
}
接收够255个数组后,观察数组值,始终不对, 不知道哪里糊涂了 编码没问题,解码有问题,解码算法上多想想有没有其他方式,这个对实时性要求蛮高的。
思路很重要。 一次发255Bit?有没有累积误差?每个周期重新调整计时周期的起点吗? 把脉冲时间缓冲起来,然后对应着波形一个个比对,看看误差有多少。 你可以试下,你用另一个端口同步输出,看看两个波形差别有多大 你这个跟红外解码的原理差不多,应该只用下降沿就可以了。
另外为什么不设置双边沿触发,而要在后面去动态的改变?
还有你把你当前解出来是什么样给出来啊,看一下是卡在哪个环节。 用的MEGA64单片机, 现在仿真结果,能找到数据头,但是后面数据多了就错乱了,而且几次错的还不一样 chengyang79 发表于 2020-4-11 12:40
一次发255Bit?有没有累积误差?每个周期重新调整计时周期的起点吗?
一次采集满255Bit,然后在数组里面找数据头, 每个周期都是重新计时的 如果知道时间周期就好办
T/2的时间采样电平即可,就怕时间误差累计以及变化.... 可以考虑直接用串口收,一次4bit 如果用ICP捕获容易被干扰,加一个小电容滤波应该会好些。
如果用电平采样,那么采样不要在1/2T处,这个点正是可能产生跳变的位置。
最好一个周期内均匀采样多个点进行加权判断是否发生有效跳变。 // **********************************************************************
// Routine to decode a Manchester bit
// Pass in the previous bit logic value
// *********************************************************************/
unsigned char Coding_ManchesterDecode(unsigned char cBit)
{
unsigned char cOutput = BitErr;
unsigned int tmp;
tmp = Coding_Timer_Poll(); // Catch next edge time
if(tmp < UPPERTIMINGLMT) // Check if edge time is useable
{
// Check edge time and determine next Logic value //
if((tmp > DecodeReadTime.LongL) && (tmp < DecodeReadTime.LongH))
{cOutput = cBit ^ 0x01;} // invert cBit for logical change
else if(tmp > DecodeReadTime.ShortL && tmp < DecodeReadTime.ShortH)
// Next edge time is short
{
tmp = Coding_Timer_Poll();
if(tmp > DecodeReadTime.ShortL &&
tmp < DecodeReadTime.ShortH)
{cOutput = cBit;} // bit stays the same
else{cOutput = BitErr;} // Un-paired short time
}
else {cOutput = BitErr;} // Edge time outside limits
}
return cOutput;
} 看看这个可能有用 有缘人我才说一句,你这种一个周期约240uS,半个周期约120uS的差分曼码用上面的各种答案是无法答题的,要换思路。这不是啥曼彻斯特码,是两相(Biphase)码。
页:
[1]