三相电机控制器满载烧桥臂、电流值跟着占空比跳,查到根因往往是死区、故障封锁和采样时刻三件事没一起算。结论先给:dsPIC30F2010 的 MCPWM 把这三件事都做进了硬件——6 位死区计数器定死区,FLTA 引脚在硬件路径上封锁故障,4 路采样保持配合 SEVTCMP 把电流采样点钉在开关之外。
三相无刷电机的控制器在样机阶段最容易出现的一种情况是:台架上带小电流跑得很好,装到整机满载跑两天,桥臂烧了一对;换掉功率管再跑,又烧。拆下来的管子多数是上下管同时导通击穿。结论先给:这类问题往往不是功率管选小了,而是互补 PWM 的死区时间、故障封锁的响应路径、电流采样的时刻这三件事没有放在一起算。dsPIC30F2010 的 MCPWM 模块刚好把这三件事都做进硬件:6 位死区计数器、FLTA 故障输入,以及可以触发 A/D 的特殊事件比较器。
MCPWM 的每一对互补输出都配了一个 6 位递减计数器,专门用来插死区。DTCON1 寄存器中的 DTAPS<1:0> 和 DTBPS<1:0> 选择死区时钟的预分频,可选 TCY、2TCY、4TCY、8TCY 四档;选定预分频后,再把 6 位无符号值写入 DTCON1,就定下了死区长度。按这个结构折算,死区步长等于"预分频 × TCY",最大 63 步。
| 预分频档位 | 单步时间(TCY = 33 ns) | 计数值 0x01 | 最大值 0x3F |
|---|---|---|---|
| TCY(1 档) | 33 ns | 33 ns | 2.08 µs |
| 2TCY | 66 ns | 66 ns | 4.16 µs |
| 4TCY | 132 ns | 132 ns | 8.32 µs |
| 8TCY | 264 ns | 264 ns | 16.63 µs |
表里的 TCY 按 30 MIPS(33 ns)代入,实际项目按自己器件的指令周期重算即可。选哪一档看的不是习惯,而是功率级:死区必须大于"驱动器传输延迟离散 + 功率管关断时间 + 余量",同时在满足这个下限的前提下尽量取小。死区偏小会直通,偏大则输出电压失真、低速电流纹波变大,两头都是实打实的代价。
手册里还有一条硬约束:PWM 模块工作期间(PTEN = 1)不要修改 DTCON1,否则可能出现意外结果。因此死区值应该在使能时基之前一次写完,运行中不做动态调整。另外,DTCON1 写入、任何器件复位都会清零死区预分频器,改参数后出现一两个周期的异常属于正常现象,别把它当成硬件故障。
PWMCON1 中对应的 PMODx 位清零时,该对引脚工作在互补模式,器件复位后默认就是互补;置 1 则改成独立输出,此时一对引脚之间不再插入死区,也允许同时有效。三相结合桥必须留在互补模式,独立模式是给需要两路独立占空比的负载准备的。
需要手动封锁某一路时,用 OVDCON 的 POVDxH / POVDxL 选择要改写的引脚,POUTxH / POUTxL 指定改写后的电平。注意即使处在手动改写状态,互补模式下的死区插入依然有效,不会因为"人手干预"就把直通风险放开。若把 PWMCON2 的 OSYNC 置 1,改写动作会与 PWM 时基同步——边沿对齐在 PTMR 归零时生效,中心对齐在归零或与 PTPER 匹配时生效,可以避免在半周期切出一个窄脉冲。
FLTA 引脚的作用是在过流、母线过压这类故障出现时,把 PWM 引脚直接拉到 FLTACON 预先定义的状态,整条路径不经过 CPU。使能位是 FLTACON 中的 FAEN3 / FAEN2 / FAEN1,一位管一对引脚;FAOVxH / FAOVxL 八个位决定故障时每个引脚是高还是低,实际电平还要结合 HPOL、LPOL 极性配置来看。如果把所有使能位都清零,FLTA 就退化成普通中断引脚或 I/O,不需要硬件封锁的场合可以这么用。
| 对比项 | 锁存模式(FLTAM = 0) | 逐周期模式(FLTAM = 1) |
|---|---|---|
| 进入条件 | FLTA 拉低 | FLTA 拉低 |
| 保持条件 | 一直保持,直到 FLTA 变高且软件清中断标志 | 只要 FLTA 为低就保持 |
| 恢复时机 | 上述两个条件都满足后的下一个 PWM 周期或半周期边界 | FLTA 变高后的下一个 PWM 周期或半周期边界 |
| 适用场景 | 过流、短路等需要人工确认的硬故障 | 限流、瞬时过载等可自恢复工况 |
两种模式的差别只在"什么时候回来"。锁存模式下,如果软件在 FLTA 还有效时就清了中断标志,模块会等到 FLTA 真正失效才恢复输出,这个细节常被误判成"清了标志还不恢复"。工程上默认选锁存:过流通常意味着硬件已经异常,让它自己恢复等于把故障放大一次。还有一点容易漏——FLTA 引脚在休眠模式下也能把 CPU 唤醒,做低功耗待机时若这根线被拉低,系统会被叫醒。
dsPIC30F2010 的 A/D 是 10 位逐次逼近型,最高 500 ksps,最多 16 个模拟输入,内部有 4 个采样/保持放大器。三相电流加母线电压正好四路,这才是它能做电机控制的底气:四路同时进入保持状态,再依次转换,采到的就是同一时刻的电流,而不是相差几个微秒的三次采样。
控制这件事的是 ADCON2 里的几个位:CHPS 选择每次采 1、2 还是 4 个通道;SIMSAM 为 1 时多通道在同一采样时钟内同时采样、随后顺序转换,为 0 则逐个采样转换;SMPI 决定发生几次采样转换后产生一次中断(1~16 次)。结果缓冲器是 16 字双端口 RAM(ADCBUF0~ADCBUFF),BUFM 置 1 时拆成两个 8 字缓冲交替写入,给 CPU 留出搬数据的时间;不拆的话,CPU 必须在两次触发之间把 16 个字全部搬完,搬不完就会丢数据。
采样时钟手册给得很明确:一次转换需要 12 个 TAD,TAD 最小 154 ns,且 TAD = TCY × 0.5 × (ADCS<5:0> + 1)。按 30 MIPS 即 TCY = 33 ns 计算,ADCS = 2 × 154 / 33 − 1 ≈ 8.33,向上取 9,实际 TAD = 165 ns,一次转换约 1.98 µs。要跑满 500 ksps,必须选自动转换触发(SSRC = 111)并把 SAMC 设为 1 个 TAD,整个周期 13 个 TAD;换成其他触发源都会额外插入 TAD 去和外部事件同步,实际速率会掉下来。
| 参数 | 手册取值 | 工程含义 |
|---|---|---|
| 分辨率 / 速率 | 10 位 SAR,最高 500 ksps | 约 1 LSB ≈ 4.9 mV(AVDD = 5 V 时) |
| 输入通道 / 采样保持 | 最多 16 通道,4 路 S/H | 三相电流 + 母线电压可同时采样 |
| 每次转换 | 12 个 TAD,TAD ≥ 154 ns | 最短约 1.85 µs/次 |
| 自动触发全周期 | SAMC = 1 时为 13 个 TAD | 30 MIPS 下约 2.15 µs,对应 500 ksps 上限 |
| 建议源阻抗 | RS ≤ 5 kΩ | 分压采母线电压时按这个约束配电阻 |
模拟输入这一端还有一个常被忽略的约束:建议信号源阻抗不超过 5 kΩ。手册给出的输入模型里,采样开关阻抗 RSS ≤ 3 kΩ、内部走线阻抗 RIC ≤ 250 Ω、保持电容 4.4 pF、引脚漏电流 ±500 nA。源阻抗太大,保持电容在有限的采样窗口里充不满,读数就会随通道切换而偏低,表现出来就是"电流值跟着占空比跳"。经运放缓冲的电流采样一般不受影响,直接电阻分压采母线电压时要按 5 kΩ 以内来配。
三相电流必须在开关动作之外的时刻采,否则采到的是开关噪声。MCPWM 的特殊事件触发器就是干这个的:往 SEVTCMP 写入一个 PTMR 比较值,时基计到这个值就产生触发信号,可以直接启动 A/D;中心对齐模式下还要用 SEVTDIR 指定在递增段还是递减段触发,不配中心对齐时这一位不起作用。SEVOPS<3:0> 是触发信号的后分频,1:1 到 1:16 可配,需要隔几个 PWM 周期采一次时用它,不必反复改比较值。写 SEVTCMP 会清零后分频计数器,所以配置顺序是先定周期和占空比,再定触发点。
/* dsPIC30F2010:中心对齐 PWM + 四路同时采样 + FLTA 锁存保护
* 假设 FCY = 30 MIPS,TCY = 33 ns,目标 PWM 频率约 10 kHz
*/
PTCON = 0x0000; /* PTEN = 0,配置期间关闭时基 */
PTPER = 1499; /* 中心对齐:2 × 33 ns × 1500 ≈ 99 µs */
PTCKPSbits.PTCKPS = 0; /* 时基预分频 1:1 */
PTMODbits.PTMOD = 2; /* 连续递增/递减,即中心对齐 */
/* 死区:预分频取 TCY,计数值 21,约 0.69 µs */
DTCON1 = 21;
/* 三相互补输出,初始占空比 50% */
PDC1 = 750; PDC2 = 750; PDC3 = 750;
/* FLTA:三对输出全部受控,故障时拉低,锁存模式 */
FLTACON = 0x0007; /* FAEN3..FAEN1 = 1,FAOV 全 0,FLTAM = 0 */
/* A/D:四通道同时采样,双缓冲 */
ADCON1 = 0x0000; /* 10 位结果,整数格式,AVDD/AVSS 为参考 */
ADCON2 = 0x0000;
ADCHS = 0x0000; /* CH0..CH3 对应 AN0..AN3 */
ADPCFG = 0x0000; /* AN0..AN3 作为模拟输入 */
ADCON3bits.ADCS = 9; /* TAD ≈ 165 ns */
ADCON3bits.SAMC = 1; /* 自动采样 1 个 TAD */
ADCON2bits.CHPS = 3; /* 每次采 4 个通道 */
ADCON2bits.SIMSAM = 1; /* 同时采样,顺序转换 */
ADCON2bits.SMPI = 2; /* 每 4 次采样转换产生一次中断 */
ADCON2bits.BUFM = 1; /* 16 字缓冲拆成两个 8 字交替写 */
ADCON2bits.ASAM = 1; /* 采样由触发事件自动启动 */
/* SSRC<2:0>:选择 MCPWM 特殊事件作为转换触发源 */
/* 采样点:中心对齐递减段 PTMR = 1000 时触发 */
SEVTCMP = 1000;
SEVTDIR = 1;
PWMCON2bits.SEVOPS = 0; /* 每个 PWM 周期触发一次 */
PWMCON2bits.OSYNC = 1; /* 输出改写与周期同步 */
ADCON1bits.ADON = 1; /* 先使能 A/D */
PTCONbits.PTEN = 1; /* 最后使能 PWM 时基 */
| 现象 | 常见根因 | 改法 |
|---|---|---|
| 满载运行一段时间烧上下管 | 死区小于驱动延迟差与关断时间之和 | 实测驱动与关断时间,按表选更大的档位,留 20% 以上余量 |
| 改了死区后输出有几拍异常 | 运行中写 DTCON1,预分频被清零 | PTEN = 1 期间不改 DTCON1,参数在初始化阶段一次写完 |
| 过流封锁后清标志仍不恢复 | 锁存模式要求 FLTA 先变高 | 检查硬件是否已释放故障,再清中断标志 |
| 三相电流值两两不一致 | 顺序采样而非同时采样 | CHPS = 3 且 SIMSAM = 1 |
| 电流读数随占空比漂 | 采样点落在开关沿附近,或源阻抗过大 | 用 SEVTCMP 把采样点移到开关之外,源阻抗压到 5 kΩ 以内 |
| 高占空比时丢采样点 | CPU 搬缓冲的时间不够 | BUFM = 1 拆双缓冲,或调小 SMPI |
| PWM 一使能就进中断 | PTPER 写成了 0x0001 | 按目标频率重算 PTPER,避开 0x0000 与 0x0001 |
一句话总结:dsPIC30F2010 做电机控制,硬件能替你做的是三件确定的事——用 6 位计数器把死区做准,用 FLTA 在硬件路径上封锁故障,用 4 路采样保持加 SEVTCMP 把电流采样点钉在开关之外。这三件事配错任何一件,现象都会指向功率管,但根因都在配置顺序里。
还想接着看:STM32 TIM1 中心对齐 PWM 与编码器 FOC 实战、F103 双 ADC 同步采样与 DMA 乒乓缓冲、反电动势过零点无感 BLDC 怎么调。
本文基于 Microchip dsPIC30F2010 数据手册(DS70118E_CN)第 14 章电机控制 PWM 与第 18 章 10 位高速 A/D 技术资料整理优化。
沧州艾诺威电子 — 国家高新技术企业,20+项国家专利
嵌入式系统开发 · 物联网方案 · AI智能硬件 · 一站式交付
电话:13930711029 | 邮箱:tech@czinv.com | 24小时内响应