news 2026/10/15 18:37:52

TMS320F280049C PWM外设详解:从EPWM时钟到死区与故障保护

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TMS320F280049C PWM外设详解:从EPWM时钟到死区与故障保护

简介:面向TI TMS320F280049C DSP开发者的PWM相移控制示例工程,基于C28x内核与driverlib驱动库,重点演示PWM模块的相位偏移生成、计数器与比较寄存器配置、死区时间设置、中断事件响应等关键操作,可直接导入CCS进行编译调试,适用于电机驱动、数字电源、工业自动化等实时控制场景。压缩包共含33个文件,以C源码、汇编启动代码、cmd链接脚本、driverlib.lib库、CCS工程配置文件及编译调试产物为主,整体318KB,结构完整覆盖从复位引导、外设初始化到程序链接分配的开发链路。目前已有1030人学习下载,对于希望掌握F280049C PWM应用的开发者具有不错的参考价值。通过学习这份工程,能够理清PWM模块从寄存器配置到实际输出波形的完整流程,理解C28x DSP的存储器组织与链接命令写法,同时熟悉CCS环境下的编译、烧写和调试方法。项目内还包含readme说明与调用driverlib.lib的典型用法,便于对照实践,并为后续PID控制等复杂算法扩展提供基础。

1. 拿到一个 PWM 工程文件,先别急着烧板子

做电机控制或者数字电源的工程师,第一次拿到 TMS320F280049C 的 PWM 例程时,多半会被 EPWM 模块里那一堆寄存器名字吓一跳。TBPRD、CMPA、DBRED、TBPHS、AQCTLA……这些缩写看起来像一个黑匣子,但 PWM 恰恰是 F280049C 上最核心、也最不能写错的外设:占空比不对是小事,死区不够或者故障保护没配置,板上的 MOS 管会直接冒烟。这篇文章顺着一个常见 PWM 工程文件的组织方式,把时钟链路、初始化顺序、死区和相位配置讲清楚,再列出几种示波器上最常见的故障现象和排查思路,适合刚从普通单片机转过来、第一次接触 C2000 实时控制芯片的开发者。

2. 时基时钟从哪来:先看懂 PWM 频率的分频链路

做电机控制的同事第一次拿 F280049C 的 PWM 例程时,问得最多的一个问题就是:为什么代码里写的是 20kHz,示波器上看到的却是 10kHz 甚至是 5kHz?绝大多数情况下都不是周期寄存器写错,而是时基时钟没有按预期工作。EPWM 模块的时基计数器每跳一步需要多长时间,完全由两级分频和计数模式共同决定,链条上任何一环理解错了,输出频率都会对不上账。

2.1 从 100MHz 主频到 TBCLK:两级分频不能省

TMS320F280049C 的内核最高跑到 100MHz,这个频率是系统时钟 SYSCLK。EPWM 模块的输入时钟 EPWMCLK 默认从 SYSCLK 而来,但实时控制里通常不会让时基计数器直接以 100MHz 步进,因为这样算出来的周期值会太小,而且死区时间、相位差这些时间量会很难换算。EPWM 内部先做第一级分频 EPWMCLKDIV,再做第二级分频 CLKDIV,两级分频相乘后取倒数,才是时基时钟 TBCLK 的周期。

用公式表示就是:

f_TBCLK = f_EPWMCLK / (EPWMCLKDIV × CLKDIV)

分频参数常见取值作用所在寄存器
EPWMCLKDIV1 / 2 / 4 / 8 / 16 / 32 / 64 / 128EPWM 模块级时钟分频TBCTL 高两位字段
CLKDIV1 / 2 / 4 / 8 / 16 / 32 / 64 / 128时基计数器预分频TBCTL 中字段
TBPRD1 ~ 65535时基周期匹配值TBPRD 寄存器(16 位)
TBCTR0 ~ 65535当前计数值TBCTR 寄存器(16 位)

这两个分频器的选值直接决定了 TBCLK 和后面所有时间量的换算关系。举个例子:如果 TBCLK = 100ns,那么死区延迟计数写 10 就是 1us,相位差计数写 33 就是 3.3us;如果把分频理解错了一档,同样的数字在示波器上看会差一倍甚至更多。所以我把时钟链路放在第一个小节来讲,后面所有寄存器的数值计算都要回到这里来对账。

2.2 三种计数模式,三种频率公式

时基计数器支持向上计数、向下计数、向上-向下计数三种模式。频率公式很容易在手册里查到,但很多人会忽略计数从 0 开始这个细节,导致周期值差 1。

  • 向上计数:计数器从 0 递增到 TBPRD,然后回到 0。一个完整周期经过 TBPRD + 1 个 TBCLK,所以 f = TBCLK / (TBPRD + 1)。
  • 向下计数:计数器从 TBPRD 递减到 0,然后回到 TBPRD。同样经历 TBPRD + 1 个 TBCLK,公式与向上一致。
  • 向上-向下计数:计数器从 0 递增到 TBPRD,再递减回 0,一个周期经历 2 × TBPRD 个 TBCLK,所以 f = TBCLK / (2 × TBPRD)。

向上和向下模式虽然公式相同,但波形在时间轴上的位置不一样,多数电机控制会选用向上-向下计数,因为波形中心对齐、谐波小;数字电源则更常用向上计数,实现简单、相位容易对齐。

2.3 一个算错频率的典型例子

假设主频 100MHz、EPWMCLKDIV = 1、CLKDIV = 10,那么 TBCLK = 10MHz。想在向上计数模式下输出 20kHz:

TBPRD + 1 = 10MHz / 20kHz = 500,所以 TBPRD = 499。

如果手滑把 TBPRD 写成了 500,实际频率就变成 10MHz / 501 ≈ 19.96kHz。示波器上肉眼可能看不出来,但如果你用频率计去量、或者多个 PWM 通道做同步,这个误差就会被放大。另一个容易犯的错是:把向上计数和向上-向下计数的公式混用。同样的 20kHz,向上-向下计数时 TBPRD 要写 250,不是 499。

注意:TBPRD 是 16 位寄存器,最大值 65535。如果 TBCLK 很高、目标频率又很低,TBPRD 可能溢出。频率低于 1kHz、时基又没分频时尤其要小心。

3. 跑通一个最小 PWM 工程:初始化代码逐行拆解

很多刚接触 F280049C 的开发者会直接去找例程里的 PWM 配置,复制一段过来就下板,结果引脚没输出、频率不对、占空比不动,然后开始怀疑芯片坏了。实际上一个最小的 EPWM 输出需要四步走齐:使能外设时钟、配置 GPIO 复用、设置时基、设置动作限定器。缺任何一步,示波器上都是零。

3.1 打开外设时钟,把 GPIO 切到 EPWM 复用功能

第一步不是配置 PWM 寄存器,而是让 EPWM 模块先通电。很多初学者在初始化里漏掉了外设时钟使能这一步,导致后面所有寄存器写完没有任何反应。另外,F280049C 的 GPIO0 和 GPIO1 默认是普通输入输出口,必须通过引脚复用配置,把这两个引脚切到 EPWM1A 和 EPWM1B 功能上,PWM 信号才能从对应引脚送出来。下面这段是典型的初始化开头:

#include "board.h" #include "epwm.h" #define PWM_TBCLK_MHZ 10 // 时基时钟 10MHz #define PWM_FREQ_KHZ 20 // 目标 PWM 频率 20kHz #define PWM_TBPRD (PWM_TBCLK_MHZ * 1000 / PWM_FREQ_KHZ - 1) // 499 #define PWM_CMPA_HALF (PWM_TBPRD / 2) // 249 void EPWM1_Init(void) { // 1) 打开 EPWM1 外设时钟,这一步漏了就全白写 SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1); // 2) 引脚复用:GPIO0 -> EPWM1A,GPIO1 -> EPWM1B GPIO_setPinConfig(GPIO_0_EPWM1_A); GPIO_setPinConfig(GPIO_1_EPWM1_B); GPIO_setPadConfig(GPIO_0, GPIO_PIN_TYPE_STD); GPIO_setPadConfig(GPIO_1, GPIO_PIN_TYPE_STD); }

这段代码里最关键的是引脚复用配置。普通单片机里输出 PWM 可能只要把 GPIO 设成输出模式就行,但 C2000 系列的外设信号必须通过 MUX 复用表选通,GPIO_setPinConfig 干的就是这件事。GPIO_setPadConfig 设置的是引脚电气特性,标准模式下推挽输出、不上拉不下拉,适合接数字输入或驱动小功率负载。

注意:不同封装、不同引脚上 EPWM 的复用编号不一样。比如同一个 EPWM1A 信号在有的封装上映射到 GPIO0,在另一封装上可能映射到 GPIO15,必须对照参考手册的引脚复用表确认。

3.2 配置时基:周期、初值、计数模式

时基部分的配置顺序很重要,我的习惯是先配分频、再配周期、最后配计数器初值。如果先写 TBPRD 再改分频,TBCLK 频率会变,算好的周期值等于白写。下面这段是时基配置:

// 3) 时基时钟 = 100MHz / 1 / 10 = 10MHz EPWM_setClockPrescaler(EPWM1_BASE, EPWM_CLOCK_DIVIDER_1, // EPWMCLKDIV = 1 EPWM_PRESCALE_DIVIDER_10); // CLKDIV = 10 // 4) 周期值:向上计数,10MHz / (499 + 1) = 20kHz EPWM_setTimeBasePeriod(EPWM1_BASE, PWM_TBPRD); // 5) 计数器清零,等待启动 EPWM_setTimeBaseCounter(EPWM1_BASE, 0); // 6) 向上计数模式 EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);

EPWM_setClockPrescaler 的第一个参数 EPWM_CLOCK_DIVIDER_1 是 EPWMCLKDIV,第二个参数 EPWM_PRESCALE_DIVIDER_10 是 CLKDIV。两个参数容易传反,传反的结果是分频倍数不变,但概念上完全错位,后面一旦要调整其中一个,就会发现自己改错了对象。

3.3 动作限定器:CMPA 在哪个边沿触发哪个动作

时基只是把计数器跑起来,真正决定输出波形的是一组动作限定器(Action Qualifier)。动作限定器的作用是:在计数器等于某个特定值时,把输出置高、置低或翻转。EPWM 的每个输出通道 A/B 都有四个触发点:CTR = 0、CTR = PRD、计数器递增时 CMPA/CMPB 匹配、计数器递减时 CMPA/CMPB 匹配。

// 7) 比较值:CMPA = 249,向上计数时约 50% 占空比 EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, PWM_CMPA_HALF); // 8) 影子装载:计数器归零时一次性装载比较值 EPWM_setCounterCompareShadowLoadMode( EPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); // 9) 动作限定器: // CTR=PRD 时输出低电平 // 递增计数匹配 CMPA 时输出高电平 // CTR=0 和递减匹配 CMPA 时不动 EPWM_setActionQualifierAction( EPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_ACTION, // CTR = 0 EPWM_AQ_OUTPUT_LOW, // CTR = PRD EPWM_AQ_OUTPUT_HIGH, // 递增时 CMPA 匹配 EPWM_AQ_OUTPUT_NO_ACTION); // 递减时 CMPA 匹配

这段配置产生的波形是:从 0 计数到 CMPA 之前输出低电平,到 CMPA 时拉高,继续计数到 TBPRD 时拉低,然后回到 0 开始下一周期。只要 CMPA 的值在 0 到 TBPRD+1 之间,占空比就是近似线性的。CMPA 写 249、TBPRD 写 499,高电平区间是 250 个计数周期,占空比约 50.1%,和理论值几乎一致。

3.4 影子装载:周期中断里更新占空比的前提

很多做电源的工程师第一次遇到“占空比改了没反应”的问题时,都是从影子装载开始的。EPWM 的比较值寄存器默认是带影子的:你写入 CMPA,真正生效的寄存器不会立刻更新,而是要等某个装载事件触发。这个设计是为了避免占空比在一个周期中间突然跳变,导致输出波形出现窄脉冲或毛刺。

装载时机触发事件适用场景
立即装载写入后立刻生效静态配置、调试
计数器归零时TBCTR = 0周期中断内更新,最常见
计数器到周期时TBCTR = TBPRD对称 PWM 的同步点

在我上面的配置里,影子装载设为“计数器归零时”,也就是每个 PWM 周期开始的位置才把新占空比送入硬件。配合后文会讲到的周期中断,可以实现每个周期都更新占空比,这也是 SVPWM 和数字电源控制的基本前提。

3.5 一个完整的 main 函数骨架

把上面的初始化串起来,main 函数的结构大概是这样的:

void main(void) { // 初始化系统时钟、看门狗等基础配置 Device_init(); // 初始化 EPWM1 输出 EPWM1_Init(); // GPIO 和 EPWM 配置完成后,开启全局中断(如果需要) // 中断初始化放在 EPWM 配置之后 while (1) { // 主循环不参与实时占空比修改 // 实时控制放在 EPWM 周期中断里做 } }

这个结构在现网项目里很常见:主循环只负责显示、通信、参数处理,占空比的实时更新全部放到中断里。如果你试图在主循环里用延时翻转 GPIO 来模拟 PWM,CPU 根本无法在微秒级稳定定时,这也是单片机做不了高质量电源/电机控制的原因——EPWM 是硬件自动跑的数,不是软件翻转出来的。

4. 从单路方波到互补驱动:死区、相位与故障保护

单路 PWM 只是第一步,真正让 F280049C 脱颖而出的是多通道协调能力。电机驱动需要互补输出,而且要确保上下桥臂不会同时导通;多路交错电源需要相位精确错开;大功率装置需要硬件级故障保护。这几件事全部由 EPWM 模块内部的死区单元、相位同步单元和故障区(TZ)完成,不需要 CPU 介入。

4.1 死区参数怎么算:DBRED 和 DBFED 的单位是 TBCLK

互补输出就是把同一路 PWM 同时送给上桥和下桥驱动,但两个信号不能同时为高,否则母线会直通短路。死区模块的作用是在上升沿或下降沿插入一段延迟,让上桥关断之后下桥才开始导通。F280049C 的死区延迟寄存器 DBRED 和 DBFED 以 TBCLK 周期为单位,所以算死区时间先要回到第 2 章的时钟链路。

举个例子:TBCLK = 10MHz,想要 1us 死区,那么 DBRED = 10MHz × 1us = 10。我见过很多人在这一步把死区设得特别大,比如 100 个计数,在 10MHz 时基下就是 10us,对 20kHz 的 PWM 来说占掉了整整 20% 的周期,波形直接畸变。死区时间不是越大越安全,它要大于功率管的关断延迟,又要尽量小,否则输出波形失真、效率下降。

死区参数计算方式典型值
DBRED上升沿延迟 = 死区时间 × TBCLK10(1us @ 10MHz)
DBFED下降沿延迟 = 死区时间 × TBCLK10(1us @ 10MHz)
死区模式仅上升沿 / 仅下降沿 / 双向双向最常用

配置死区模块的典型代码如下:

// 死区:上升沿延迟 10 个 TBCLK = 1us EPWM_setRisingEdgeDelayCount(EPWM1_BASE, 10); EPWM_setFallingEdgeDelayCount(EPWM1_BASE, 10); EPWM_setDeadBandDelayMode(EPWM1_BASE, EPWM_DB_RED, true); EPWM_setDeadBandDelayMode(EPWM1_BASE, EPWM_DB_FED, true); EPWM_setDeadBandMode(EPWM1_BASE, EPWM_DB_RED_FED_ENABLE); // EPWM1A 高有效,EPWM1B 低有效(互补输出) EPWM_setDeadBandPolarity(EPWM1_BASE, EPWM_DB_POLARITY_RED_ACTIVE_HIGH, EPWM_DB_POLARITY_FED_ACTIVE_LOW);

注意:死区配置必须要放在时基和动作限定器都配置完之后。死区模块是从 A 路输入信号取原始的 PWM 波形,再分别生成延迟后的 A 和互补的 B,中间任何一步没配置好,看波形时都是乱的。

4.2 互补输出只有一路使能还不够:A/B 极性配合

很多人以为把死区配好了,EPWM1A 和 EPWM1B 就自动互补了。不是的,你还要决定 EPWM1B 的极性。上面代码里把 B 路设成“下降沿有效”,实际输出就是 A 的反相信号,再叠加上死区延迟,才是真正安全的互补波。如果你忘了配极性,B 路可能会和 A 路同相,上下桥同时导通,一上电就炸。

调试互补输出有个笨但有效的办法:先把死区设成 0,看 A/B 波形是不是完全反相;确认反相后,再逐步加大死区,直到你看到两个信号之间出现清晰的“窗口”空隙。这个顺序能帮你区分是死区问题还是极性配置问题。

4.3 相位同步:TBPHS 与 SYNC 信号

多路 PWM 场景里,比如三相逆变器或者多相交错电源,第二路 PWM 要相对第一路错开固定相位。F280049C 的 EPWM 模块之间通过 SYNC 信号级联:主模块在计数器归零时发出同步脉冲,从模块收到脉冲后,把 TBPHS 寄存器里的相位值装载到计数器里,实现相位对齐。

相位值换算和相位角度有关:还是以 TBPRD = 499、TBCLK = 10MHz 的向上计数模式为例,360 度对应 500 个计数周期,那么 120 度就是 500 × 120 / 360 ≈ 166。配置成从模块的方法如下:

// EPWM1 为主模块:计数器归零时发同步脉冲 EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); // EPWM2 为从模块:相位滞后 120 度 EPWM_setPhaseShift(EPWM2_BASE, 166); EPWM_enablePhaseShiftLoad(EPWM2_BASE, true);

相位同步配置里最容易犯的错是把 TBPHS 直接写成角度值,比如写 120。这里存的是计数值,不是角度,必须先按照时基和周期换算。另外一个坑是:主模块和从模块必须使用同一个时基时钟频率,如果两个通道的分频不一样,相位会随时间漂移,无法保持稳定。

4.4 TZ 故障保护:硬件过流时直接强制输出

TZ 模块的全称是 Trip Zone,相当于 PWM 硬件输出的“急停开关”。它监控一组故障信号源,一旦触发,可以立刻把 EPWM 输出强制为高、低或高阻态,整个过程不需要 CPU 参与。这个特性在大功率电源里至关重要:过流信号从比较器出来到 PWM 关闭,必须是硬件级延迟,而不是等中断里软件去改寄存器。

// TZ1 故障输入触发时,EPWM1A 和 EPWM1B 强制输出低电平 EPWM_setTripZoneAction(EPWM1_BASE, EPWM_TZ_ACTION_LOW, // EPWM1A EPWM_TZ_ACTION_LOW); // EPWM1B EPWM_enableTripZoneSignals(EPWM1_BASE, EPWM_TZ_SIGNAL_OSHT1);

TZ 配置有两个容易踩的坑。一是故障信号极性不对,有的板子过流信号是低有效,有的高有效,配置反了就会出现一上电就关断、或者过流了纹丝不动。二是故障发生后没有软件清标志,PWM 一直处于锁定状态,必须手动清除 TZ 标志才能重新输出。我在后面第 5 章的排查里会再展开这两个问题。

5. PWM 输出异常排查:示波器上的五个翻车现场

这章写一些我调 PWM 时亲眼见过、也帮别人查过的故障现象。每一条都按“现象 → 原因 → 解决”的顺序整理,示波器上看到类似波形时可以对照着查。

5.1 现象:PWM 引脚一直是低电平

最常见的问题是引脚复用没配好。F280049C 的每一位 GPIO 出厂时默认是普通 IO,即使你把 EPWM 的所有寄存器都配对了,引脚没有切到复用功能,输出就是低电平。排查时先看 GPIO 控制寄存器里的 MUX 字段,确认是不是选到了对应的 EPWM 功能。另一个可能原因是外设时钟没开,EPWM 模块整个没跑起来,寄存器写什么都不生效。

解决方式:先确认 SysCtl_enablePeripheral 已调用;再用示波器量引脚电平,如果确实低电平,接着查 GPIO 复用配置。用一个最简单的例程——只配 EPWM1A 输出固定占空比——排除其他因素。

5.2 现象:频率和计算值差一倍

示波器上看到 10kHz,代码里算出来是 20kHz,这种“减半”现象几乎都是计数模式搞错了。向上-向下计数模式一个完整周期要走 2 × TBPRD 个 TBCLK,如果你按向上计数公式算周期值,又用了向上-向下模式,频率就会减半。解决方式很简单:把计数模式改成向上计数,或者把 TBPRD 减半。

另一种情况是分频参数配置错位,EPWMCLKDIV 和 CLKDIV 传反。两个参数都是 1 到 128 的分频值,传反后表面看总分频倍数没变,但以后调试时会非常迷惑。建议在代码注释里把这两个参数对应的 TBCLK 频率写清楚。

5.3 现象:占空比更新了波形不变

占空比改了但示波器上纹丝不动,最典型的原因是影子装载没触发。如果你用的是“计数器归零装载”模式,而 PWM 模块还没开始工作、计数器停在某个值上,你写进去的 CMPA 会一直待在影子寄存器里,永远不会进入工作寄存器。解决方式是先确认时基已经在跑,再查看状态寄存器里的装载标志是否被清除。

另外,有些代码会同时修改 TBPRD 和 CMPA,比如做软起动、调频调压。此时必须让两个装载点同步,否则 TBPRD 装了新值、CMPA 还在用旧值,波形会出现一个周期突然变窄或变宽。

5.4 现象:互补输出上电瞬间直通

这是最危险的一种现象:上电瞬间 EPWM1A 和 EPWM1B 同时出现高电平,功率管直接炸掉。原因通常是两个:一是死区模块配置太晚,上电时死区还没生效;二是 GPIO 在上电复位期间的默认状态和 PWM 逻辑不匹配,输出管被短暂导通。

解决方式有两个,组合用最稳。第一,把 TZ 模块配置成上电后默认强制低电平,等所有 PWM 寄存器配好、死区生效后,再由软件清除 TZ 标志释放输出。第二,在硬件上把上下桥驱动的使能引脚用电阻下拉,确保芯片复位期间驱动芯片不工作。

5.5 现象:输出波形边沿毛刺多、上升沿有回勾

波形边沿出现毛刺,很多人的第一反应是继续调代码寄存器,其实八成的边沿毛刺是硬件布局问题。PWM 引脚走线过长、门极驱动电阻过大或过小、地回路不好,都会在高低电平切换瞬间产生振铃。代码上能做的,一是检查 GPIO 的驱动强度配置,输出能力不够就换更强的驱动;二是在门极驱动信号上串联一个小电阻,减缓边沿斜率。

如果波形只是偶尔出现一个窄毛刺,还要留意是不是电流探头或示波器探头地线太长。用最短的地弹簧接地,排除测量引入的假毛刺,不要上来就怀疑芯片。

6. 从固定占空比到 SVPWM:把代码包接进电机控制链路

固定占空比的 PWM 只能让电机转起来,真正做 FOC(磁场定向控制)时,需要的是空间矢量调制(SVPWM)。SVPWM 的输入是两相静止坐标系下的电压矢量,输出是三相逆变器六个开关管的占空比组合。EPWM 部分要做的事其实很纯粹:在正确的时刻把计算出来的新占空比送到 CMPA/CMPB,并且保证装载点在一个周期的固定位置。这个工作通常放在 EPWM 周期中断里完成,中断触发点选计数器归零,正好对应 PWM 周期的起点。

__interrupt void EPWM1_ISR(void) { // 从 FOC 计算得到新的占空比 uint16_t dutyA = svpwm_calc_dutyA(); uint16_t dutyB = svpwm_calc_dutyB(); // 更新比较值,影子装载在计数器归零时生效 EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, dutyA); EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_B, dutyB); // 清除中断标志,重新使能 EPWM_clearEventTriggerInterruptStatus( EPWM1_BASE, EPWM_EVENT_TRIGGER_INTERRUPT_STATUS_ETFLG); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3); }

从 SVPWM 映射到 CMPA/CMPB 的公式本身不复杂:先把目标电压矢量转换成三相占空比,再按扇区做一次平移。EPWM 侧的难点在于时序预算——20kHz 的 PWM 周期是 50us,你需要在这段时间里完成电流采样、坐标变换、PI 调节和占空比输出。如果全部堆在中断里做,就很容易超时。我的习惯是把 FOC 算法拆成两半:一半在 EPWM 中断里做,另一半放主循环里做,利用双缓冲让数据不打架。

我自己第一次调 F280049C 的 PWM 时,死区设得太短,一个瞬间直通就烧掉了一路驱动,后来学到的教训是:上电首次输出前,先让 TZ 把输出锁住,确认示波器波形全部正常再释放。这个习惯留到现在,也替我挡过不少次故障。希望这篇笔记里的公式、代码和排查思路能帮到你,祝你的板子一次点亮。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 18:37:49

Android AIDL跨进程服务:多App共享后台状态的完整实践

简介:面向Android中高级开发者的AIDL跨进程通信实战资源,围绕如何通过AIDL定义一个共享服务,让三个独立App同时绑定并调用同一接口,解决多应用数据交换与协同操作问题。资源配套完整示例工程,包含IService.aidl接口定义…

作者头像 李华
网站建设 2026/10/15 18:37:27

CEF win64 支持 H264/H265 播放:编译配置与踩坑全解析

简介:CEF-win64版本5563是基于Chromium嵌入式框架的64位Windows构建,专为需要在应用中嵌入浏览器内核的开发者设计。该版本使用Visual Studio 2019编译,并原生支持H264与H265视频编解码,适合在线教育、直播、视频会议等视频播放场…

作者头像 李华
网站建设 2026/10/15 18:37:24

全球行政区划四级数据建模:层级血缘、质量校验与ETL落地

简介:这是一份覆盖全球范围的国家、省份与城市四级行政区划的公开关系型数据,数据结构清晰、层级对应明确,适合需要地图展示、区域统计、多级联动选择或自建业务系统的开发人员直接导入使用。资源包为单个rar压缩包,内部包含1个sq…

作者头像 李华
网站建设 2026/10/15 18:36:55

实践报告写成了“监控录像”?趣博思AI教你剪出“纪录片”

我审过不少实践报告,发现一个规律:写得最长的那个,往往得分最低。 有个学生的报告我印象很深,洋洋洒洒八千字,从早上几点到岗、中午吃了什么、下午跟谁说了什么话,事无巨细。我翻到第三页就明白了一个问题—…

作者头像 李华