7多摩川编码器总结Word文档格式.docx
《7多摩川编码器总结Word文档格式.docx》由会员分享,可在线阅读,更多相关《7多摩川编码器总结Word文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
17位(131072)多圈精度:
16位(65536)
最高转速/(r·
min-1):
6000】
输出:
差分NRZ编码二进制
传输速度/Mbps:
2.5
发送、接收电路:
差分形式
通信方式:
主从模式
接口:
3FG,4sig+,5sig-,7VCC,8DGND。
4和5为差分信号接口。
2、通信步骤如下图:
(逻辑链路层)
1)CPLD向编码器发送一个控制字CF
2)3us后编码器返回数据包。
4)数据传输
正如CF介绍中提到,不同的CF控制命令会对应不同的数据结构传输。
主要有三类,而我们用的是DataID0,绝对数据传输。
后面的空格表明没有数据传输。
数据传输中,低位在前,高位在后,每一字都是以0开始以1结束。
由于是17位精度编码器,DF2数据位的高7位都是0。
五、需求分析
1、启动
DSP每隔60us向CPLD发送一个启动脉冲,CPLD捕捉到上升沿后开始向编码器发送CF请求命令。
如果CPLD已经处于发送或接受状态,再接收到启动脉冲,不予响应。
2、485使能
由于CPLD与编码器的通讯需要MAX485进行电平转换,而MAX485是一个半双工器件,因此,需要提供一个端口控制485的使能端,决定485的读写控制。
3、频率要求
板子上提供10M频率的时钟,而多摩川编码器的通讯协议需要2.5M频率时钟,因此需要分频。
4、异常情况分析
考虑到传输过程中的异常情况(比如把“0”传输成“1”,或者反之),以及其他可能会出现的错误情况。
1)编码器接受到错误的CF,给出了相应的回应。
2)编码器接受到错误的CF,没有回应。
3)编码器自身出现错误(在SF中会给出错误类型)。
5、与DSP的通讯
得到绝对位置值之后,需要将读取的结果发送给DSP,而这一过程需要提供一个端口使CPLD与DSP连接。
六、整体设计
1、流程图
基于多摩川编码器的通讯协议以及需求分析,可以做出以下流程图。
有启动脉冲
无响应或无正确响应
正确完成一周期或
错误结束一周期
有正确响应
2、分配状态
根据流程图,可以通过“状态机”来完成各个状态之间的切换,因此,分配状态为:
Idle(闲置),Request(请求),Wait(等待),Receive(接收)四个状态。
状态机的编写有一段式、两段式和三段式,这里状态比较简单,可以采用结构简单的一段式。
(对于复杂的状态机,不推荐使用一段式)
具体写法如下:
reg[1:
0]state
parameter
Idle=2'
b00,Request=2'
b01,
Wait=2'
b10,Receive=2'
b11;
…
case(state)
Idle:
…
Request:
Wait:
Receive:
3、闲置状态
CPLD处于闲置状态,等待DSP发送命令。
当DSP发送启动脉冲后,CPLD检测到上升沿,即由闲置状态进入请求状态,同时,为请求状态做好初始化准备。
而在其它状态检测到上升沿时,则不予响应。
具体代码如下:
1)检测启动脉冲
always@(posedgestartorposedgestart_fg1)
begin
if(start==1)start_fg<
=1'
b1;
if(start_fg1==1)start_fg<
b0;
end
2)状态更改并为请求状态做好初始化准备
begin
txd<
=1;
if(start_fg==1'
b1)
begin
state<
=Request;
E_c<
//485使能,1向编码器写数据
start_fg1<
end
end
4、请求状态
CPLD处于请求状态时,每一个时钟周期发送一个高低电平。
请求命令为:
0010000001。
发送结束后,进入等待状态,等待编码器响应。
if(i==8'
d10)//发送结束
=Wait;
=0;
//485使能,0接受编码器数据
CF_r<
=10'
d0;
txd<
i<
else
=CF[9-i];
=i+1'
5、等待状态
CPLD处于等待状态时,等待编码器相应。
编码器一旦发送低电平过来,为避免传输干扰,设定了一个头部检测。
头部检测的方式为,每次左移并接受一个数据,检测开始的头4位,如果头4位正确,则进入到接受状态;
如果头4位不正确,则继续左移并接受数据,在指定时间内,如果没有成功接受到数据,则认为这一次通讯失败,并给出错误类型erro<
=2'
d3,同时数据位报全1(数据位默认为全1),并且进入到闲置状态,等待下一次的请求命令。
在最初设计时,这里加入了一个“超时重发”的功能,即通讯失败后进入请求状态,重新发送请求命令,再次进入到等待状态,并且允许超时重发3次,3次都失败后则执行前面提到的错误处理办法。
只是后来由于时间以及资源的闲置,把这一个模块删掉了,如果资源以及时间允许的话,可以考虑加上这一模块。
Wait:
E_b<
if(CF_r[3:
0]==4'
b0010)//头检测
begin
=Receive;
=(CF_r<
<
1)|re;
=4;
if(i==4'
d14)
begin
state<
=Idle;
erro<
d3;
end
else
i<
6、接受状态
这一状态是编码器的主要工作状态,同时由于接收的信息比较多,也是处理起来比较麻烦的一部分。
首先,利用计数器计数10次,读出CF信息,并且保存到CRC_buf里;
再次利用计数器计数10次,读出SF信息,也保存在CRC_buf里;
再利用计数器计数30次,取出位置信息,这里需注意一点,编码器发回的位置信息是低位在前,高位在后,因此,在接受数据时,需要将其调整一下。
最后,利用计数器计数10次,读出CRC的信息。
接收完数据后,就进行CRC校验。
由于这一部分工作是同组另一位学长完成,这里不做具体阐述。
如果CRC校验通过,则输出位置信息;
如果CRC校验不通过,则输出错误信息,并且报全1。
以上是正常情况,同时还需要对CF进行检查。
如果发回的CF与发送出去的CF不同,则出错。
出错的话,按照协议,编码器可能会发回一个最长的数据包,与实际情况不符。
因此,也算作一种错误。
另外,SF的错误信息是编码器自身的错误,根据要求,如果有这种错误的话,需要断电处理。
因此,检测到这种错误时,给出错误信息,并不需要额外处理。
代码如下:
begin
if(i<
9)
elseif(i==9)//CF检验
if(CF_r==CF)
CRC_buf<
=CRC_buf|{CF_r[8:
1],40'
d0};
CF_r<
elseif(i<
19)
elseif(i==19)
if(CF_r[4]|CF_r[3])//检测SF,出错应该断电处理begin
d2;
1],32'
DATA1<
=(DATA1>
>
1)|{re,29'
end
49)
DATA1<
i<
59)
end
DATA1[23:
0]={DATA1[28:
21],DATA1[18:
11],DATA1[8:
1]};
for(i=0;
i<
24;
i=i+1)
CRC_buf[31-i]=DATA1[i];
CRC_buf=CRC_buf|CF_r[8:
1];
for(i=47;
i>
7;
i=i-1'
begin
CRC_buf[47:
40]={CRC_buf[46:
40],(CRC_buf[47]^CRC_buf[39])};
CRC_buf[39:
0]=CRC_buf[38:
0]<
1;
//shift
if(!
CRC_b