Yindow

【红色飓风Nano二代测评】旋转编码器

0
阅读(2896)

旋转编码器在数控机床、小车等对于保持一定精度的速度控制或者位置控制系统的检测器件。还记得第一次接触旋转编码器,是大三的时候,那个时候学校正在组织PLC大赛,其中有一题就是编写AB相编码器的驱动。今天偶然在实验室清理东西的时候,发现了一个旋转编码器,那就通过它谢谢nano开发板的测评吧!

我这里使用的是一个增量式的旋转编码器,也就是当编码器旋转时,会有相应的相位输出。其计数的起点可以从任意位置开始设定,可以实现多圈的无限累加和测量。一般的增量式的编码器会有一个Z信号,编码器每转一圈就发出一个脉冲的Z信号,作为参考机械零位。也就是说我们只用检测Z信号的频率就可以知道编码器的转速了。但是这样做的话,分辨率不是很高,为了提高分辨率,我们一般是使用带90度相位差的AB两路信号。我这个编码器上面有一个参数显示的是“Resolution 2000P/R”,我这个的分辨率就是2000.

我曾经在一个做数控机床厂上班的时候,他们那边也用到了旋转编码器,但是他们不是用的FPGA驱动,也不是用的单片机,居然是在一块10cm*15cm的电路板上面,几乎摆满了一些数字芯片,就用这些东西做的,后来我问他们为啥要用这么多的数字芯片,他们给我的答复是,这个模块是一二十年前的了!估计那个时候单片机啊FPGA啊什么的还没有普及哦。科技在进步,现在FPGA驱动这个旋转编码器也就20个逻辑门左右。

如下图1所示,是当编码器旋转的时候发出来的波形。

 

图1 AB相计数

从图中我们可以看出,当A相的脉冲的下降沿对应的是B脉冲的高电平的时候,我们认为编码器为正向旋转,当A相的脉冲下降沿对应的是B脉冲的低电平的时候我们认为编码器为反向旋转;同理,当B脉冲的上升沿对应的A脉冲的高电平的时候,为正转,B脉冲的上升沿对应的A脉冲的低电平的时候,为反转。。。。后面的大家可以自行去归纳。

源码如下:

  module ENCODER
  (
  	input clk,
  	input rst_n,
  	
  	input inA,
  	input inB,
  	
  	output[7:0] led
  
  	//output[47:0] COUNTDat
  );
  
  reg[2:0] Arr,Brr;
  
  always @ (posedge clk or negedge rst_n)
  begin
  	if(!rst_n)
  		begin
  			Arr <= 3'd0;
  			Brr <= 3'd0;
  		end
  	else
  		begin
  			Arr <= {Arr[1:0],inA};
  			Brr <= {Brr[1:0],inB};
  		end
  end
  
  wire RA = (Arr[2:1] == 2'b01);	//获取A相上升沿
  wire FA = (Arr[2:1] == 2'b10);	//获取A相下降沿
  
  wire RB = (Brr[2:1] == 2'b01);	//获取B相上升沿
  wire FB = (Brr[2:1] == 2'b10);	//获取B相下降沿
  
  reg[31:0] COUNT;
  always @ (posedge clk or negedge rst_n)
  begin
  	if(!rst_n)
  		begin
  			COUNT <= 32'd0;
  		end
  	else if((RA & (!inB)) || (FA & ( inB)) || (RB & ( inA)) || (FB & (!inA)))
  		begin
  			COUNT <= COUNT + 1'b1;
  		end
  	else if((RA & ( inB)) || (FA & (!inB)) || (RB & (!inA)) || (FB & ( inA)))
  		begin
  			COUNT <= COUNT - 1'b1;
  		end
  end
  
  //assign COUNTDat = {8'HAA,COUNT,8'H55};
  assign led = COUNT[15:8];	//通过LED观察数据
  
  endmodule

 

nano开发板上面的引脚对于如下:

NET "clk"  LOC = "M9"  ; 

NET "rst_n"  LOC = "P7"  ;

 

NET "led[0]"  LOC = "M12"  ; 

NET "led[1]"  LOC = "L12"  ; 

NET "led[2]"  LOC = "L13"  ; 

NET "led[3]"  LOC = "M14"  ; 

NET "led[4]"  LOC = "R12"  ; 

NET "led[5]"  LOC = "T12"  ; 

NET "led[6]"  LOC = "T13"  ; 

NET "led[7]"  LOC = "T14"  ; 

 

NET "inA"  LOC = "R16"  ; 

NET "inB"  LOC = "T15"  ; 

 

下面是正转效果图:

 

 

下面是反转效果图: