51单片机EC11编码器编程实战:从基础原理到防抖优化

1次阅读
没有评论

共计 1133 个字符,预计需要花费 3 分钟才能阅读完成。

image.webp

技术背景:EC11 编码器工作原理

EC11 是一种机械式旋转编码器,通过内部机械结构产生两路相位差 90 度的正交信号(A 相和 B 相)。当旋钮旋转时,这两路信号会产生特定的时序变化:

51 单片机 EC11 编码器编程实战:从基础原理到防抖优化

  • 顺时针旋转时,A 相先于 B 相变化
  • 逆时针旋转时,B 相先于 A 相变化

这种设计使得我们可以通过检测两路信号的相位差来判断旋转方向。EC11 广泛应用于音量控制、菜单选择等需要旋转输入的场合。

硬件设计:电路连接

典型 EC11 与 51 单片机连接电路如下:

EC11         51 单片机
A 相 ------> P3.2(INT0)
B 相 ------> P3.3(INT1)
公共端 ----> GND

注意事项:

  1. 必须接上拉电阻(通常 4.7KΩ-10KΩ)
  2. 公共端必须可靠接地
  3. 信号线尽量短以减少干扰

软件实现

GPIO 中断配置

建议使用下降沿触发中断,因为 EC11 的信号在旋转时会产生清晰的下降沿。配置方法:

IT0 = 1;  // INT0 下降沿触发
IT1 = 1;  // INT1 下降沿触发
EX0 = 1;  // 允许 INT0 中断
EX1 = 1;  // 允许 INT1 中断
EA = 1;   // 开启总中断 

状态机去抖算法

机械编码器最大的问题是信号抖动。我们使用状态机来处理:

  1. 空闲状态:等待第一个下降沿
  2. 确认状态:等待第二个下降沿(确认有效旋转)
  3. 判断状态:根据两个信号的先后顺序判断方向

状态转换图:

 空闲 -> (检测到下降沿) -> 确认 -> (再次检测) -> 判断 

方向判断逻辑

关键代码片段:

if(A 相先变化){// 顺时针}else if(B 相先变化){// 逆时针}

完整代码示例

#include <reg51.h>

volatile unsigned char direction = 0; // 旋转方向
volatile unsigned long lastTime = 0;  // 上次中断时间

void INT0_ISR() interrupt 0 {if((TF0 - lastTime) > 5){ // 5ms 防抖
        if(P3_3) direction = 1; // 顺时针
        else direction = 2;     // 逆时针
        lastTime = TF0;
    }
}

void main() {
    // 初始化代码...
    while(1){
        // 主循环处理旋转事件
        if(direction){
            // 根据 direction 值执行相应操作
            direction = 0; // 清除标志
        }
    }
}

避坑指南

  1. 机械抖动时长:实测约 2 -10ms
  2. 中断嵌套风险:避免在中断中处理复杂逻辑
  3. 低功耗模式:需唤醒后重新初始化编码器

进阶优化

硬件消抖:在信号线上并联 104 电容
软件滤波:增加数字滤波算法

实践问题

  1. 如何修改代码实现加速旋转检测?
  2. 如果去掉上拉电阻会有什么现象?
  3. 如何扩展实现按键功能(EC11 通常带按键)?

通过以上内容,希望能帮助初学者快速掌握 EC11 编码器的使用。在实际项目中,建议先搭建简单测试电路验证基本功能,再逐步添加防抖等高级功能。

正文完
 0
评论(没有评论)