旋转编码器

 

 

 

 

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

  

 

posted @ 2022-09-17 10:38  xiaoberber  阅读(159)  评论(0编辑  收藏  举报