作者:普地编码器 PDEncoder 技术团队

在智能车、机器人小车、电机测速等项目中,编码器是非常常见的速度反馈器件。很多同学在使用 STC32G12K128 配合 逐飞开源库 调试编码器时,可能会遇到一个现象:

编码器接线正常,电源正常,电机也在转,但是程序里面编码器计数始终没有变化,或者读数一直为 0。

这个问题看起来像是编码器坏了,也像是定时器配置错误,但实际原因可能非常简单:
初始化时 IO 输出状态被设置为了低电平,导致编码器输入信号被 MCU 端拉低,最终无法正常读取脉冲。


一、问题现象

在调试过程中,常见表现如下:

  1. 编码器 Pluse/Dir 相已经接到单片机对应引脚;

  2. 编码器供电电压正常,例如 5V 或 3.3V;

  3. 电机转动时,用手感觉编码器机械部分正常;

  4. 程序调用编码器读取函数,但计数值一直不变;

  5. 示波器或逻辑分析仪测量时,发现编码器输出信号电平异常偏低;

  6. 将编码器从单片机 IO 上断开后,编码器自身输出又恢复正常。

这类现象很容易误判为:

  • 编码器损坏;

  • 定时器编码器模式配置错误;

  • 中断没有打开;

  • 逐飞库函数调用错误;

  • 编码器供电不足。

但如果编码器断开 MCU 后信号正常,接上 MCU 后信号被拉低,就要重点检查 IO 初始化方向和输出状态


二、核心原因

问题的核心是:

在初始化编码器引脚时,IO 被配置成了某种会主动输出低电平的状态,导致编码器输出信号被单片机端强行拉低。

对于 MCU 来说,这两个引脚应该作为 输入引脚 使用,而不是作为普通推挽输出使用。

如果初始化时把 IO 设置成输出低电平,或者在切换为输入功能前先输出了低电平,就可能出现以下情况:

编码器输出高电平  →  MCU IO 端被配置为低电平输出
                  →  两边形成冲突
                  →  信号被拉低
                  →  MCU 无法识别有效脉冲

最终结果就是:
编码器本来有脉冲,但 MCU 看到的始终是低电平或异常波形。


三、为什么这个问题容易被忽略?

因为很多同学在使用开源库时,通常会直接调用初始化函数,不会特别关注底层 GPIO 的初始化参数。

例如在一些初始化封装中,可能会看到类似这样的参数:

gpio_init(pin, mode, output_value, pull_mode);

或者类似的 IO 初始化函数:

gpio_mode(pin, mode, value);

其中某个参数可能代表:

  • 初始输出电平;

  • 上拉/下拉状态;

  • 输入输出模式;

  • 复用功能;

  • 高阻输入或准双向口。

如果这个参数被设置成 低电平输出,就可能影响编码器输入。

尤其是在 STC 系列单片机中,IO 模式本身有多种配置方式,例如:

  • 准双向口;

  • 推挽输出;

  • 高阻输入;

  • 开漏输出。

如果编码器信号引脚没有正确设置为输入状态,或者被初始化成低电平输出,就可能导致信号无法被正常读取。


四、解决方法:修改初始化参数

解决方法很简单:

把编码器相关 IO 初始化参数从“输出低电平”改为“输入状态”或“不主动拉低”的状态。

具体修改位置要根据你使用的逐飞库版本和工程结构来确定,一般可以重点检查以下几个地方:

encoder_init();

或者:

gpio_init();

以及编码器初始化中对应 A/B 相引脚的 GPIO 配置。

错误思路一般类似:

// 示例:错误配置,可能会导致 IO 主动拉低
gpio_init(ENCODER_A_PIN, GPO, 0, GPIO_PIN_CONFIG);
gpio_init(ENCODER_B_PIN, GPO, 0, GPIO_PIN_CONFIG);

正确思路应该是:

// 示例:正确配置,应配置为输入或复用输入
gpio_init(ENCODER_A_PIN, GPI, 1, GPIO_PIN_CONFIG);
gpio_init(ENCODER_B_PIN, GPI, 1, GPIO_PIN_CONFIG);

按以上方法修改\Libraries\zf_driver\zf_driver_encoder.c 文件就可以解决编码器读不到的问题。


五、推荐排查步骤

遇到编码器不能读数时,建议按下面顺序排查。

1. 先确认硬件连接

检查:

  • 编码器 VCC 是否接对;

  • GND 是否与主控板共地;

  • A 相、B 相是否接到正确引脚;

  • 编码器输出电压是否与 MCU 输入电平兼容;

  • 是否需要上拉电阻。

很多编码器是开漏输出或 NPN 输出,如果没有上拉,信号也可能无法正常变成高电平。


2. 用万用表或示波器看 A/B 相电平

如果条件允许,最好使用示波器或逻辑分析仪。

观察两种状态:

编码器未接 MCU 时:

A/B 相是否有正常高低电平变化?

编码器接上 MCU 后:

A/B 相是否被拉低?
波形幅度是否明显变小?
高电平是否上不去?

如果断开 MCU 正常,接上 MCU 异常,大概率就是 MCU 端 IO 配置或硬件输入阻抗问题。


3. 检查 IO 初始化模式

重点检查编码器引脚是否被配置为:

  • 普通输出;

  • 推挽输出;

  • 初始输出低;

  • 下拉输入;

  • 其他外设功能冲突。

对于编码器输入,通常应优先选择:

  • 输入模式;

  • 上拉输入;

  • 高阻输入加外部上拉;

  • 定时器编码器复用输入模式。


4. 检查引脚是否被其他模块占用

有时同一个引脚可能同时被配置给:

  • UART;

  • PWM;

  • ADC;

  • 普通 GPIO;

  • 定时器输入;

  • 编码器输入。

如果初始化顺序不对,后面的模块可能把前面配置好的编码器引脚重新改掉。

建议在工程中全局搜索编码器相关引脚,例如:

Pxx
ENCODER_A
ENCODER_B
TIMx_CHx

确认这些引脚只被编码器功能使用。


六、普地编码器应用提示

普地编码器在智能车、机器人小车、自动化设备中,常见输出方式包括:

  • 正交增量输出;

  • 带方向输出;

  • SPI输出;

  • 模拟电压输出;

  • RS485 通讯输出;

在智能车项目中,如果使用 MCU 直接读取 A/B 相信号,建议优先确认以下几点:

项目 建议
输出方式 优先选择与 MCU 输入电平兼容的 AB 相输出
供电电压 确认 3.3V / 5V 是否匹配
上拉方式 开漏/NPN 输出需要合适上拉
IO配置 编码器引脚必须为输入或外设输入
抗干扰 编码器线远离电机线,必要时加滤波

编码器本身只是提供脉冲信号,真正能不能稳定读数,还取决于主控 IO 配置、电源、接线和软件初始化是否正确。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐