你的位置:EETOP 赛灵思(Xilinx) 社区 >> >> 全部 >> 详细内容

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

发布者:jackzhang 时间:2013-03-07 22:10:01

光电编码器是通过光电转换将输出轴上的机械几何位移量转换成一串脉冲或数字量的传感器。在电机伺服控制系统中,它与电机同轴连接,常用来测量电机转子的速度和位置[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数据位。上面并不是程序中的真正代码,因为液晶显示屏驱动需要初始化,且需要严格时序控制,程序较长,这里就不给出具体代码了。

 

 把程序下载到开发板后,程序运行正常,角度值被写到了液晶显示屏第一行上,如图3所示。液晶屏动态刷新显示,程序中设计每隔900 ns读入一个字符,读入16个字符共需0.014 4 ms。显示所有的8 192个状态(即旋转一周)最短需要117.964 8 ms,因此能够实现实时显示。通过检验,该系统运行稳定,能够获得稳定的角度值输出。
 本文用Verilog HDL设计了一种绝对值编码器实时读出程序,仿真和在电路板上的测试表明,该绝对值编码器运行正常。程序采用模块化编程,一致性较好。其中,在二进制数转角度值时用到了线性变换的思想,解决了在用Verilog HDL处理角度值输出问题。使编码器数据不传入计算机也可以得到处理,具有较大实用性。
参考文献
[1] 陈赟,赵兴国.基于PCI总线的单圈绝对式光电轴角编码器实时数据采集系统[J].光子学报,2007,36(3):421-424.
[2] 夏冬梅,孙林.基于CPLD的增量式旋转编码器接口电路模块设计[J].机械制造与自动化,2009(5):156-157,160.
[3] 周政,李菊芬.绝对值编码器在高炉料车控制中的应用[J].南钢科技与管理,2006(2):47-48.
[4] 于志赣,刘国平,张旭斌.液晶LCD1602模块的应用[J].机电技术,2009(3):58-59.

最新课程

  • 深入浅出玩儿转FPGA

    本视频基于Xilinx公司的Artix-7FPGA器件以及各种丰富的入门和进阶外设,提供了一些典型的工程实例,帮助读者从FPGA基础知识、逻辑设计概念

  • 从零开始大战FPGA基础篇

    本课程为“从零开始大战FPGA”系列课程的基础篇。课程通俗易懂、逻辑性强、示例丰富,课程中尤其强调在设计过程中对“时序”和“逻辑”的把控,以及硬件描述语言与硬件电路相对应的“

  • Verilog基础及典型数字

    课程中首先会给大家讲解在企业中一般数字电路从算法到流片这整个过程中会涉及到哪些流程,都分别使用什么工具,以及其中每个流程都分别做了