QEP解码
QEP解码即将两路相位相差90度传感器信号转换为方向dir,脉冲plus,脉冲数量counter(根据方向和脉冲得出的绝对脉冲数)。
本程序采用下表所示关系做QEP解码
程序中,输入为clk,rst,a, b,输出为dir, plus, counter。程序中HITHTIME用来控制plus高电平时间。
程序如下:
/*************************************************
//module name:qepdecode
//designer:kang
//date:2010-10-08
*************************************************/
module qepdecode(
//input signals
clk,
rst,
a,
b,
//output signals
dir,
plus,
counter
);
input clk;
input rst;
input a;
input b;
output dir;
output plus;
output [15:0] counter;
reg dir;
reg plus;
reg [15:0] counter;
reg [1:0] priorba;
reg [1:0] nowba;
reg [3:0] prioredge;
reg [3:0] nowedge;
wire [3:0] saveab;
wire [7:0] saveedge;
reg [3:0] sign;
reg cp;
reg [15:0] counter_plush;
parameter IDLE=4'h0;
parameter UPA=4'h1;
parameter DOWNA=4'h2;
parameter UPB=4'h3;
parameter DOWNB=4'h4;
parameter HIGHTIME=16'd0;
assign saveab={priorba,nowba};
assign saveedge={prioredge,nowedge};
//save nowstate and prior
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
nowba<=2'b00;
priorba<=2'b00;
end
else
begin
nowba<={b,a};
priorba<=nowba;
end
end
//save the edge change of a and b
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
prioredge<=IDLE;
nowedge<=IDLE;
cp<=0;
end
else
begin
case(saveab)
4'b0001:begin
prioredge<=nowedge;
nowedge<=UPA;
cp<=1;
end
4'b1011:begin
prioredge<=nowedge;
nowedge<=UPA;
cp<=1;
end
4'b0010:begin
prioredge<=nowedge;
nowedge<=UPB;
cp<=1;
end
4'b0111:begin
prioredge<=nowedge;
nowedge<=UPB;
cp<=1;
end
4'b0100:begin
prioredge<=nowedge;
nowedge<=DOWNA;
cp<=1;
end
4'b1110:begin
prioredge<=nowedge;
nowedge<=DOWNA;
cp<=1;
end
4'b1000:begin
prioredge<=nowedge;
nowedge<=DOWNB;
cp<=1;
end
4'b1101:begin
prioredge<=nowedge;
nowedge<=DOWNB;
cp<=1;
end
default:cp<=0;
endcase
end
end
//direction make
//"sign" allows direction reverse
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
sign<=4'b1111;
dir<=1;
end
else
begin
case(saveedge)
8'h13: //upa and upb
begin
dir<=1;
sign<=4'b1111;
end
8'h14: //upa and downb
begin
dir<=0;
sign<=4'b1111;
end
8'h12:if(sign[0]) //upa and downa
begin
dir<=!dir;
sign<=4'b1110;
end
8'h24: //downa and downb
begin
dir<=1;
sign<=4'b1111;
end
8'h23: //downa and upb
begin
dir<=0;
sign<=4'b1111;
end
8'h21:if(sign[1]) //downa and upa
begin
dir<=!dir;
sign<=4'b1101;
end
8'h31: //upb and upa
begin
dir<=0;
sign<=4'b1111;
end
8'h32: //upb and downa
begin
dir<=1;
sign<=4'b1111;
end
8'h34:if(sign[2]) //upb and downb
begin
dir<=!dir;
sign<=4'b1011;
end
8'h42: //downb and downa
begin
dir<=0;
sign<=4'b1111;
end
8'h41: //downb and upa
begin
dir<=1;
sign<=4'b1111;
end
8'h43:if(sign[3]) //downb and upb
begin
dir<=!dir;
sign<=4'b0111;
end
default:;
endcase
end
end
//counter
always @(posedge clk or negedge rst)
begin
if(!rst) counter<=16'h0;
else
if(cp)
if(dir) counter<=counter+1'b1;
else if(counter>0) counter<=counter-1'b1;
end
//counter_plush
always @(posedge clk or negedge rst)
begin
if(!rst) counter_plush<=HIGHTIME+1'b1;
else if(cp) counter_plush<=0;
else counter_plush<=counter_plush+1'b1;
end
//plus
always @(posedge clk or negedge rst)
begin
if(!rst) plus<=0;
else if(counter_plush<=HIGHTIME) plus<=1;
else plus<=0;
end
endmodule
仿真波形
文章评论(0条评论)
登录后参与讨论