共计 1811 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点
最近在做一个基于 STM32 的智能小车项目,发现 C8T6 最小系统板虽然便宜好用,但 GPIO 和定时器资源确实有限。特别是需要接两个正交编码器时,原生的接口根本不够用。官方手册显示这块板子只有 37 个 GPIO,但实际可用且带定时器功能的引脚更少。经过实测发现以下问题:

- TIM2 和 TIM4 虽然支持编码器模式,但引脚与常用外设(如 SPI1、USART1)冲突
- 直接接编码器会出现信号抖动,导致计数不准
- 高速旋转时偶发计数丢失现象
硬件设计
原理图关键点解析
先来看看最小系统板的核心电路设计要点:
- VBAT 电路 :即使不用 RTC,这个 0.1uF 电容也必须接,否则可能引发奇怪的重启问题
- NRST 复位电路 :10K 上拉 +100nF 电容的组合,手焊时注意电容别装反
- 时钟电路 :8MHz 晶振两端的 22pF 负载电容,值偏差太大会导致通信异常
编码器扩展方案
为了解决信号质量问题,我设计了如下调理电路:
- 采用 SN74LVC2G14 双施密特触发器做波形整形
- 每路信号串联 100Ω 电阻并并联 100pF 电容形成低通滤波
- 在 Altium Designer 中布局时要注意:
- 信号线尽量短
- 地线包围敏感信号
- 避免 90 度直角走线
软件实现
CubeMX 配置
- 在 Pinout 界面分配 TIM2_CH1/TIM2_CH2 到 PA0/PA1
- 在 Configuration 选项卡设置 TIM2 为 Encoder Mode
- 参数配置建议:
- Prescaler 设为 0
- Counter Period 设为 65535(16 位最大值)
- Encoder Mode 选 TI1 and TI2
核心代码示例
// 初始化代码
TIM_HandleTypeDef htim2;
TIM_Encoder_InitTypeDef sConfig = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 0xFFFF;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 6; // 适当滤波
HAL_TIM_Encoder_Init(&htim2, &sConfig);
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
// 速度计算函数
int16_t GetEncoderSpeed() {
static uint16_t last_cnt = 0;
uint16_t curr_cnt = TIM2->CNT;
int16_t delta = (int16_t)(curr_cnt - last_cnt);
last_cnt = curr_cnt;
return delta;
}
避坑指南
信号抖动处理
- 硬件层面:
- 在编码器电源端加 10uF 钽电容
- 信号线使用双绞线
- 软件层面:
- 设置定时器输入捕获滤波器(IC1Filter=6)
- 在中断里做中值滤波
电源噪声抑制
测试发现 3.3V 电源纹波会影响编码器精度,建议:
- 在每路编码器电源入口处加 0.1uF MLCC
- 布局时电容尽量靠近 MCU 引脚
- 使用星型拓扑供电,避免共阻抗干扰
性能验证
使用 Saleae 逻辑分析仪捕获波形:
- 低速测试(60RPM):
- 计数误差率 <0.1%
- 波形上升沿干净
- 高速测试(3000RPM):
- 误差率升至 1.2%
- 出现少量毛刺
通过增加滤波器参数后,高速下的误差可以控制在 0.8% 以内。
扩展思考
如果项目需要接多个编码器,可以尝试以下优化方案:
- 使用 TIM2+TIM4 同时接两个编码器
- 配置 DMA 将 CNT 寄存器值定期搬运到内存
- 设置定时器溢出中断处理 32 位扩展计数
这个方案我在四驱车项目上实测过,4 个编码器同时工作时 CPU 占用率能从 15% 降到 3% 以下。
最后想说
折腾 STM32 编码器的这两周,最大的体会就是硬件设计决定性能上限,软件优化弥补硬件不足。特别是当发现 TIM 的计数器莫名其妙跳变时,别急着改代码,先用示波器看看信号质量。希望这篇笔记能帮到正在调编码器的你,有什么问题欢迎在评论区交流~
正文完
