用定时器进行miller2编码的思考

时间:2022-06-29 00:31:21

因为编码过程中没有办法进行定时器的输出翻转,否则数据中间会出现很多尖峰脉冲跳变。

所以现在只能在不使用翻转的情况下,进行编码,所以就要使用到状态图,当前状态,之前状态以及以后状态

决定了数据的来龙去脉。

下面是编码的状态图手稿

用定时器进行miller2编码的思考

用定时器进行miller2编码的思考

下面是打出来的miller2码的波形

用定时器进行miller2编码的思考


下面是代码

void  __irq timer1_miller2_data2(void)
{

rSRCPND |=1<<11;//
rINTPND |=1<<11;//清除timer1的中断
//Uart0_Printf("enter timer1 miller2_data2 irq \n");
cnt++;
if(cnt<=32)//16个前0状态
{
rTCON&=~(1<<10);//无需要翻转
rTCNTB1=312;
rTCMPB1=156;
status=s0;//起始状态
}
else if(cnt>(32+bits_cnt))//超过要发送的位数
{
rTCON &=~(1<<8);//关闭定时器1
rINTMSK|=1<<11;//屏蔽定时器1中断
status=s0;//返回初始状态
cnt=0;//计数值初始化
int_finish=1;
status_cnt=0;
}
else
{
if(1==data[cnt-33])
{
switch(status)
{
case s0:
count_b();//
status=s2;//完成
break;
case s1:
cnt--;//变成s7之前自己要把cnt--,以防止问题出现,s7就不用再减cnt了
count_a();//
status=s4;//未完成
break;
case s2:
count_c();//
status=s7;//未完成
break;
case s3:
cnt--;//变成s7之前自己要把cnt--,以防止问题出现,s7就不用再减cnt了
count_a();//
status=s6;//未完成
break;
case s4:
count_b();
status=s2;
break;
case s6:
count_c();
status=s7;
break;
case s7:
cnt--;
count_a();
status=s0;
break;
case s8:
cnt--;
count_a();
status=s6;
break;
}//switch(status)

}// if(1==data[cnt-33])
else
{
switch(status)
{
case s0:
count_a();//
status=s1;//未完成
break;
case s1:
count_b();//
status=s3;//未完成
break;
case s2:
count_a();//
status=s8;//未完成
break;
case s3:
cnt--;//变成s7之前自己要把cnt--,以防止问题出现,s7就不用再减cnt了
count_c();//
status=s5;//未完成
break;
case s5:
count_a();
status=s1;
break;
case s7:
cnt--;
count_a();
status=s0;
break;
case s8:
cnt--;
count_c();
status=s5;
break;
}//switch(status)
}// if(1==data[cnt-33]) 的else
}//最后的else
sta_register[status_cnt++]=status;
}


一开始打出来的波形肯定是不对的,因为那么多状态,你想兼顾,有点困难哈,所以使用一个数组sta_register[100]来保存每一次中断时的状态

然后打印出来,跟所需要的状态进行对比,如果没有错误,就是对的波形,如果有错误,那么在有错误的地方找到那个case语句,进行修改,就OKay了哈

注意数据尾部 要加一个数据1,即dummy位,实际上面的代码,在最后的位置会产生一个高低电平的count_a(0;

应该要避免

实际上真正能用的是快速中断模式,这样能大大地加快运行速度哈。

而且if条件的判断顺序有一定的要求,不然出不来要求的波形,比较恼火的