共计 916 个字符,预计需要花费 3 分钟才能阅读完成。
正交编码器基础
编码器通过 A / B 两相方波信号的相位差判定方向。典型时序如下:

A 相: _|‾|_|‾|_|‾
B 相: _|‾|_|‾|_|‾ (正转时滞后 90°)
硬件连接规范
- 必接元件 :
- 10kΩ 上拉电阻(接近编码器侧)
-
0.1μF 陶瓷电容(信号对地)
-
屏蔽线接法:
- 双绞线传输信号
- 屏蔽层单点接地
代码实现对比
轮询法(基础版)
// O(n) 时间复杂度,适合低速场景
void loop() {
static uint8_t lastState = PIND & 0b00001100; // 假设接 D2,D3
uint8_t newState = PIND & 0b00001100;
if(newState != lastState) {
// 状态机判断逻辑
lastState = newState;
}
}
中断法(推荐方案)
// 使用 PCINT 中断,响应时间 <2μs
void setup() {PCICR |= (1<<PCIE2); // 启用 PCINT2 组
PCMSK2 |= (1<<PCINT18)|(1<<PCINT19); // D2,D3
}
ISR(PCINT2_vect) {
static uint8_t lastAB = 0;
uint8_t currAB = (PIND >> 2) & 0x03;
// 方向判断算法...
}
抗干扰实战方案
- 硬件滤波 :
- 典型值:R=1kΩ, C=10nF (截止频率 16kHz)
-
公式:fc=1/(2πRC)
-
软件去抖 :
// 状态机实现,检测稳定持续时间 enum {STATE_0, STATE_1, STATE_2}; if(steady_time > 50μs) count++; -
中断优化 :
- 使用 volatile 声明共享变量
- 避免浮点运算
- 最小化 ISR 代码量
关键问题排查
- 中断冲突 :
- 用 Saleae 逻辑分析仪捕获
-
检查中断标志位清除情况
-
计数器溢出 :
volatile int32_t totalCount = 0; // 在中断中处理 16 位溢出 if(change > 0x7FFF) totalCount -= 65536;
性能测试数据
| 转速 (RPM) | 误差率 (%) |
|---|---|
| 100 | 0.02 |
| 1000 | 0.15 |
| 5000 | 1.8 |
进阶思考
- 如何通过脉冲间隔实现零速检测?
- 多编码器系统如何优化中断响应时序?
- 怎样利用 Timer1 硬件计数提升性能?
(示波器波形图建议位置:硬件滤波章节后插入抖动对比图)
正文完
