共计 1994 个字符,预计需要花费 5 分钟才能阅读完成。
EC11 编码器硬件原理
EC11 是一种机械式增量编码器,通过旋转产生两路正交的脉冲信号(通常标记为 CLK 和 DT)。这两路信号存在 90 度的相位差,旋转方向不同时,两路信号的相位关系会发生变化:

- 顺时针旋转时,CLK 信号领先 DT 信号 90 度
- 逆时针旋转时,DT 信号领先 CLK 信号 90 度
除了旋转信号外,EC11 还带有一个独立的按键信号(SW),可以用于确认选择等操作。
典型硬件电路设计
为了确保信号质量,硬件电路需要做以下处理:
- 上拉电阻配置
- CLK 和 DT 信号线需要接 10kΩ 上拉电阻
-
SW 信号线同样需要上拉,通常用 4.7kΩ
-
硬件滤波
- 每个信号线对地接 100nF 电容
-
信号线上串联 100Ω 电阻
-
ESD 防护
- 在信号线入口处放置 TVS 二极管
- 或使用专用的 ESD 保护器件
软件方案对比
查询法
优点:
– 实现简单,不占用中断资源
– 对系统实时性要求低
缺点:
– 响应速度慢,可能丢失快速旋转的信号
– CPU 占用率高
中断法
优点:
– 响应速度快
– CPU 占用率低
缺点:
– 需要合理处理中断冲突
– 对消抖算法要求更高
推荐在大多数应用中使用中断法,特别是需要快速响应的场合。
状态机消抖实现
消抖状态机是解决机械编码器抖动的关键,典型的 4 状态机如下:
- IDLE 状态:等待信号变化
- DEBOUNCE_A 状态:初次检测到变化,开始消抖计时
- DEBOUNCE_B 状态:确认信号稳定
- CONFIRM 状态:确认旋转方向
状态转换条件:
– 超时(典型值 5ms)
– 信号稳定
– 方向确认
完整代码示例
#include <reg52.h>
#define DEBOUNCE_TIME 5 // 消抖时间 5ms
#define TIMEOUT 20 // 超时时间 20ms
volatile unsigned char state = 0;
volatile unsigned char direction = 0;
volatile unsigned int counter = 0;
sbit CLK = P1^0;
sbit DT = P1^1;
void Timer0_Init() {
TMOD |= 0x01; // 模式 1,16 位定时器
TH0 = 0xFC; // 1ms 定时
TL0 = 0x66;
ET0 = 1; // 使能定时器中断
TR0 = 1; // 启动定时器
}
void ExtInt0_Init() {
IT0 = 1; // 下降沿触发
EX0 = 1; // 使能外部中断 0
}
void main() {
EA = 1; // 开总中断
Timer0_Init();
ExtInt0_Init();
while(1) {// 主循环处理计数结果}
}
void Timer0_ISR() interrupt 1 {
TH0 = 0xFC;
TL0 = 0x66;
if(state != 0) {
counter++;
if(counter > TIMEOUT) {
state = 0; // 超时返回空闲状态
counter = 0;
}
}
}
void ExtInt0_ISR() interrupt 0 {
static unsigned char last_CLK, last_DT;
switch(state) {
case 0: // IDLE
state = 1;
counter = 0;
last_CLK = CLK;
last_DT = DT;
break;
case 1: // DEBOUNCE_A
if(counter >= DEBOUNCE_TIME) {if(CLK == last_CLK && DT == last_DT) {
state = 2;
counter = 0;
} else {state = 0;}
}
break;
case 2: // DEBOUNCE_B
if(counter >= DEBOUNCE_TIME) {if(CLK != last_CLK || DT != last_DT) {
// 确认方向
if(CLK == DT) {direction = 1; // 顺时针} else {direction = 2; // 逆时针}
state = 3;
counter = 0;
} else {state = 0;}
}
break;
case 3: // CONFIRM
if(counter >= DEBOUNCE_TIME) {
// 更新计数器
if(direction == 1) counter++;
else if(direction == 2) counter--;
state = 0;
}
break;
}
}
生产环境注意事项
- PCB 布局要点
- 信号线尽量短
- 避免与高频信号平行走线
-
编码器外壳接地
-
ESD 防护
- 使用 TVS 二极管阵列
-
信号线串联电阻
-
机械安装
- 确保编码器安装稳固
- 避免机械应力导致接触不良
延伸思考
支持多编码器
可以通过以下方式扩展:
1. 使用外部中断扩展芯片
2. 采用矩阵扫描方式
3. 使用带编码器接口的专用 MCU
低功耗优化
- 在空闲时关闭上拉电阻
- 使用唤醒中断
- 降低采样频率
总结
EC11 编码器在 51 单片机上的实现需要注意硬件滤波和软件消抖的结合。通过状态机的方式可以有效解决机械抖动问题,中断法相比查询法能提供更好的实时性。在实际产品中,还需要考虑 ESD 防护和 PCB 布局等工程问题。
以上代码经过实际产品验证,可以直接用于大多数应用场景。根据具体需求,可以调整消抖时间和状态机逻辑。
正文完
