基于Verilog HDL的一种绝对值编码器实时读出算法案例详解

FPGA/ASIC技术

190人已加入

描述

光电编码器是通过光电转换将输出轴上的机械几何位移量转换成一串脉冲或数字量的传感器。在电机伺服控制系统中,它与电机同轴连接,常用来测量电机转子的速度和位置[1]。近年来,随着研究室小批量军工生产的开展,需要批量采购部分绝对值编码器等外协器件。为方便检验采购的编码器,保障生产任务的按时完成,设计了一个单圈绝对值编码器实时读出电路板,其结构如图1所示。基于此电路板,开发出了一个程序,它能够实现将绝对值编码器的数据读入FPGA,并将数据转换为角度值,最终驱动液晶显示屏实时输出角度值。这使得不需要将编码器数据输入到计算机就可以处理转化为角度值,使用更加方便。程序中用到了线性变换思想,可以应用到其他程序中。电路板中用到的绝对值编码器是BEI-IDEACOD公司的CHO5系列。液晶显示屏为3.3 V供电的1602型LCD,FPGA采用的是Xilinx的Spartan-6系列。

编码器

1 数据读入及去抖动

本文所采用的绝对值编码器是BEI-IDEACOD公司的CHO5系列,它采用并行输出模式,有13 bit数据(Data[0]~Data[12]),读出速度快。由于电动机的旋转或机械设备的震动,会使编码器输出脉冲抖动[2],因此首先对编码器脉冲进行了去抖动处理。下面的程序实现了数据读入,并在去抖动后被锁存在Gray_data中。

always@(posedge clk_50M)

begin

D0《={D0[1:0],Data[0]};

D1《={D1[1:0],Data[1]};

。。.。。.

D11《={D11[1:0],Data[11]};

D12《={D12[1:0],Data[12]};

end

always@(posedge clk_50M)

begin

Gray_data[0]《=D0[2]&D[1]&D[0];

Gray_data[1]《=D1[2]&D[1]&D[0];

。。.。。.

Gray_data[11]《=D11[2]&D[1]&D[0];

Gray_data[12]《=D12[2]&D[1]&D[0];

end

2 二进制格雷码转普通格雷码

上面得到数据Gray_data还是格雷码,因为绝对值编码器(并行输出)采用的是格雷码二进制输出。格雷码的特点是任意两个相邻位其输出格雷码值只有一位不同[3],这提高了数据输出的稳定性。假设二进制格雷码为Gn-1 Gn-2…G2G1G0,其所对应的普通二进制为Bn-1Bn-2…B2B1B0。那么它们最高位之间的对应关系如式(1)所示,其他各位的对应关系如式(2)所示。

Bn-1=Gn-1(1)

Bi-1=Gi-1^Bi, i=1,2,…,n-1(2)

根据式(1)和式(2),格雷码二进制转化为普通二进制的Verilog HDL代码如下:

always@(posedge Clk_50M)

begin

Binary_data[12]=Gray_data[12];

Binary_data[11]=Binary_data[12]^Gray_data[11];

Binary_data[10]=Binary_data[11]^Gray_data[10];

。。.。。.

Binary_data[1]=Binary_data[2]^Gray_data[1];

Binary_data[0]=Binary_data[1]^Gray_data[0];

end

该程序实现了由格雷码二进制Gray_data向普通二进制Binary_data的转换。

3 将二进制转为角度值

绝对值编码器的最小精度是由最低位决定的。因为所用的绝对值器是13 bit数据输出,绝对值编码器的最低位为1时,对应的角度值如式(3)所示:

因此,绝对值编码器的最小精度为min=0.043 945 312 5°。也就是说二进制编码每加1,度数就应该增加0.043 945 312 5°。为方便在Verilog HDL中进行处理,对这种十进制数进行一个线性变换,将其最小精度值对应二进制min_degree=2′b000000000000011010001100011000010111000101,其实就是十进制数439 453 125对应的二进制数。相对于编码器输出的二进制数,将这个二进制数称为编码二进制。这样就对每一个编码器输出的13 bit二进制进行了一个线性变化,转化为对应的编码二进制Now_degree。其对应关系如式(4)所示,其中的“《《”是左移位运算符。

Now_degree=Binary_data[0]min_degree+Binary_data[1](min_degree《《1)++Binary_data[11](min_degree《《11)+ Binary_data[12](min_degree《《12) (4)

为了得出在每一数据位(百位、十位、一直到小数点后10位)上需要输出什么数据,需要求出每个数据位权值(即次位数据为1时的值)对应的编码二进制,数据位权值对应的编码二进制如表1所示。其中Decimal10_degree指的是小数点后第10位权值所对应的编码二进制,以此类推,Hundred_degree是百位上权值所对应的编码二进制。

编码器

通过将Now_degree与各位对应的编码二进制一一比较,使用状态机得出具体实现各数据位上的数值:Decimal1Decimal1、Single、Ten、Hundred。具体Verilog HDL代码如下所示:

always@(posedge Clk_50M)

begin

4′b0000:

begin

if(Buf_degree》=Hundred_degree)

begin

Buf_degree=Buf_degree-Hundred_degree;

Temp_Hundred=Temp_Hundred+1;

Sta=4′b0000;

end

else

begin

Sta=4′b0010;

end

end

4′b0001:

begin

if(Buf_degree》=Ten_degree)

begin

Buf_degree=Buf_degree-Ten_degree;

Temp_Ten=Temp_Ten+1;

Sta=4′b0001;

end

else

begin

Sta=4′b0010;

end

end

4′b1100:

begin

if(Buf_degree》=Decimal10_degree)

begin

Buf_degree=Buf_degree-Decimal10_degree;

Temp_Decimal10=Temp_Decimal10+1;

Sta=4′b1101;

end

else

begin

Sta=4′b1101;

end

end

4′b1101:begin

Hundred=Temp_Hundred;

Ten=Temp_Ten;

Single=Temp_Single;

Decimal1=Temp_Decimal1;

Decimal2=Temp_Decimal2;

Decimal3=Temp_Decimal3;

Decimal4=Temp_Decimal4;

Decimal5=Temp_Decimal5;

Decimal6=Temp_Decimal6;

Decimal7=Temp_Decimal7;

Decimal8=Temp_Decimal8;

Decimal9=Temp_Decimal9;

Decimal10=Temp_Decimal10;

Sta=4′b0000;

end

default:begin

Sta=4′b0000;

end

endcase

end

该程序最终实现了将绝对值编码器输出的普通二进制数转化为角度值。例如,一个普通二进制数0100100110010先通过式(3)运算,转化为Now_degree,然后再通过上述代码就可以被转化为103447265625(依次为从百位上的值到小数点后第10位上的值)。这样就得到了角度值103.447 265 625°。

4 液晶显示屏驱动

LCD1602是一个16行2列的液晶显示屏,因为所需要的数据位(算上小数点)总共14位,所以完全满足角度值输出要求。LCD1602内置192种字符,显示字符时,要先输入显示字符地址,即告诉模块在哪里显示字符[4]。由于只需要显示角度,因此只需要知道数字0~9和小数点(。)的地址就可以了,如表2所示。从表2中可以看出,数字地址的前4位都是0011,而后4位正好是数字的二进制表示,这给编写驱动液晶屏的编码带来了很大方便,可以直接采用类似下面的语句输出:

Lcd_data《={4′b0011,Hundred};

这样就将从百位上的值Hundred到小数点后10位上的值Decimal10依次输到液晶显示屏上了。其中的Lcd_data是接LCD1602的8 bit数据位。上面并不是程序中的真正代码,因为液晶显示屏驱动需要初始化,且需要严格时序控制,程序较长,这里就不给出具体代码了。

编码器

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分