![]()
module Encoder
(
input clk,
input rst_n,
input key_a, // 旋转编码器EC11的A脚
input key_b, // 旋转编码器EC11的B脚
output reg L_pulse, // 左旋脉冲输出
output reg R_pulse // 右旋脉冲输出
);
localparam NUM_250US = 3_000;
reg [12:0] cnt;
//count for clk_500us
always@(posedge clk or negedge rst_n) begin
if(!rst_n) cnt <= 0;
else if(cnt >= NUM_250US-1) cnt <= 1'b0;
else cnt <= cnt + 1'b1;
end
reg clk_500us;
always@(posedge clk or negedge rst_n) begin
if(!rst_n) clk_500us <= 0;
else if(cnt == NUM_250US-1) clk_500us <= ~clk_500us;
else clk_500us <= clk_500us;
end
reg key_a_r,key_a_r1,key_a_r2;
//消除亚稳态
always@(posedge clk_500us) begin
key_a_r <= key_a;
key_a_r1 <= key_a_r;
key_a_r2 <= key_a_r1;
end
reg A_state;
//简单去抖动处理
always@(key_a_r1 or key_a_r2) begin
case({key_a_r1,key_a_r2})
2'b11: A_state <= 1'b1;
2'b00: A_state <= 1'b0;
default: A_state <= A_state;
endcase
end
reg key_b_r,key_b_r1,key_b_r2;
//消除亚稳态
always@(posedge clk_500us) begin
key_b_r <= key_b;
key_b_r1 <= key_b_r;
key_b_r2 <= key_b_r1;
end
reg B_state;
//简单去抖动处理
always@(key_b_r1 or key_b_r2) begin
case({key_b_r1,key_b_r2})
2'b11: B_state <= 1'b1;
2'b00: B_state <= 1'b0;
default: B_state <= B_state;
endcase
end
reg A_state_r,A_state_r1;
//对A_state信号进行边沿检测
always@(posedge clk) begin
A_state_r <= A_state;
A_state_r1 <= A_state_r;
end
wire A_pos = (!A_state_r1) && A_state_r;//上升沿
wire A_neg = A_state_r1 && (!A_state_r);//下降沿
//当A的上升沿伴随B的高电平或当A的下降沿伴随B的低电平 为向左旋转
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) L_pulse <= 1'b0;
else if((A_pos&&B_state)||(A_neg&&(!B_state)))
L_pulse <= 1'b1;
else
L_pulse <= 1'b0;
end
//当A的上升沿伴随B的低电平或当A的下降沿伴随B的高电平 为向右旋转
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) R_pulse <= 1'b0;
else if((A_pos&&(!B_state))||(A_neg&&B_state))
R_pulse <= 1'b1;
else
R_pulse <= 1'b0;
end
endmodule