尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

TMS320F28377S ePWM模块深度解析:从基础配置到电机控制实战

TMS320F28377S ePWM模块深度解析:从基础配置到电机控制实战 1. 从零开始为什么选择TMS320F28377S做PWM控制如果你正在寻找一款能处理复杂电机控制、数字电源或者高精度信号生成的微控制器那么TI的C2000系列特别是TMS320F28377S这颗芯片大概率已经进入了你的视野。我最初接触这颗芯片也是因为一个伺服驱动器的项目当时需要实现多路高分辨率、高同步精度的PWM输出同时还要跑复杂的控制算法。市面上常见的通用MCU比如STM32F103虽然也能做PWM但在面对需要纳秒级精度同步、死区时间灵活配置、以及PWM与ADC采样严格对齐的场合时就显得有些力不从心了。而F28377S作为一款集成了双核C28x CPU和CLA协处理器的DSP其PWM模块ePWM的设计几乎就是为这类工业级应用量身定制的。简单来说PWM脉冲宽度调制就是一种用数字信号模拟模拟量的方法。通过快速开关一个方波改变其高电平导通时间占整个周期的比例即占空比就能等效输出不同的电压或电流平均值。比如占空比50%的5V方波其平均电压就是2.5V。这个原理听起来简单但在实际应用中魔鬼全在细节里。电机的换相、电源的稳压、LED的调光都对PWM的频率、分辨率、同步性和可靠性提出了苛刻要求。F28377S的ePWM模块其强大之处在于它不仅仅是一个简单的定时器加比较器。它把PWM生成的各个环节——时基、计数模式、比较动作、死区、斩波、事件触发、故障保护——都做成了高度可配置且相互联动的硬件单元。这意味着你可以在硬件层面实现很多复杂逻辑极大减轻CPU的负担让CPU能专注于更高级的算法而不是频繁地干预PWM的翻转。这对于实现高性能的实时控制系统至关重要。所以当你拿到一块F28377S的开发板想要点个灯或者让电机转起来第一步往往就是配置PWM。这篇内容我就以一个最基础的、让一个GPIO口输出固定占空比方波的任务为例带你深入F28377S的ePWM模块理解其配置逻辑并分享一些从原理图到代码调试的实战心得。这不仅是“Hello World”更是打开高性能实时控制大门的钥匙。2. 核心模块拆解ePWM的“五脏六腑”与工作流程在动手写代码之前我们必须先搞清楚F28377S的ePWM模块到底由哪些部分组成以及它们是如何协同工作的。每个ePWM模块例如ePWM1都是一个相对独立的子系统其内部结构可以清晰地分为几个功能子模块理解这个结构是进行任何高级配置的基础。2.1 时基TB子模块PWM的心脏时基子模块是整个PWM波形的节拍器。它核心是一个计数器TBCTR和一个周期寄存器TBPRD。计数器TBCTR这是核心的计时单元它的计数行为决定了PWM的波形模式。F28377S支持向上计数、向下计数以及上下计数模式。最常用的是上下计数模式计数器从0开始向上计数到周期值TBPRD然后向下计数回0如此循环。这种模式能产生中心对称的PWM波形非常适合电机控制因为它能减少谐波分量。周期寄存器TBPRD这个寄存器定义了PWM的周期。计数器的计数范围由它决定。PWM的频率计算公式为PWM频率 系统时钟频率 / (TBPRD * 2)在上下计数模式下。例如系统时钟200MHz想要100kHz的PWM那么TBPRD 200MHz / (100kHz * 2) 1000。相位与同步时基模块还支持相位寄存器TBPHS和同步输入/输出信号。这允许多个ePWM模块的计数器从同一个起点开始计数或者让一个模块的计数器跟随另一个模块的计数器实现多路PWM的严格同步。在驱动三相逆变桥时这个功能必不可少。2.2 计数比较CC子模块决定占空比比较子模块是PWM的“雕刻刀”。它包含两个比较寄存器CMPA和CMPB有些模块还有CMPC和CMPD。在计数器TBCTR运行过程中硬件会实时将其值与CMPA/CMPB进行比较。比较匹配当TBCTR的值等于CMPA时就会触发一个“比较匹配A”事件等于CMPB时触发“比较匹配B”事件。这些事件是后续动作的源头。占空比计算在上下计数模式下PWM的占空比由比较寄存器的值决定。对于一个通道例如ePWMxA其高电平时间对应于计数器值小于比较寄存器值的时间。具体逻辑由动作限定器AQ子模块根据事件来定义。占空比 (CMPA / TBPRD) * 100%。如果你设置CMPA TBPRD / 2那么就会得到50%占空比的对称波形。2.3 动作限定器AQ子模块波形的“导演”动作限定器是连接“事件”和“输出动作”的桥梁。它接收来自时基和比较子模块的事件如“计时器等于0”、“计时器等于周期值”、“比较匹配A”等并根据配置的规则控制ePWM输出引脚ePWMxA和ePWMxB的电平。核心动作主要包括“置高”、“置低”、“翻转”。例如最常见的配置是在“计时器等于0”事件时将ePWMxA输出置为高电平在“比较匹配A”事件时将其置为低电平。这样在上下计数模式下就会产生一个从周期开始处高电平在CMPA点变低电平的脉冲。灵活性AQ模块允许你为同一个事件在不同的计数方向向上或向下定义不同的动作。这为实现更复杂的PWM波形如带死区的互补PWM提供了可能。2.4 死区DB子模块硬件安全锁在驱动半桥或全桥电路时我们绝不允许上下两个开关管如MOSFET同时导通否则会造成直通短路瞬间烧毁器件。死区子模块就是为了防止这种情况而生的硬件安全机制。工作原理DB模块位于AQ模块的输出之后。它接收AQ产生的原始PWM信号通常称为EPWMxA和EPWMxB然后通过可配置的延时电路生成两路带死区时间的互补信号。具体来说它可以在上升沿或下降沿插入延时确保在一路信号关闭后另一路信号要经过一段死区时间才会开启。这段时间保证了开关管有足够的关断时间。关键参数死区时间通常以系统时钟周期为单位进行配置。需要根据你所使用的开关管MOSFET或IGBT的开关特性特别是关断时间来谨慎设定一般在几百纳秒到几微秒之间。2.5 故障保护TZ子模块紧急刹车系统这是ePWM模块最重要的安全特性之一。它允许外部故障信号如过流、过压、过热直接通过特定的GPIO引脚TZn输入无需CPU干预即可强制将ePWM输出置为安全状态高电平、低电平或高阻态。工作模式分为周期性和单次触发。周期性模式下故障信号有效期间PWM输出一直被钳位在安全状态单次触发模式下一旦触发需要软件手动清除标志位才能恢复输出。重要性在电机驱动和电源应用中响应速度是保护系统的关键。软件检测故障并处理存在延迟而TZ模块的硬件响应是纳秒级的能最大程度避免灾难性后果。这也是F28377S这类工业级芯片与消费级MCU的一个重要区别。2.6 事件触发ET子模块精准的定时“闹钟”ET模块允许ePWM模块在特定的时间点如计数器等于0、等于周期值、等于CMPA/CMPB时向CPU或CLA发出中断请求或者启动ADC进行采样。与ADC的联动这是实现高性能控制的核心。例如你可以在PWM波形的谷底计数器0或峰值计数器TBPRD触发ADC对电机相电流进行同步采样这样可以避开开关噪声获得最准确的电流值。F28377S的ePWM模块可以非常精确地控制这个触发时刻。中断管理ET模块可以配置在多个时间点产生中断让CPU有机会在PWM周期的关键节点执行控制算法更新比较寄存器值等操作。理解了以上六个子模块你就掌握了ePWM的“地图”。接下来我们就可以根据这张地图开始我们的第一个实战任务配置一路简单的PWM输出。3. 实战第一步搭建开发环境与初始化配置理论已经足够现在让我们动手让一个GPIO口输出PWM波。我假设你使用的是TI官方的ControlSUITE或最新的C2000Ware库以及Code Composer Studio (CCS)开发环境。这里我以CCS v10以上版本和C2000Ware为基础进行说明。3.1 创建工程与引脚复用配置首先创建一个新的CCS工程选择正确的器件型号TMS320F28377S。TI提供了丰富的例程但为了彻底理解我们从最基础的配置开始。第一步是配置引脚功能。F28377S的GPIO引脚功能非常灵活需要通过寄存器配置将其映射到ePWM模块。我们假设使用ePWM1的A通道EPWM1A它可能对应多个物理引脚如GPIO0。我们需要在代码中初始化这个引脚为ePWM功能。在C2000Ware的驱动库中通常会有一个Device_initGPIO()或类似的函数但更细粒度的控制需要直接操作寄存器或使用库函数。一个典型的配置顺序如下使能ePWM1时钟虽然上电后外设可能默认有时钟但显式使能是个好习惯。通过设置PCLKCR0寄存器的相应位来完成。配置GPIO复用功能这是关键一步。找到EPWM1A对应的引脚例如GPIO0需要设置GPyPUD寄存器禁止上拉根据电路设计决定。GPyGMUXn和GPyMUXn寄存器这两个寄存器共同决定引脚的复用功能。对于ePWM输出通常需要将GPyMUXn设置为特定的“功能1”或“功能2”具体数值需要查阅芯片的数据手册Datasheet或技术参考手册TRM中的“Pin Multiplexing”表格。例如将GPIO0配置为EPWM1A可能需要写GPIO0_MUX 1。GPyDIR寄存器设置为输出模式虽然复用为外设功能后方向通常自动管理但初始化时设为输出更稳妥。GPyQSELn寄存器配置输入限定器对于输出引脚通常不需要可以忽略或设为异步模式。注意引脚复用配置是新手最容易出错的地方之一。务必、务必、务必对照官方数据手册的引脚功能表来操作。不同封装的芯片引脚映射可能不同。一个错误的功能选择会导致没有波形输出而排查起来又很隐蔽。3.2 ePWM1模块的初始化代码详解配置好引脚后我们就可以开始初始化ePWM1模块本身了。下面是一段基于寄存器直接操作的初始化代码并附上详细注释。我们目标是产生一个频率为10kHz占空比为30%的中心对称PWM波。// 假设系统时钟 SYSCLKOUT 200 MHz #define PWM_FREQ_HZ 10000 // 10 kHz #define PWM_DUTY_PERCENT 30 // 30% 占空比 void InitEPwm1(void) { // 1. 配置时基 (TB) 子模块 // 停止时基计数器方便配置 EPwm1Regs.TBCTL.bit.CTRMODE TB_COUNT_UPDOWN; // 设置为上下计数模式 EPwm1Regs.TBCTL.bit.PHSEN TB_DISABLE; // 禁止相位加载单模块运行无需同步 EPwm1Regs.TBCTL.bit.PRDLD TB_SHADOW; // 周期寄存器使用影子寄存器模式缓冲 EPwm1Regs.TBCTL.bit.SYNCOSEL TB_SYNC_DISABLE; // 同步输出选择禁止主模块 // 计算周期值。公式PWM频率 SYSCLKOUT / (TBPRD * 2) // 因此 TBPRD SYSCLKOUT / (PWM频率 * 2) Uint16 period (Uint16)(200000000L / (PWM_FREQ_HZ * 2)); // 200MHz / (10k*2) 10000 EPwm1Regs.TBPRD period; // 将计算值写入活跃寄存器 // 2. 配置计数比较 (CC) 子模块 EPwm1Regs.CMPCTL.bit.SHDWAMODE CC_SHADOW; // CMPA使用影子寄存器 EPwm1Regs.CMPCTL.bit.SHDWBMODE CC_SHADOW; // CMPB使用影子寄存器 EPwm1Regs.CMPCTL.bit.LOADAMODE CC_CTR_ZERO; // 在计数器0时加载影子寄存器值到活跃寄存器 EPwm1Regs.CMPCTL.bit.LOADBMODE CC_CTR_ZERO; // 同上 // 计算比较值。占空比 CMPA / TBPRD // 因此 CMPA TBPRD * 占空比 // 注意在上下计数模式下这个计算产生对称PWM。对于非对称PWM逻辑会不同。 Uint16 cmpAValue (Uint16)((period * PWM_DUTY_PERCENT) / 100); EPwm1Regs.CMPA.half.CMPA cmpAValue; // 写入CMPA影子寄存器 // 3. 配置动作限定器 (AQ) 子模块 // 我们希望在计数器0时将EPWM1A置高在计数器CMPA时向上计数过程中将EPWM1A置低。 // 在向下计数过程中当计数器再次等于CMPA时我们不做动作这样就会在下一个周期开始时再次置高。 EPwm1Regs.AQCTLA.bit.ZRO AQ_SET; // 计数器0时置高 EPwm1Regs.AQCTLA.bit.CAU AQ_CLEAR; // 向上计数且等于CMPA时置低 // 注意这里没有配置CAU向下计数等于CMPA的动作所以输出保持低电平直到周期结束。 // 4. 配置死区 (DB) 子模块本例为单路输出暂不启用死区 EPwm1Regs.DBCTL.bit.OUT_MODE DB_DISABLE; // 完全禁用死区模块信号直通 // 5. 配置故障保护 (TZ) 子模块本例暂不启用但建议初始化时将其禁用 EPwm1Regs.TZSEL.bit.OSHT1 0; // 不选择任何TZn引脚作为单次触发故障源 EPwm1Regs.TZCTL.bit.TZA TZ_FORCE_HI; // 即使故障发生对EPWM1A的操作强制高可根据需要改为低或高阻 // 更安全的做法是设置为 TZ_FORCE_LO 或 TZ_HIZ取决于你的功率桥驱动逻辑。 // 6. 配置事件触发 (ET) 子模块本例暂不启用中断 EPwm1Regs.ETSEL.bit.INTEN 0; // 禁止中断产生 // 7. 启动计数器 EPwm1Regs.TBCTL.bit.CTRMODE TB_COUNT_UPDOWN; // 再次确认模式虽然前面设过 // 实际上CTRMODE在第一步已经设置这里只是强调。计数器会立即开始运行。 }这段代码完成后理论上EPWM1A引脚就应该输出10kHz占空比30%的PWM波了。但“理论上”和“实际上”往往有差距这就需要我们进行调试和验证。4. 调试与验证示波器上的波形与常见问题排查代码写好了下载到开发板接上示波器探头结果可能是一片寂静没有波形或者波形完全不对。别慌这是学习过程中最宝贵的环节。下面是我总结的一套排查流程和常见坑点。4.1 基础排查清单时钟确认首先确保系统时钟配置正确。你的SysCtrl初始化代码是否真的将系统时钟SYSCLKOUT设置为了你计算时假设的200MHz一个简单的验证方法是点一个LED用延时函数闪烁估算一下时间是否大致符合预期。或者可以输出一个已知频率的PWM比如1Hz到GPIO用示波器测量。引脚连接与配置物理连接探头地线夹好了吗探头接触点是否氧化尝试测量一个已知是3.3V的电源引脚确认示波器和探头工作正常。复用功能回头检查GPyMUXn寄存器的配置值。这是最高频的错误源。确认你配置的引脚编号和复用功能选项与数据手册中“EPWM1A”的标注完全一致。有时同一个ePWM输出可能对应两个不同的引脚你需要选择其中一个并正确配置。输出使能确认GPIO方向寄存器GPyDIR相应位被设置为1输出。虽然复用后可能自动管理但手动设置为输出更可靠。ePWM模块使能确认外设时钟控制寄存器PCLKCR0中对应ePWM1的时钟使能位被置1。有些例程的InitSysCtrl()函数可能默认只使能了部分外设时钟。寄存器配置顺序与影子寄存器注意我们配置的是影子寄存器如CMPA.half.CMPA。它的值会在特定事件如计数器为零时才加载到活跃寄存器真正生效。如果你配置了LOADAMODE为CC_CTR_ZERO那么你需要确保计数器至少经过一个完整的周期从0到PRD再回到0新的比较值才会生效。在调试时可以在初始化后加一个短暂延时或者直接读取活跃寄存器CMPA.half.CMPAHR如果支持来确认值已加载。4.2 示波器测量与波形分析当有波形输出后用示波器测量以下关键参数并与你的配置进行比对频率测量一个完整周期的时长T频率f1/T。它应该等于你设定的10kHz即周期100us。如果不符检查TBPRD的计算公式和系统时钟频率。占空比测量高电平时间Ton与周期T的比值。它应该接近30%。如果不符检查CMPA值的计算以及AQ动作配置是否正确。特别注意在上下计数模式下如果你只在CAU向上计数匹配时清除而在CAD向下计数匹配时没有设置动作那么占空比确实是CMPA/TBPRD。但如果你错误地在CAD也配置了AQ_SET就会得到一个完全不同的波形对称的脉冲。幅值应该是3.3V芯片IO电压。如果幅值过低检查板子供电和负载。直接驱动LED测试是很好的方法。上升/下降沿观察边沿是否干净陡峭。如果边沿缓慢可能是负载过重如直接驱动大功率LED未加三极管或者探头阻抗影响使用10X探头。4.3 进阶问题为什么我的PWM输出不稳定或偶尔跳动如果波形基本正确但偶尔有毛刺或周期跳动可以考虑以下原因中断干扰你的程序是否开启了其他高优先级中断并且在该中断服务函数中执行了耗时很长的操作这可能会打断PWM周期计数器运行的时序虽然概率极低因为ePWM是硬件独立运行但如果中断函数里进行了大量计算或全局变量访问可能导致CPU无法及时响应ePWM本身的事件中断如果你开启了的话造成控制环路延迟。确保中断服务函数尽可能短小精悍。影子寄存器更新冲突如果你在程序运行中动态更新CMPA或TBPRD比如实现调光或调速必须注意更新时机。最佳实践是在计数器等于0或等于周期值的时刻进行更新以避免在一个PWM周期中间产生“毛刺”波形。这就是为什么我们配置LOADAMODE CC_CTR_ZERO的原因。在中断服务函数中更新比较值时确保你写的是影子寄存器。电源噪声对于电机驱动等大电流应用功率部分的噪声可能会耦合到芯片的电源或地线上导致数字逻辑出错。确保你的开发板或自制PCB有良好的电源去耦在芯片电源引脚附近放置0.1uF和10uF的电容并且数字地和功率地单点连接。4.4 利用CCS的寄存器观察窗和图形化工具CCS提供了强大的调试功能寄存器观察窗在调试视图中添加EPwm1Regs到观察窗口。你可以实时查看所有ePWM寄存器的值特别是TBCTR计数器看它是否在0和TBPRD之间循环。这比示波器更直观地确认计数器在工作。CPU寄存器查看确认PCLKCR0等时钟控制寄存器的值。内存观察窗可以查看代码中计算出的period和cmpAValue变量的实际值确保计算无误。通过以上步骤你应该能成功让F28377S输出一个干净、稳定的PWM波。这只是一个起点。ePWM模块的真正威力在于将这些基础功能组合起来去解决复杂的实际问题。5. 从单路到互补PWM驱动一个半桥电路掌握了单路PWM后一个很自然的进阶就是驱动一个半桥电路例如一个高边和一个低边MOSFET。这需要用到同一个ePWM模块的两个输出通道EPWMxA和EPWMxB并引入死区保护。5.1 互补PWM与死区配置原理在半桥中EPWMxA和EPWMxB需要输出互补的波形当A为高时B为低反之亦然。但为了防止直通必须在开关切换之间插入一段两者都为低的时间这就是死区时间。在F28377S中实现这个功能主要依靠**动作限定器AQ和死区DB**子模块的配合。一种常见的配置思路是AQ模块配置产生一个原始的、不带死区的互补信号。例如让EPWMxA在计数器0时置高在比较匹配时置低让EPWMxB与之相反在计数器0时置低在比较匹配时置高。这样我们就得到了两路理想的、互补但瞬间切换的PWM信号。DB模块接收AQ输出的这两路原始信号EPWMxA和EPWMxB对它们的上升沿或下降沿进行延时生成最终带死区的两路输出信号。DB模块有几种工作模式最常用的是“有效高互补模式”。在这种模式下你可以独立设置上升沿延时RDLY和下降沿延时FDLY。通常我们会对EPWMxA和EPWMxB的上升沿插入延时确保在任何一个信号从低变高之前另一个信号已经保持低电平一段时间即死区时间。5.2 代码实现与关键配置假设我们仍然使用ePWM1现在要配置EPWM1A和EPWM1B为带死区的互补PWM。void InitEPwm1ForComplementaryWithDeadband(void) { // 时基和比较模块配置与单路相同 EPwm1Regs.TBCTL.bit.CTRMODE TB_COUNT_UPDOWN; EPwm1Regs.TBPRD 10000; // 仍以10kHz为例 EPwm1Regs.CMPA.half.CMPA 3000; // 30%占空比 // 1. 配置AQ模块产生原始互补信号 // 对于EPWM1A: 0时刻置高 CAU时刻置低 EPwm1Regs.AQCTLA.bit.ZRO AQ_SET; EPwm1Regs.AQCTLA.bit.CAU AQ_CLEAR; // 对于EPWM1B: 我们希望它与A互补。所以0时刻置低 CAU时刻置高。 EPwm1Regs.AQCTLB.bit.ZRO AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CAU AQ_SET; // 注意这里我们只处理了向上计数匹配CAU。向下计数匹配CAD时没有动作波形会自然对称。 // 2. 关键配置死区DB模块 EPwm1Regs.DBCTL.bit.OUT_MODE DB_FULL_ENABLE; // 使能死区发生器对A和B通道都生效 EPwm1Regs.DBCTL.bit.POLSEL DB_ACTV_HI; // 选择输出极性为高有效这是最常见的 // DBCTL.bit.IN_MODE 通常保持默认表示死区输入源就是本模块的EPWMxA和EPWMxB。 // 设置死区时间。假设系统时钟200MHz一个时钟周期5ns。 // 我们希望插入200ns的死区时间。200ns / 5ns 40个时钟周期。 Uint16 deadband_clocks 40; EPwm1Regs.DBRED deadband_clocks; // 上升沿延时对于EPWMxA是上升沿延时 EPwm1Regs.DBFED deadband_clocks; // 下降沿延时对于EPWMxA是下降沿延时 // 在“有效高互补模式”下DBRED和DBFED的具体作用对象由POLSEL和OUT_MODE共同决定。 // 简单理解这个配置会在EPWMxA和EPWMxB的上升沿都插入延时防止同时导通。 }配置完成后用示波器同时测量EPWM1A和EPWM1B引脚。你应该看到两路互补的方波并且在每次电平跳变特别是从低到高时能看到一个短暂的两路都为低电平的“死区”窗口。用示波器的光标功能可以精确测量这个时间它应该接近你设定的200ns。重要经验死区时间的设置需要根据你实际使用的MOSFET或IGBT的开关特性来定。太短起不到保护作用太长则会降低有效输出电压增加损耗。务必查阅器件数据手册中的“关断延迟时间td(off)”和“下降时间tf”参数并留有一定裕量。通常可以先设置一个保守值如500ns-1us待系统正常工作后再逐步优化。6. 高级应用基石事件触发与ADC同步采样ePWM模块不仅仅是输出它还是整个控制系统时序的“指挥官”。其中最强大的功能之一就是精确触发ADC采样。在电机控制中为了获得准确的相电流进行FOC磁场定向控制运算必须在PWM波形的特定点通常是开关管导通的中间点或PWM周期中心进行采样以避开开关噪声。6.1 配置ePWM触发ADCF28377S的ePWM模块可以通过事件触发ET子模块在计数器到达特定位置时产生一个SOCStart-of-Conversion脉冲信号给ADC模块。void InitEPwm1ForADCTRIG(void) { // ... 时基、比较、AQ等基础配置与之前相同 ... // 配置事件触发ET子模块 // 我们希望在每个PWM周期的开始计数器0和中间点计数器TBPRD触发ADC采样。 // 假设我们使用ADCINA0通道采样电流。 // 1. 选择触发源 EPwm1Regs.ETSEL.bit.SOCAEN 1; // 使能SOCAStart-of-Conversion A触发 EPwm1Regs.ETSEL.bit.SOCASEL ET_CTR_ZERO; // 设置SOCA的触发事件为计数器等于零 (TBCTR 0) // 还可以配置SOCB例如在计数器等于周期值时触发 // EPwm1Regs.ETSEL.bit.SOCBEN 1; // EPwm1Regs.ETSEL.bit.SOCBSEL ET_CTR_PRD; // 2. 设置触发分频如果需要 EPwm1Regs.ETPS.bit.SOCAPRD ET_1ST; // SOCA在每个选定事件都产生触发脉冲1:1分频 // ET_2ST 表示每两个事件触发一次以此类推。 // 3. 在ADC模块中配置相应的SOC例如SOC0的触发源为 ePWM1_SOCA // 这部分代码通常在ADC初始化函数中。例如 // AdcaRegs.ADCSOC0CTL.bit.CHSEL 0; // 选择ADCINA0通道 // AdcaRegs.ADCSOC0CTL.bit.TRIGSEL 10; // 10 通常代表 ePWM1_SOCA (具体值查TRM) // AdcaRegs.ADCSOC0CTL.bit.ACQPS 15; // 采样窗口大小 }这样每当ePWM1的计数器归零就会自动触发一次ADC对通道A0的采样。ADC转换完成后会产生一个中断你可以在中断服务程序中读取转换结果用于电流环计算。6.2 同步采样与PWM更新策略为了实现高性能的实时控制采样、计算和PWM更新必须在同一个控制周期内紧密配合。一个典型的时序是PWM周期开始(TBCTR0)触发ADC采样电流/电压。ADC转换完成(稍后)产生中断CPU/CLA进入中断服务程序。中断服务程序中读取ADC结果运行控制算法如PID、FOC计算出新的PWM占空比即新的CMPA值。更新PWM将新的CMPA值写入其影子寄存器。PWM周期中点(TBCTRTBPRD)影子寄存器的值被加载到活跃寄存器新的占空比在下半个周期或下一个完整周期生效。这种“影子寄存器”机制是实现无毛刺、平滑更新PWM的关键。你可以在中断服务程序中的任何时间安全地更新CMPA影子寄存器而硬件会在你预设的加载点如计数器为零自动同步更新避免了在PWM周期中间改变比较值可能造成的脉冲宽度异常。我个人在电机控制项目中的体会是将ADC采样点设置在PWM波形的“中心点”或“谷底”对于上下计数模式两者是同一时刻即TBCTR0或TBCTRTBPRD可以有效避开功率管开关瞬间产生的巨大毛刺获得最稳定的采样值。同时将控制算法的计算量优化到能在ADC中断中完成是保证系统实时性的核心。如果计算量太大可以考虑使用F28377S的CLA控制律加速器协处理器来并行处理。
返回列表