共计 1133 个字符,预计需要花费 3 分钟才能阅读完成。
技术背景:EC11 编码器工作原理
EC11 是一种机械式旋转编码器,通过内部机械结构产生两路相位差 90 度的正交信号(A 相和 B 相)。当旋钮旋转时,这两路信号会产生特定的时序变化:

- 顺时针旋转时,A 相先于 B 相变化
- 逆时针旋转时,B 相先于 A 相变化
这种设计使得我们可以通过检测两路信号的相位差来判断旋转方向。EC11 广泛应用于音量控制、菜单选择等需要旋转输入的场合。
硬件设计:电路连接
典型 EC11 与 51 单片机连接电路如下:
EC11 51 单片机
A 相 ------> P3.2(INT0)
B 相 ------> P3.3(INT1)
公共端 ----> GND
注意事项:
- 必须接上拉电阻(通常 4.7KΩ-10KΩ)
- 公共端必须可靠接地
- 信号线尽量短以减少干扰
软件实现
GPIO 中断配置
建议使用下降沿触发中断,因为 EC11 的信号在旋转时会产生清晰的下降沿。配置方法:
IT0 = 1; // INT0 下降沿触发
IT1 = 1; // INT1 下降沿触发
EX0 = 1; // 允许 INT0 中断
EX1 = 1; // 允许 INT1 中断
EA = 1; // 开启总中断
状态机去抖算法
机械编码器最大的问题是信号抖动。我们使用状态机来处理:
- 空闲状态:等待第一个下降沿
- 确认状态:等待第二个下降沿(确认有效旋转)
- 判断状态:根据两个信号的先后顺序判断方向
状态转换图:
空闲 -> (检测到下降沿) -> 确认 -> (再次检测) -> 判断
方向判断逻辑
关键代码片段:
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; // 清除标志
}
}
}
避坑指南
- 机械抖动时长:实测约 2 -10ms
- 中断嵌套风险:避免在中断中处理复杂逻辑
- 低功耗模式:需唤醒后重新初始化编码器
进阶优化
硬件消抖:在信号线上并联 104 电容
软件滤波:增加数字滤波算法
实践问题
- 如何修改代码实现加速旋转检测?
- 如果去掉上拉电阻会有什么现象?
- 如何扩展实现按键功能(EC11 通常带按键)?
通过以上内容,希望能帮助初学者快速掌握 EC11 编码器的使用。在实际项目中,建议先搭建简单测试电路验证基本功能,再逐步添加防抖等高级功能。
正文完
