差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
后一修订版 两侧同时换到之后的修订记录
旋转调节系统设计 [2018/10/22 13:41]
anran [实验原理]
旋转调节系统设计 [2018/10/22 13:56]
anran [实验原理]
行 35: 行 35:
 ===旋转编码器连接=== ===旋转编码器连接===
  
 +STEP BaseBoard V3.0底板上旋转编码器的电路图如下:
  
 +{{:​4-旋转编码器电路.png?​800|旋转编码器电路}}
 +
 +我们使用的旋转编码器为EC11系列的,支持按动开关,共有5个管脚,
 +  * 1、2管脚支持按动开关,就像我们之前用到的独立按键连接方式,
 +  * 3、4、5管脚支持旋转编码,4脚为公共端,3、5管脚分别为旋转编码器的A、B相输出,如上图所示,我们给4脚接地,3、5管脚则需要接上拉电阻,同时为了降低输出脉冲信号的抖动干扰,我们有增加了电容到地做硬件去抖。
  
 ===旋转编码器驱动设计=== ===旋转编码器驱动设计===
 +
 +{{:​4-编码器原理示意.jpg?​500|编码器原理示意}}
 +
 +上图是机械增量式旋转编码器的原理示意图,中间圆形齿轮连接到旋转编码器的公共端4管脚,STEP BaseBoard V3.0底板上我们将之接地处理,A、B两个触点连接到旋转编码器的A、B相输出端3、5管脚,当进行旋转操作时,A、B触点会先后接触和错开圆形齿轮,从而导致A、B相输出信号产生相位不同的脉冲信号:
 +  * 顺时针旋转时,A触点超前于B触点接触和错开圆形齿轮,A信号脉冲相位超前
 +  * 逆时针旋转时,B触点超前于A触点接触和错开圆形齿轮,B信号脉冲相位超前
 +
 +{{:​4-编码器顺时针旋转时序.jpg?​600|编码器顺时针旋转时序}}
 +
 +{{:​4-编码器逆时针旋转时序.jpg?​600|编码器逆时针旋转时序}}
 +
 +根据时序图可以看出旋转编码器顺时针或逆时针旋转时,A相信号超前或滞后B相信号,FPGA接收到旋转编码器的A、B信号时,可以根据A、B的状态组合判定编码器的旋转方向。 程序设计中我们可以对A、B信号检测,检测A信号的边沿及B信号的状态,
 +  * 当A信号上升沿时B信号为低电平,或当A信号下降沿时B信号为高电平,证明当前编码器为顺时针转动
 +  * 当A信号上升沿时B信号为高电平,或当A信号下降沿时B信号为低电平,证明当前编码器为逆时针转动
 +以上就是我们旋转编码器驱动设计的总体思路,下面我们就通过编程来实现它。
 +
 +前面电路连接部分我们使用了两个电容对A、B信号作去抖处理,可以起到一定的效果,为了驱动更加稳定,我们在程序中再简单处理一下,先对系统时钟分频得到2KHz的时钟,然后在2KHz时钟的节拍下对A、B信号采样,三级锁存消除亚稳态
 +
 +对A信号采样程序实现如下(对B信号一样):
 +<code verilog>
 +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 
 +</​code>​
 +
 +然后简单去抖处理程序实现如下(对B信号一样):
 +<code verilog>
 +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 
 +</​code>​
 +
 +检测A信号的边沿程序实现如下:
 +<code verilog>
 +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);​
 +</​code>​
 +
 +最后根据A信号边沿与B信号的状态组合判定旋转的信息,
 +
 +逆时针旋转脉冲输出程序实现如下:
 +
 +<code verilog>
 +//​当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 
 +</​code>​
 +
 +所以通过上面程序最终实现了左旋右旋的脉冲输出,脉冲的脉宽等于系统时钟的周期。
  
 ===系统总体实现=== ===系统总体实现===