两相编码器的驱动原理
根据A,B相的相位差,即相位的领先或落后来判断编码器转轴旋转方向,根据编码器旋转产生的脉冲来计数。
二、输出信号
1、信号序列
一般编码器输出信号除A、B两相(A、B两通道的信号序列相位差为90度)外,每转一圈还输出一个零位脉冲Z。
当主轴以顺时针方向旋转时,按下图输出脉冲,A通道信号位于B通道之前;当主轴逆时针旋转时,A通道信号则位于B通道之后。从而由此判断主轴是正转还是反转。
摘自:原创置顶 李逍遥~
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.youkuaiyun.com/weixin_42562514/article/details/89435902
两相旋转编码器的FPGA驱动代码
//编码器驱动
//作者:杨成煜
//日期:2020/4/11
//==================defines=====================
`define SIM
module encoder(
//================System Signal================
input clk,
input rst_n,
//================Interface====================
input a,
input b,
output reg[31:0] cnt
);
//================parameters===================
`ifndef SIM
`else
`endif
localparam S_IDLE = 5'b00001;
localparam S_PLUS_CHECK = 5'b00010;
localparam S_PLUS = 5'b00100;
localparam S_MINUS_CHECK = 5'b01000;
localparam S_MINUS = 5'b10000;
//================System regs==================
reg a_t0;
reg a_t1;
reg b_t0;
reg b_t1;
reg[4:0] state;
wire a_pedge;
wire b_pedge;
wire a_nedge;
wire b_nedge;
//================Main Codes===================
//a,b temp
always @(posedge clk)begin
a_t0 <= a;
a_t1 <= a_t0;
b_t0 <= b;
b_t1 <= b_t0;
end
assign a_pedge = a_t0&(~a_t1);
assign a_nedge = ~a_t0&a_t1;
assign b_pedge = b_t0&(~b_t1);
assign b_nedge = ~b_t0&b_t1;
//state machine
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
state <= S_IDLE;
else case(state)
S_IDLE:begin
if(a_pedge==1'b1)
state <= S_PLUS_CHECK;
else if(b_pedge==1'b1)
state <= S_MINUS_CHECK;
else
state <= S_IDLE;
end
S_PLUS_CHECK:begin
if(b_pedge==1'b1)
state <= S_PLUS;
else if(a_pedge==1'b1)
state <= S_IDLE;
else
state <= S_PLUS_CHECK;
end
S_PLUS:begin
state <= S_IDLE;
end
S_MINUS_CHECK:begin
if(a_pedge==1'b1)
state <= S_MINUS;
else if(b_pedge==1'b1)
state <= S_IDLE;
else
state <= S_MINUS_CHECK;
end
S_MINUS:begin
state <= S_IDLE;
end
default:state <= S_IDLE;
endcase
end
//cnt
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
cnt <= 'd0;
else if(state==S_PLUS)
cnt <= cnt + 1'b1;
else if(state==S_MINUS)
cnt <= cnt - 1'b1;
end
endmodule
仿真脚本
//编码器仿真脚本
//日期:2020/4/11
//作者:杨成煜
`timescale 1ns/1ns //时间精度
`define clock_period 20 //时钟周期
module tb_encoder; //实体名称
//=====================<系统端口>=============================
reg clk;
reg rst_n;
//=====================<外设端口>=============================
reg a;
reg b;
wire[31:0] cnt;
integer i;
integer j;
encoder encoder_inst(
//================System Signal================
.clk (clk),
.rst_n (rst_n),
//================Interface====================
.a (a),
.b (b),
.cnt (cnt)
);
//=====================<时钟信号>=============================
initial begin
clk = 1;
forever
#(`clock_period/2) clk = ~clk;
end
//=====================<复位信号>=============================
initial begin
rst_n = 0;#(`clock_period*20+1);
rst_n = 1;
end
//=====================<激励信号>=============================
initial begin
a = 0;
#(`clock_period*20+1);//初始化
for(i=0;i<20;i=i+1)begin
a=0;
#1000;
a=1;
#2000;
a=0;
#1000;
end
a=0;
#5000;
for(i=0;i<20;i=i+1)begin
a=0;
#2000;
a=1;
#2000;
end
end
initial begin
b = 0;
#(`clock_period*20+1);
for(j=0;j<20;j=j+1)begin
b=0;
#2000;
b=1;
#2000;
end
b=0;
#5000;
for(j=0;j<20;j=j+1)begin
b=0;
#1000;
b=1;
#2000;
b=0;
#1000;
end
end
endmodule
仿真波形
正转逻辑
反转逻辑