无感六步方波驱动,听着是个大门槛,拆开看其实就是一件事:在合适的时刻把悬空相上的反电动势过零信号抓出来。这个信号抓准了,电机就能安静、高效地转起来;抓不准,轻则换相发抖、相电流畸变,重则直接失步堵转。我自己最早从带霍尔方案切到无感方案时,也在这上面卡了两三周,后来把硬件滤波、采样时序、软件判据和示波器实测这四件事串起来,才算真正跑顺。
这篇文章我按实际调板的顺序来写:先讲反电动势过零在物理上是怎么来的,再讲硬件采样网络怎么设计参数,然后讲STM32上的采样时序和软件滤波怎么实现,最后重点说示波器怎么测、波形怎么认。内容面向正在做方波驱动、准备自己啃无感启动或者用ADC硬采反电动势的工程师和DIY玩家,不涉及FOC那种复杂的坐标变换,只讲方波六步驱动这条务实路线。
1. 无感六步方波驱动与过零信号的底层逻辑
1.1 六步换向的本质与悬空相上的反电动势
三相无刷电机的驱动方式,方波驱动是最直白的一种:任意时刻给三相绕组中的两相通电,第三相悬空。电磁力拉着转子走大约60度电角度,就切换一次通电组合,六个状态循环一遍正好是一圈电角度,这就是“六步换向”。转子位置只要偏差30度以上,力矩就会明显下降甚至反转,所以换向时刻必须对准。
换向时刻从哪里来?带霍尔的方案直接读霍尔信号,无感方案则利用一个物理事实:转子永磁体旋转时,会在三相绕组里感应出反电动势(BEMF)。反电动势的大小正比于转速,而它的相位直接对应转子位置。悬空那一相没有外部电压强制驱动,它的端电压就等于中性点电压叠加上该相的反电动势,所以只要盯住悬空相电压,就能反推转子转到哪了。
这里有个关键结论需要讲透:反电动势过零点正好出现在换向点(最佳换相点)之前30度电角度处。也就是说,你检测到悬空相BEMF过零之后,再等30度电角度,就是理想的换向时刻。这个30度对应的物理时间是转速的函数,转速越快时间越短,这也是后面所有“延迟换相”计算的出发点。
1.2 过零检测真正的难点在哪里
理论很好懂,落地却有一堆麻烦,我踩过的坑基本都集中在下面几个方面。
第一个问题是信号太小。反电动势和转速成正比,静止和低速时BEMF幅度可能只有几十毫伏甚至更小,淹没在噪声和直流偏置里。所以无感方案普遍要求先预定位、强制开环加速到一定转速,才能切入闭环,这个门槛一般在几百转每分。
第二个问题是噪声太狠。电机相线上叠加着母线电压斩波,MOS管开关瞬间还有振铃和尖峰,如果不做硬件滤波,ADC采出来的值完全是乱的。可滤波做重了又会把BEMF信号的相位拉偏,这个矛盾贯穿整个调试过程。
第三个问题是采样窗口。如果PWM占空比很小或很大,反电动势能够被稳定采样的时间窗口就很窄,要么采不到,要么采到的是畸变段。所以通常要把采样点选在PWM关断期间,而不是任意时刻乱采。
把这几个问题想清楚,再去设计硬件和软件,思路就顺了。下面两章分别讲硬件选型参数和软件实现细节。
2. 硬件方案:比较器与ADC的实际取舍
2.1 两种过零检测方案怎么选
业界常见的过零捕捉方案就两条路:外部比较器输出电平跳变,或者MCU内置ADC直接采样悬空相电压,再由软件判过零。二者没有绝对优劣,只有适不适合你的场景。
我把它俩的差异整理成一张表,方便你对照选型:
| 对比项 | 比较器方案 | ADC采样方案 |
|---|---|---|
| 响应速度 | 硬件比较,纳秒级,几乎无延迟 | 取决于ADC采样率和判断周期,通常要几个微秒 |
| 调试直观性 | 只能看到高低电平,内部状态靠猜 | 直接读电压数值,BEMF变化曲线一目了然 |
| 资源占用 | 几乎不占MCU算力,用外部比较器或内部COMP | 需要ADC通道、定时器触发、DMA搬运,软件逻辑更重 |
| 抗干扰能力 | 依靠比较器自身滞回,逻辑简单 | 可做数字滤波、多次采集中间值,灵活性更高 |
| 硬件成本 | 每相一片比较器或复用内部COMP,PCB多几个器件 | 几乎零额外硬件,只要电阻分压网络 |
| 适用场景 | 对换相延迟要求极高、转速范围宽的项目 | 项目初期调试、想看清信号细节、转速中规中矩 |
我的建议很明确:如果是自己DIY或者项目处在调试阶段,优先选ADC方案。原因不是比较器不好,而是ADC方案能看到具体电压值。BEMF波形在你面前摆着,过零在哪、噪声拖尾多长、滤波有没有把相位拉偏,全都能在示波器和串口里直接看出来。等你把ADC方案调通了,如果后续量产要压低MCU负载、压缩换相延时,再换比较器方案,逻辑和参数都可以平移过去。
2.2 ADC采样网络的电阻分压与滤波参数计算
以常见的12V供电系统为例,MCU的ADC参考电压是3.3V,所以母线电压和相电压不能直接进ADC,必须先分压。我常用的分压网络是上拉电阻10kΩ接到相线,下拉电阻4.7kΩ接到GND,中点接ADC引脚。相线最高电压约12V,分压后中点为:
U_adc = 12V × 4.7k / (10k + 4.7k) ≈ 3.84V
这个值已经超过3.3V了,超出ADC量程,不安全。所以参数要重新选。工程上一般让最大分压点不要超过3.0V,留出余量。把下拉电阻改成3.3kΩ再算:
U_adc_max = 12V × 3.3k / (10k + 3.3k) ≈ 3.0V
这个值压在3.0V,对上3.3V参考还留了0.3V余量,安全。注意上拉和下拉的并联等效内阻约为 10k//3.3k ≈ 2.49kΩ,这个内阻直接决定了后面滤波电容的效果。
滤波电容加在ADC引脚和GND之间,构成一阶RC低通。截止频率公式是:
fc = 1 / (2π × R_eq × C)
如果用1nF电容,fc ≈ 1 / (2π × 2.49k × 1nF) ≈ 63.9kHz。这个频率能压掉一部分高频开关噪声,但对20kHz的PWM基波有衰减但不会太狠。如果换成10nF,fc直接掉到6.4kHz,BEMF信号里较高频率的分量就会被明显削弱,波形迟钝,换相点滞后。所以我个人建议,除非你的PWM频率很低或者电机转速很慢,否则电容先别超过2.2nF到4.7nF这个区间。
再说相位延迟。一阶RC在频率f处的相位滞后角是 φ = arctan(f / fc)。假设电机最高电频率1kHz,fc约64kHz,滞后角约0.9度,几乎可以忽略。但如果电容选大了、fc只有6.4kHz,那1kHz处相位滞后约8.9度,对应30度换相延迟调整就是不小的一笔误差,必须补偿。这个计算在调试高速电机时非常关键,实测波形会明显看到过零时刻往后拖。
2.3 比较器方案的参考点选择
如果你想用比较器方案,电路结构其实比ADC简单:三相分别通过分压电阻接到比较器输入端,比较器参考端接一个半母线电压分压点,比较器输出过零脉冲给MCU的捕获引脚。关键在于参考点为什么取半母线电压。
六步驱动中,PWM关断期间悬空相会被续流钳位到近似半母线电压,此时BEMF就在这个基准上叠加波动。BEMF过零的物理含义就是悬空相电压等于中性点电压,而系统在稳态时中性点电压接近半母线电压。所以把比较器参考端设成半母线电压,本质上就是在和中性点电压做比较。为什么不直接测中性点?因为大多数电机没有引出中性点,即使引出了,中性点在开关动作时也有高频扰动,参考地还不如取电阻分压的半母线干净。
比较器本身要考虑滞回量。LM393这类外部比较器可以加正反馈电阻形成滞回,滞回窗口太大会把真实的过零也吞掉,太小又滤不掉抖动。我的经验是从10mV到20mV滞回开始调,根据实测波形微调。STM32F103这类芯片没有内部比较器,用外部LM393/LM339即可;如果换用G4系列或者F3系列,内部COMP可以省掉外部器件,但配置复杂度会转移到寄存器上。
3. 软件实现:采样时序、滤波与换相延时
3.1 采样时刻为什么选在PWM OFF期间
硬件搭好只成功一半,软件采样时刻错了,前面全白做。方波驱动通常采用中心对齐PWM,载波周期内会有一段上管导通、一段下管导通、一段死区。不同调制方式下,悬空相在PWM不同阶段的电压表现差异很大。
实测下来最可靠的采样窗口是PWM OFF期间,准确说是下管导通、上管关闭的那段。此时电流经下管续流,悬空相电压被钳在近似半母线电压附近,BEMF就叠加在这个平台上。此时信号干净,噪声小,而且对ADC来说电平在量程中间,不会过压也不会太低。如果在上管导通期间采,悬空相上会挂着接近母线的高压,分压后超出ADC范围,采出来的数直接削顶,完全不能用。
具体到STM32实现,我建议用定时器的周期匹配事件或更新事件去触发ADC采样,这样能保证每个PWM周期的采样点位置完全一致。比如PWM用TIM1中心对齐模式,把ADC触发源配成TIM1的CC4事件,并把CC4比较值设在计数器接近0或者接近周期值的时刻,正好落在下管续流阶段。这样采样点稳定,省去软件轮询等待的抖动。
3.2 过零判断、30度延迟换相与启动策略
拿到ADC值之后,软件要判断BEMF是否过零,而不是简单地“小于参考就反转”。我一般做两层判断:第一层是滞回比较,比如参考电压是1.5V,电压从上方落到1.45V以下才认为可能过零,从下方升上来要超过1.55V才认为反向过零,这能滤掉一大部分阈值附近的毛刺;第二层是连续N次采样确认,N取3到5,全部满足同一方向才判定为有效过零,避免单次尖峰误触发。
过零确认之后,延迟30度电角度再换相。30度对应的时间计算公式是:
t_30 = 60度电角度时间 / 2 = (1 / (6 × 电频率)) / 2
更直观的写法是,如果当前检测到过零时刻的转速对应的电周期是T_elec,那么 t_delay = T_elec / 12。因为一个电周期内过零事件出现6次(三相各两次),相邻过零间隔60度,过零到换向是30度,正好是60度间隔的一半,也就是一个电周期被12等分。
实际代码里我会用定时器来产生这个延迟,而不是用空转的delay循环。过零中断里把目标延迟时间写到定时器,装载比较值,计数器溢出时进换相中断。这样换相时刻精度不受主循环的其他任务影响。延迟时间要实时更新,因为转速在变,电周期在变,如果一直用固定值,转速一上去换相点就会越偏越远。
启动阶段无感方案绕不开预定位和强制换相。我的启动流程是:先任意给两个绕组通电一段时间,把转子拉到已知位置,然后按固定的强制换相序列逐步加速,转速升到大概400到800转再尝试切换反电动势闭环。切换的判断条件是连续多个过零周期偏差在可接受范围内,且转速估算值稳定。这个启动参数没有万能配置,和电机惯量、负载力矩强相关,只能实测调。
3.3 软件滤波不能只靠硬件:去毛刺与数据平滑
很多初学者觉得硬件滤波电容加够了,软件就不用管了,实际这是错的。电机换相瞬间、MOS管开关瞬态、电源纹波,都会在ADC采样值上叠加尖峰。如果只靠电容,要么滤不干净,要么把BEMF延迟太多。所以软件上必须再做一道保险。
我常用的一种方法是单周期多次采样取中值或平均值。一个PWM周期内用DMA连续采8个点,排序取中间几个点的均值作为当前周期悬空相电压。这个方法对抗尖峰效果明显,而且不会引入像滑动平均那样明显的相位滞后。唯一要注意的是,这8个点必须落在PWM OFF的有效窗口内,如果窗口不够长,点位太少,就只能退回到单点采样加连续判断。
还有一个小技巧:把相邻两次采样的电压差作为辅助判据。BEMF过零时,悬空相电压的斜率方向会发生变换。如果你看到电压值虽然还在参考上方,但斜率已经从负变成正,说明过零即将发生,可以提前一个采样周期做预估。这个逻辑在高速场景下特别好用,等于给换相预测争取了一个周期的提前量。伪代码思路大概是:
if (current_adc < ref_low && last_adc > ref_low) { zero_cross_count++; if (zero_cross_count >= 3) { flag_zero_cross = 1; zero_cross_count = 0; scale_delay_timer(period_estimate / 12); } } else { zero_cross_count = 0; }注意这段逻辑里zero_cross_count要周期清零,防止一个过零被反复确认多次。我见过有人漏了清零,结果一个过零触发三次换相,电机当场乱转。
4. 示波器实测:把看不见的反电动势拍下来
4.1 测量点与探头设置
示波器测量是调方波驱动的重要手段。测量点选在哪,直接决定你看到的是真相还是噪声。我的习惯是:不直接夹MOS管输出端,而是把探头夹在电机相线根部,也就是离电机最近的那段线上。因为MOS管输出端到电机的线段上有寄生电感,开关瞬间会叠加很强的振铃,这部分不是电机本身的信号,会让判断失真。
探头设置上,第一件事是用10x档而不是1x档。10x档输入阻抗高,对电路影响小,频响也宽得多。第二件事是接上接地弹簧,不要用那个长长的鳄鱼夹地线。地线夹在开关节点上会形成一个环,捡到一堆共模噪声,波形糊成一团。实测用接地弹簧和不用接地弹簧,波形干净程度的差别能有一倍以上。
建议打开示波器的20MHz带宽限制。方波驱动里PWM频率普遍在16kHz到25kHz,BEMF信号的频率范围远低于20MHz,打开带宽限制能滤掉一部分高频空间辐射噪声,波形反而更清楚。电压档位一般设在每格1V到2V,时间档位根据转速来调,先看两三个电周期,再慢慢收紧。
4.2 实测波形到底长什么样
虽然文章里不能用图,但我尽量把波形特征描述到你能自己照着认的程度。用ADC方案时,你示波器上看到的悬空相电压波形大概是这样的:MOS管导通期间,相电压被拉到接近母线电压并被PWM斩波,出现一簇方波脉冲;MOS管关断期间,波形下降到一条近似水平的平台,这就是续流钳位段;在这个平台上,会叠着一条缓慢变化的曲线,那就是反电动势的片段。BEMF过零时,这条曲线从平台上方穿过平台继续往下走。
你判断过零成功与否的标志是:过零发生的位置应该在换相前30度电角度处,且每个电周期内过零间隔应该是均匀的。如果用两个通道同时测两相电压,再叠加一个换相逻辑信号,能明显看到换相事件发生在过零之后、波形对称的位置。如果换相点和BEMF过零的间隔忽长忽短,说明过零检测不稳定或延迟时间没更新好。
如果是比较器方案,观察点就简单多了:比较器输出引脚应该是周期性的方波,高电平时间与低电平时间加起来正好覆盖一个电周期内该相的悬空段,边沿位置就是过零时刻。重点看边沿有没有抖动,如果触发示波器单次抓取时,边沿位置每次都在跳,说明比较器参考电压附近噪声太大,要么滞回不够,要么采样点选错了窗口。
4.3 示波器测量的波形陷阱
调试中你大概率会看到一些迷惑波形,我挑三个最常见的陷阱提醒一下。
第一个是共地干扰。示波器探头的地线夹如果夹在电机地线上,而电源地和电机地之间存在较长走线,高频开关电流会在地线回路产生压降,导致你测出来的波形上叠了一层和开关同步的噪声。解决方法是把探头地和被测点尽量靠近,最好直接接在电机负极或母线电容的负极上,那里是系统真正的参考地。
第二个是滤波电容太大导致的相位延迟。你在示波器上会看到过零时间明显往后拉,原本过零后30度换相,实际可能拖到40度甚至更多,电机发热明显上升。这种问题不是算法调参能解决的,要把电容改小,或者软件里补偿这个延迟。我的排查方法是把实测的过零波形和电流波形对照,如果电流过零点比理论位置明显滞后,先怀疑相位延迟。
第三个是浮地测量问题。如果你的系统和示波器不共地,直接用探头接相线会把示波器地拉到高压上。示波器标配的探头地线只适合共地系统,隔离测量要用差分探头或者隔离通道,千万别拿普通探头去捅浮地的高压侧,这是安全问题,没有商量余地。
5. 常见问题排查与实战心得
5.1 常见问题速查表
调试过程中遇到的问题,90%都能归到下面几类。我整理成一张速查表,方便排查时对号入座:
| 现象 | 可能原因 | 排查方法与解决思路 |
|---|---|---|
| 启动时电机抖动,无法转动 | 预定位不充分,强制换相时序不对 | 延长预定位时间,降低强制换相启动频率,增大初始占空比 |
| 低速切入闭环瞬间失步 | BEMF信噪比低,过零误判 | 提高切入转速,检查滤波是否过重,适当增大滞回窗口 |
| 运行中偶发失步,伴随异响 | 过零连续判断次数太多,换相延迟没跟上 | 降低连续确认阈值,检查t_delay是否实时更新 |
| 空载正常,带载失步 | 负载变化导致电周期突变,延迟时间偏差大 | 增加转速估算的更新频率,压缩过零到换相的延迟链路 |
| 相电压波形有明显毛刺 | 探头地线过长,测量点离MOS管太近 | 用接地弹簧,改到电机相线根部测量,开20MHz带宽限制 |
| 比较器边沿抖动严重 | 参考电压噪声大,滞回不足 | 增加正反馈电阻调滞回,检查分压网络滤波电容 |
| 高速时过零信号丢失 | PWM占空比过大,有效采样窗口过短 | 限制占空比上限,必要时改用同步整流或比较器方案 |
5.2 几个值得记住的实战心得
调试顺序上,我强烈建议先用开环强制换相把电机转起来,再用示波器确认BEMF波形正常,最后才切入闭环。很多人一上来就指望闭环直接完美运转,结果软件、硬件、参数三个变量搅在一起,出问题根本不知道怪谁。开环阶段能确认硬件和电机本身没问题,等于先关掉一个变量。
滤波参数我从“宁轻勿重”的原则开始调。先用小电容、快采样、软件多做判断,再根据实测波形逐步加重滤波。反过来的路线就痛苦了,电容一大,所有波形看着都圆润,但换相点全偏了,你还以为是延迟时间没算对,白白浪费时间。我在这上面栽过一次跟头,调了三天发现是滤波电容惹的祸。
最后说个小技巧:用ADC方案调试时,把悬浮相的采样值通过DAC或者PWM引脚输出,再接到示波器另一个通道,这样你能实时看到软件内部的过零判断依据,比单纯看相电压波形更直接。我当时就是用这个方法,把过零判据和实际波形对齐,一眼就看出软件里的比较阈值偏了零点几伏,两分钟就定位了问题。
无感方波驱动的过零检测,说到底是一套“物理信号—硬件调理—软件判据”的链路,每一环都要对。硬件把BEMF调到你采得了的位置,软件在对的时刻采样并用稳定的判据确认,再用示波器把每一步都验证清楚,整条链路就通了。我自己的体会是,这个项目急不得,每个环节都值得静下来多测几次波形,宁可多花一个晚上看波形,也别用加班去掩盖没有定位的问题。