触摸屏触发后步进电机转速为何偏慢?
结论
从代码看,add_repeating_timer_us(1000, ...) 每 1 ms 触发一次定时器,但回调只会把 motor_state 设为 1。GPIO 步进操作实际在主循环中执行,每轮循环最多走一步。因此,1 ms 只是定时器的通知间隔,电机不一定每毫秒前进一步。主循环处理触摸和 LCD 所花的时间,可能会限制实际步进速度。
为什么电机会慢
主循环每次先调用 readPoint(),之后才检查 motor_state 并更新线圈。如果 readPoint() 或触摸屏通信耗时较长,主循环就无法及时处理定时器事件。多个定时器周期到来时,motor_state 仍然只是 1,无法记录有多少步待执行。主循环恢复后也只走一步,期间的节拍就合并了。
触摸响应同样受轮询影响。程序要等 readPoint() 返回并完成按钮处理,才会设置 motor_on。触摸后和图像定时器触发时,程序都会调用 drawImagem(),LCD 绘制也会占用主循环时间。
改进步进调度
可以把每一步的 GPIO 更新放进独立的定时调度中,让主循环负责读取触摸和更新显示。定时器回调只执行短小、确定的 GPIO 操作,不要在回调里调用 LCD 绘图或触摸读取函数。也可以使用能输出步进脉冲的专用驱动器,通过定时器、PIO 等机制产生脉冲。具体接法取决于电机和驱动器型号。
当前回调只设置标志,代码如下:
bool timer_motor_callback(struct repeating_timer *t) {
motor_state = 1;
return true;
}
如果继续用标志交接,至少应改用计数器记录待执行步数,并让主循环尽快处理。不过,主循环的延迟仍会影响步进节奏。若要避免 readPoint() 和绘图造成的阻塞影响步进,应在合适的定时器回调或硬件外设中推进步进序列。中断回调中不要执行耗时操作,也要确认所用 SDK API 和驱动方式适用于回调上下文。
检查步进序列和硬件
代码每步先将四个 GPIO 拉低,再只将一个线圈对应的引脚拉高。这属于单相励磁式序列。它是否适合当前电机和驱动电路,取决于线圈接法、电机类型和驱动器。如果电机由 STEP/DIR 驱动器控制,应按驱动器接口生成脉冲,而不是直接轮流驱动线圈引脚。
步进频率也有上限。电源、驱动器、电机负载、加速过程和步进方式都会影响实际速度。频率过高可能导致失步或电机无法启动。建议先测量主循环耗时和实际步进频率,再逐步缩短步进间隔,并观察电机是否运行稳定。
触摸与显示处理
检查 readPoint() 是否会阻塞,以及触摸驱动能否采用更高效的非阻塞读取方式。触摸检测和电机步进应分别调度;显示动画可以降低刷新频率,减少绘图对控制时间的占用。还要留意 f_btn、motor_on、direcao 等变量:如果主循环和回调都会访问它们,需要做好并发保护,避免读写竞争。
问题中没有提供电机型号、驱动器信息或 readPoint() 的实现,因此无法仅凭这段代码确定最高安全速度或最终硬件接法。可以先确认两点:主循环是否被触摸读取拖慢,以及当前单相励磁代码是否符合电机所需的驱动序列。
备注:内容仅供参考。
