OnStep步进电机驱动原理全解读:Timer.ino硬件定时器与脉冲波形生成
【免费下载链接】OnStepArduino telescope goto for equatorial and alt/az mounts项目地址: https://gitcode.com/gh_mirrors/on/OnStep
OnStep 是一款基于 Arduino 的开源望远镜 GoTo 控制系统,支持赤道仪(Equatorial)和经纬仪(Alt/Az)两种机架。它的"灵魂"之一是精确地驱动步进电机:每一步脉冲的时机、频率、方向都必须分毫不差。而这一切,都藏在 Timer.ino 这个不到 500 行的文件里。本文将带你读懂 OnStep 如何用硬件定时器生成步进脉冲波形,让你彻底明白"电机为什么能这么精准地动"。🔭
一、为什么必须用硬件定时器?
让望远镜跟踪恒星,本质上是控制步进电机以恒定的频率输出脉冲。如果用delay()或软件循环发脉冲,抖动(jitter)会让跟踪速率漂移,长曝光拍摄时星点必然拖线。
OnStep 的解决方案是:用微控制器的硬件定时器(Hardware Timer)产生中断,在中断服务程序(ISR)里切换步进引脚电平。定时器由硬件计数,与 CPU 主循环完全解耦,即使主程序在忙着处理串口命令、校准算法,脉冲的节奏也不会乱。
三个定时器各司其职,分工极其清晰:
| 定时器 | 职责 | 代码位置 |
|---|---|---|
| Timer1 | 恒星时主时钟,驱动跟踪/导星的"总节拍" | Timer.ino第 82 行TIMER1_COMPA_vect中断 |
| Timer3 | Axis1(赤经 RA / 方位 Azm)电机脉冲输出 | Timer.ino第 243 行TIMER3_COMPA_vect中断 |
| Timer4 | Axis2(赤纬 Dec / 高度 Alt)电机脉冲输出 | Timer.ino第 336 行TIMER4_COMPA_vect中断 |
二、Timer1:恒星时主时钟与速率"总调度"
Timer1 是整台系统的"心脏起搏器"。以 Mega2560 为例,它约每 33 毫秒中断一次(恒星时速率的 3 倍频),每次中断把系统恒星时计数lst加 1 分(centisecond),并顺带处理蜂鸣器计时等杂务。
真正精彩的是 Timer.ino 中的timerSupervisor()函数(第 120 行起),它在非 GoTo 状态下完成三件大事:
- 导星加减速控制:根据导星指令(
guideDirAxis1/2)按加速度曲线调整导星速率,避免电机急停急启; - 合成目标速率:把导星速率、PEC 速率、恒星时跟踪速率相加(
guideTimerRate + pecTimerRate + trackingTimerRate),得出每个轴最终需要的脉冲频率,并据此确定方向(timerDirAxis1/2); - 换算成定时器刻度(ticks):通过
PresetTimerInterval()把"每秒多少步"换算成 Timer3/Timer4 的倒计时值,只有速率真正变化时才写入硬件(runTimerRateAxis1与isrTimerRateAxis1对比),避免频繁重编程带来的毛刺。
此外,OnStep 支持PPS(Pulse Per Second)信号校准。如果你接了 1PPS 天线信号,clockSync()(第 478 行)会对 40 个秒脉冲做滑动平均,把晶振误差修正进ppsRateRatio,再由SiderealClockSetInterval()(第 60 行)立即生效——这对使用陶瓷谐振器的 Mega2560 尤为重要。
三、脉冲波形生成:SQUARE / PULSE / DEDGE 三选一
在 Config.h 中有一个关键配置:
#define STEP_WAVE_FORM SQUARE // SQUARE, PULSE Step signal wave form波形类型定义在 src/sd_drivers/Models.h(第 52~54 行):SQUARE = 2、PULSE = 3、DEDGE = 4。三种波形在电机 ISR 里的实现方式完全不同:
1️⃣ SQUARE(方波,默认推荐)
电机定时器以2 倍脉冲频率运行,每次中断在"置位"和"清零"之间切换,自然合成 50% 占空比的方波。看 Timer3 中断中的核心逻辑(Timer.ino第 307~313 行):
takeStepAxis1 = true; // 前半周期:STEP 线拉高 ... if (takeStepAxis1) a1STEP; // 后半周期:保持高电平 clearAxis1 = true;好处:信号完整性最好(Config.h第 107 行注释原话),且高电平持续时间长,能从容地执行方向切换、回差补偿等附加逻辑。
2️⃣ PULSE(窄脉冲)
定时器以 1 倍速率运行,每次中断只发一个窄高脉冲(a1STEP后紧接a1CLEAR)。脉冲宽度由驱动器型号决定,例如Models.h中 A4988 要求 1000ns、TMC2209 仅需 103ns。
3️⃣ DEDGE(双沿模式,高速利器)
同样 1 倍速率运行,但利用toggleStateAxis1计数器让 STEP 引脚在每个时钟沿都翻转(Timer.ino第 322~323 行)。驱动器只要识别上升沿即可计数,这让极限频率下的信号边沿更干净。
💡 提示:引脚操作全部用宏直写寄存器端口完成,如 src/HAL/Mega2560/Mega2560.h 中的
a1STEP_H(SET(Axis1_StepPORT, Axis1_StepBIT)),比digitalWrite()快得多,保证中断内的翻转延迟最小。
四、速率如何变成硬件刻度?以 Mega2560 为例
Mega2560 的电机定时器(Timer3/4)运行在 2 MHz(16MHz 分频 /8),每个 tick =0.5 微秒,见 src/HAL/Mega2560/Mega2560.h 第 149 行TIMER_RATE_MHZ 2L。
PresetTimerInterval()(同文件第 153 行)的换算逻辑:
- 输入"16MHz 等效刻度"(微秒 ×16),范围钳制在 1µs ~ 约 134 秒;
- SQUARE 模式下除以 2(因为 2 倍速率);
- 再除以 8 换算成 2MHz tick 数;
- 若超过 16 位寄存器上限 65536,则拆成
nextRep(重复次数)+nextRate(单次倒计时),由 ISR 内的count静态变量做模运算跳过多余中断(Timer.ino第 249~253 行)。
而在中断内部调速则用QuickSetIntervalAxis1()——Mega2560 上它就是直接写OCR3A寄存器(第 170 行),实现"下一拍立即生效"的无延迟变速,这正是导星加速/减速能平滑运行的原因。
五、电机 ISR 里的完整一步:方向、回差、微步切换
Timer3 的中断远比"拉高一个引脚"复杂。每次有效中断会:
- 方向判定:比较当前位置
posAxis1与目标targetAxis1,用a1DIR_H/a1DIR_L设置方向引脚; - 回差补偿:向东(跟随天空方向)移动时先消耗
blAxis1回差计数,不计入真实位置; - TMC 微步切换:若配置了 TMC SPI 驱动器,GoTo 高速时用
axis1DriverGotoFast()切大微步,低速跟踪时切回axis1DriverTrackingFast(),兼顾速度、精度与电流; - 位置记账:
posAxis1 += stepAxis1,让上层算法与硬件严格同步。
减速停止时(MoveTo.ino第 317 行附近),SQUARE 波形的占空比会临时偏置,确保最后一个脉冲完整落地——细节都藏在条件编译里,用户无需关心。
六、新手实用建议 🛠️
- 保持默认
SQUARE波形:除非追求极限频率,SQUARE 的信号完整性最佳,Config.h注释也明确推荐; - Mega2560 用户强烈建议启用
PPS_SENSE ON:用 1PPS 信号驯服廉价晶振,跟踪精度立竿见影; - 修改配置只需重编译:所有波形、驱动器参数都在 Config.h 中,通过条件编译宏生效,
Validate.h(第 931 行)会在编译期拦截非法取值; - 想深挖硬件差异:各平台的定时器实现都在 src/HAL/ 下,如
src/HAL/ESP32/ESP32.h、src/HAL/STM32/Common.h,结构一致,可读性强。
七、核心文件路径速查
| 文件 | 作用 |
|---|---|
| Timer.ino | 三个硬件定时器、恒星时、速率合成、电机 ISR 全在此 |
| Config.h | STEP_WAVE_FORM、驱动器等用户配置总入口 |
| src/sd_drivers/Models.h | 波形常量、各驱动器最小脉冲宽度表 |
| src/HAL/Mega2560/Mega2560.h | 定时器初始化、PresetTimerInterval、快速引脚宏 |
| src/HAL/ESP32/ESP32.h | ESP32 平台的对应实现 |
一句话总结:OnStep 用 Timer1 当节拍器算速率,用 Timer3/Timer4 当脉冲发生器出波形,PresetTimerInterval负责"速度→刻度"的翻译,QuickSetInterval负责"下一拍生效"的调速——三层协作,构成了这台开源望远镜毫秒级精确运动的底层秘密。⚙️
【免费下载链接】OnStepArduino telescope goto for equatorial and alt/az mounts项目地址: https://gitcode.com/gh_mirrors/on/OnStep
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考