51单片机EC11编码器入门指南:从硬件连接到软件解码

1次阅读
没有评论

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

image.webp

EC11 编码器工作原理

EC11 是一种机械式旋转编码器,通过内部机械结构产生两路相位差 90 度的正交脉冲信号(A 相和 B 相),旋转方向不同时两路信号的相位关系会相反。同时 EC11 还集成了按压开关功能(SW 引脚),可实现旋转 + 按压的复合操作。

51 单片机 EC11 编码器入门指南:从硬件连接到软件解码

硬件连接设计

推荐电路图

典型连接方式如下:

  • A 相 / B 相引脚:各接 10kΩ 上拉电阻到 VCC,并联 0.1μF 滤波电容到 GND
  • SW 引脚:接 10kΩ 上拉电阻,按键按下时接地
  • 所有信号线通过 100Ω 电阻连接到单片机 IO 口

PCB 布局要点

  1. 编码器尽量靠近单片机放置
  2. 信号走线避免与高频线路平行
  3. 地线回路要完整,建议使用铺铜
  4. 机械固定要稳固,防止振动导致接触不良

软件解码实现

状态机方向判断

// 编码器状态定义
#define ENCODER_STATE_00 0
#define ENCODER_STATE_01 1
#define ENCODER_STATE_10 2
#define ENCODER_STATE_11 3

volatile uint8_t encoderState = ENCODER_STATE_00;
volatile int16_t encoderCount = 0;

void EXTI_Encoder_Handler(void) {uint8_t currA = GPIO_ReadPin(ENCODER_A_PIN);
    uint8_t currB = GPIO_ReadPin(ENCODER_B_PIN);

    // 状态机实现
    switch(encoderState) {
        case ENCODER_STATE_00:
            if(currA && !currB) encoderState = ENCODER_STATE_10;
            else if(!currA && currB) encoderState = ENCODER_STATE_01;
            break;
        case ENCODER_STATE_01:
            if(currA && currB) {encoderState = ENCODER_STATE_11; encoderCount++;}
            else if(!currA && !currB) encoderState = ENCODER_STATE_00;
            break;
        case ENCODER_STATE_10:
            if(currA && currB) {encoderState = ENCODER_STATE_11; encoderCount--;}
            else if(!currA && !currB) encoderState = ENCODER_STATE_00;
            break;
        case ENCODER_STATE_11:
            if(!currA && currB) encoderState = ENCODER_STATE_01;
            else if(currA && !currB) encoderState = ENCODER_STATE_10;
            break;
    }
}

按键消抖处理

推荐使用硬件滤波 + 软件确认的方式:

  1. 硬件:RC 滤波(典型值 R =10kΩ,C=0.1μF)
  2. 软件:连续检测到 5 次相同状态才确认按键动作

常见问题排查

  1. 信号抖动 :检查滤波电容是否焊接良好
  2. 方向误判 :确认 AB 相接线顺序是否正确
  3. 按键不响应 :测量 SW 引脚电压变化是否正常

进阶应用

多编码器支持

  1. 每个编码器使用独立的状态变量
  2. 通过 IO 扩展芯片增加接口数量
  3. 采用矩阵扫描方式减少 IO 占用

低功耗优化

  1. 只在编码器动作时唤醒 MCU
  2. 使用外部中断触发唤醒
  3. 降低采样频率节省功耗

应用示例:菜单导航

void UpdateMenu(int16_t delta) {currentItem = (currentItem + delta) % MENU_ITEMS_COUNT;
    if(currentItem < 0) currentItem += MENU_ITEMS_COUNT;
    LCD_DisplayMenu(currentItem);
}

void HandleEncoder() {
    static int16_t lastCount = 0;
    if(encoderCount != lastCount) {UpdateMenu(encoderCount - lastCount);
        lastCount = encoderCount;
    }

    if(ReadKeyPress()) {ExecuteMenuItem(currentItem);
    }
}

通过以上实现,可以构建一个完整的旋转编码器交互系统。在实际项目中,建议先验证硬件连接可靠性,再逐步完善软件功能。EC11 虽然结构简单,但正确处理各种边界条件才能获得良好的用户体验。

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