C2000 DSP eHRPWM与EDMA3寄存器配置实战:电机控制与数据搬运
1. 项目概述:从寄存器到系统级数据搬运
在嵌入式系统开发,尤其是电机控制、数字电源这类对实时性和精度要求极高的领域,我们每天都在和芯片的“灵魂”打交道——寄存器。它们不是冰冷的地址和数值,而是我们与硬件对话的“语言”。通过精确地配置每一个位域,我们能让一个PWM模块输出特定频率和占空比的波形,能让一个ADC在特定时刻启动转换,也能让一个DMA控制器在后台悄无声息地搬运海量数据。
最近在调试一个基于TI C2000系列DSP的伺服驱动器项目,核心任务之一就是实现高精度、高动态响应的电流环控制。这要求eHRPWM模块产生分辨率极高的PWM信号来驱动功率器件,同时,ADC模块需要同步采样电流反馈,并通过EDMA3控制器将采样数据快速、无延迟地搬运到内存中供算法处理。整个过程环环相扣,任何一个环节的配置失误都会导致控制性能下降甚至系统失效。本文将结合实战经验,深入剖析eHRPWM关键子模块的寄存器配置逻辑,并串联起EDMA3控制器如何作为数据搬运的“幕后英雄”,协同完成这一复杂任务。无论你是正在啃芯片手册的新手,还是希望优化现有系统性能的老手,相信这些从寄存器位域到系统架构的细节解读都能带来启发。
2. eHRPWM寄存器配置深度解析
eHRPWM(Enhanced High-Resolution Pulse-Width Modulator)远不止是简单的PWM发生器。它是一个高度模块化、可配置的信号生成引擎,每个子模块都通过一组精密的寄存器来控制。理解这些寄存器,就是理解如何“雕刻”出你想要的PWM波形。
2.1 PWM斩波子模块:为驱动注入“心跳”
PWM斩波功能常被初学者忽略,但在驱动IGBT或SiC MOSFET等功率开关管时,它至关重要。其核心目的是在主PWM波中插入一个高频的“斩波”信号,用于:
- 改善门极驱动:高频斩波可以维持功率管门极电容的电荷,防止其在长脉冲期间因漏电流而意外关断,这对于需要高电平维持的驱动芯片(如某些光耦或隔离驱动器)是必要的。
- 传递状态信息:在某些多电平或复杂拓扑中,可以通过斩波信号的占空比或模式来传递额外的控制或状态信息。
斩波功能完全由PWM斩波控制寄存器控制。我们逐位拆解其配置逻辑:
CHPEN (Bit 0): 斩波使能位这是总开关。0禁用斩波,PWM信号直通;1启用斩波功能。注意:在电机控制中,通常只在需要门极维持或特定调制策略时才开启。盲目开启会增加开关损耗和EMI。
OSHTWTH (Bits 4:1): 单次脉冲宽度这个位域定义了斩波序列开始时,第一个脉冲的宽度。其单位是SYSCLKOUT/8。例如,系统时钟为200MHz,则SYSCLKOUT/8 = 25MHz,周期为40ns。设置OSHTWTH=0,则第一个脉冲宽度为1 * 40ns = 40ns。
实操心得:这个“首脉冲”通常用于在PWM周期开始时,给功率管一个更强的驱动脉冲,确保其快速、可靠地开通。在驱动大电流或高结电容的MOSFET时,适当增加此宽度(例如设为
2或3)可以改善开通特性,但需权衡开关损耗。
CHPFREQ (Bits 7:5): 斩波时钟分频它决定斩波信号的频率。公式为:斩波频率 = SYSCLKOUT / (CHPFREQ + 1)。CHPFREQ=0表示不分频,斩波频率等于系统时钟,这是最高频模式。
配置考量:斩波频率不宜过高,否则会因寄生参数导致门极振荡;也不宜过低,否则失去维持作用。经验上,对于多数IGBT驱动,选择
CHPFREQ=2或3(即除以3或4),使斩波频率在几十MHz量级,是一个不错的起点。需要在实际板级测试中观察门极波形来最终确定。
CHPDUTY (Bits 10:8): 斩波时钟占空比它控制斩波信号本身的占空比,以1/8为步进。0对应12.5%,3对应50%,7对应87.5%(注意7是保留值,通常不使用)。
避坑指南:占空比的选择与驱动芯片的输入特性相关。如果驱动芯片要求高电平维持,通常选择较高的占空比(如
5对应75%)。但要注意,过高的占空比会使斩波信号的有效高电平时间过长,可能影响主PWM的关断沿精度。务必查阅驱动芯片的数据手册,确认其推荐或可接受的维持脉冲占空比范围。
一个典型的PWM斩波配置代码示例如下(假设使用TI的DriverLib库):
// 配置eHRPWM1的斩波模块 // 使能斩波,首脉冲宽度为2个时钟单位,斩波时钟4分频,占空比50% EPWM_setChopperMode(EPWM1_BASE, EPWM_CHOPPER_MODE_ENABLED); EPWM_setChopperDutyCycle(EPWM1_BASE, EPWM_CHOPPER_DUTY_50_PERCENT); // CHPDUTY=3 EPWM_setChopperFreq(EPWM1_BASE, EPWM_CHOPPER_FREQ_4); // CHPFREQ=3 EPWM_setChopperOneShotWidth(EPWM1_BASE, 2); // OSHTWTH=2这段配置产生的效果是:在每个PWM周期开始时,先产生一个宽度为2 * (SYSCLKOUT/8)的强驱动脉冲,随后在整个PWM高电平期间,叠加一个频率为SYSCLKOUT/4、占空比为50%的高频斩波信号。
2.2 故障保护子模块:系统的“紧急制动”
故障保护是电机和电源系统的生命线。eHRPWM的故障保护子模块提供了一套硬件级别的快速响应机制,其响应速度远快于软件中断。该模块包含6个关键寄存器,构成了一个完整的“检测-动作-记录-清除”链条。
TZSEL:故障源选择寄存器这是配置的起点,决定哪些外部故障引脚(TZn)能触发保护。它分为两部分:
- OSHTn (Bits 15:8): 选择哪些引脚触发“单次”故障。一旦触发,PWM输出将锁定在预设的安全状态(高、低或高阻),直到软件明确清除故障标志。
- CBCn (Bits 7:0): 选择哪些引脚触发“逐周期”故障。触发后,PWM输出在本周期内立即采取安全动作,但在下个PWM周期开始时自动复位,如果故障信号已消失,则PWM恢复正常输出。
设计抉择:如何选择OSHT与CBC?这取决于故障的性质。对于过流、短路等致命性故障,必须使用OSHT,因为一旦发生,必须彻底关断系统,等待软件排查。对于轻微的过压或过温,可能希望系统在故障条件消失后能自动恢复,此时可以使用CBC。一个常见的策略是将硬件比较器的输出连接到OSHT引脚,将软件可编程的阈值比较器输出连接到CBC引脚。
TZCTL:故障动作控制寄存器当故障发生时,它决定PWM输出引脚(EPWMxA和EPWMxB)的具体行为。每个引脚有4种选择:
00: 高阻态。这是最常用的安全状态,因为它能同时关断上下桥臂,避免直通风险。但前提是功率驱动电路在高阻输入时能确保功率管关断。01: 强制输出高电平。10: 强制输出低电平。11: 无动作(忽略故障)。慎用!仅在调试或特殊模式下使用。
TZEINT, TZFLG, TZCLR, TZFRC:中断与状态管理寄存器组这组寄存器构成了故障事件的处理闭环:
- TZEINT:使能故障中断。你可以选择在OSHT或CBC故障发生时产生CPU中断,以便软件记录日志或进行高级处理。
- TZFLG:故障标志寄存器。硬件自动置位,指示发生了何种故障(OST/CBC)以及是否产生了中断。这是软件查询故障来源的唯一依据。
- TZCLR:故障清除寄存器。通过向对应位写
1来清除TZFLG中的标志位。关键点:对于OSHT故障,必须在清除标志位后,PWM输出才能恢复(如果TZCTL配置为高阻等动作)。对于CBC故障,标志位可能在软件清除前就被硬件在周期开始时自动清除了。 - TZFRC:软件强制故障寄存器。用于测试目的,可以模拟一个故障事件,验证整个保护链路是否工作正常。
一个完整的故障保护配置与处理流程示例如下:
// 1. 配置故障源:TZ1引脚作为OSHT故障源,TZ2引脚作为CBC故障源 EPWM_enableTripZoneSignals(EPWM1_BASE, EPWM_TZ_SIGNAL_OSHT1 | EPWM_TZ_SIGNAL_CBC2); // 2. 配置故障动作:故障时,两个PWM输出均置为高阻态 EPWM_setTripZoneAction(EPWM1_BASE, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_HIGH_Z); EPWM_setTripZoneAction(EPWM1_BASE, EPWM_TZ_ACTION_EVENT_TZB, EPWM_TZ_ACTION_HIGH_Z); // 3. 使能OSHT故障中断 EPWM_enableTripZoneInterrupt(EPWM1_BASE, EPWM_TZ_INTERRUPT_OSHT); // 4. 在中断服务函数中处理故障 __interrupt void TZ_ISR(void) { // 读取标志位,判断具体故障源 if (EPWM_getTripZoneFlagStatus(EPWM1_BASE, EPWM_TZ_FLAG_OSHT)) { // 处理OSHT故障,例如记录错误代码、关闭系统电源等 systemErrorCode = ERROR_OVERCURRENT; // 清除故障标志(否则PWM输出保持锁定状态) EPWM_clearTripZoneFlag(EPWM1_BASE, EPWM_TZ_FLAG_OSHT); // 注意:清除标志后,PWM输出是否恢复取决于TZCTL配置和当前故障引脚状态 } // ... 清除中断标志等操作 }2.3 事件触发子模块:精准的定时与同步
事件触发子模块是eHRPWM与系统其他部分(如ADC、DMA)实现硬件同步的桥梁。它允许在PWM波形的特定时刻(如计数器为零、等于周期值、等于比较器A/B值时)产生事件,用于触发ADC采样或启动一次DMA传输。
ETSEL:事件选择寄存器
- INTEN (Bit 3): 中断使能。决定是否在事件发生时产生EPWMx_INT中断。
- INTSEL (Bits 2:0): 事件源选择。这是核心配置,决定了在哪个时间点产生事件。常见选项:
1: TBCTR = 0x0000 (计数器下溢点)。常用于同步ADC在PWM周期开始时采样。2: TBCTR = TBPRD (计数器等于周期值,上溢点)。常用于对称PWM的中心对齐模式同步。4/5: TBCTR = CMPA 在递增/递减时。这是实现高分辨率占空比控制的关键,用于在比较器匹配的精确时刻触发事件,例如在空间矢量调制中精确触发ADC采样。6/7: TBCTR = CMPB 在递增/递减时。用于第二路比较事件。
ETPS:事件触发预分频寄存器它引入了“事件计数”的概念,允许每N次事件才产生一次中断或触发,用于降低CPU中断频率或实现特定的触发序列。
- INTPRD (Bits 1:0): 中断周期选择。设定需要累计多少次事件才产生一次中断。
0禁用,1每次事件都中断,2每两次事件中断一次,以此类推。 - INTCNT (Bits 3:2): 中断事件计数器。只读,显示当前已累计的事件次数。当
INTCNT等于INTPRD时,产生中断并自动清零INTCNT。
ETFLG, ETCLR, ETFRC:标志、清除与强制寄存器其功能与故障子模块的TZFLG/TZCLR/TZFRC类似,用于管理事件触发中断的状态、清除和软件强制测试。
一个典型应用是,在电机控制中,我们希望在每个PWM周期的中点(对称PWM的波谷或波峰)触发ADC采样,但每4个周期才让CPU中断一次来处理这4次采样的平均值。配置如下:
// 选择事件源:计数器等于周期值(对于增减计数模式,这就是波峰或波谷点) EPWM_setInterruptSource(EPWM1_BASE, EPWM_INT_TBCTR_U_CMP); // 设置每4个事件产生一次中断 EPWM_setInterruptEventCount(EPWM1_BASE, 4); // 使能中断 EPWM_enableInterrupt(EPWM1_BASE); // 在中断服务程序中,ETPS.INTCNT会自动从3归零,并置位ETFLG.INT __interrupt void EPWM1_ISR(void) { // 此时,我们已经积累了4个PWM周期的ADC采样数据 processAdcSamples(); // 清除中断标志 EPWM_clearInterruptFlag(EPWM1_BASE); }通过ETPS的预分频功能,我们可以将CPU从高频的、周期性的中断中解放出来,让其有更多时间执行复杂的控制算法,而ADC采样则由硬件精确同步触发,确保了采样时刻的准确性。
2.4 高分辨率PWM子模块:突破数字精度的极限
标准PWM的分辨率受限于系统时钟和计时器位数。eHRPWM的HRPWM模块通过微边沿定位技术,将PWM边沿的调节精度提升到了皮秒级。这是通过三个特殊寄存器实现的。
CMPAHR:高分辨率比较寄存器这是HRPWM的核心。在标准模式下,我们通过写入CMPA寄存器(16位)来设定比较值。在HRPWM模式下,CMPA寄存器存放粗调值(以系统时钟周期为步进),而CMPAHR寄存器(高8位)存放微调值。MEP逻辑电路会在这个“粗调”出的边沿附近,进行精细的延迟或提前,精度可以达到系统时钟周期的1/256甚至更高。
关键限制:CMPAHR的有效值范围是
0x01到0xFF。写入0x00会禁用该通道的HRPWM功能。这意味着HRPWM的微调范围大约是1个系统时钟周期。
HRCNFG:HRPWM配置寄存器这个寄存器决定了HRPWM的工作模式。
- EDGMODE (Bits 1:0): 边沿模式。选择对PWM的哪个边沿进行微调。
00: 禁用HRPWM。01: 微调上升沿。最常用,用于高分辨率占空比控制。10: 微调下降沿。11: 微调双沿。用于需要同时精确控制脉冲宽度和位置的应用。
- CTLMODE (Bit 2): 控制模式。选择由哪个寄存器提供微调值。
0: CMPAHR控制(占空比控制模式)。这是默认且最常用的模式,通过微调比较匹配点来精细控制占空比。1: TBPHSHR控制(相位控制模式)。用于微调PWM输出的初始相位,在多模块同步时非常有用。
- HRLOAD (Bit 3): 影子寄存器加载模式。选择CMPAHR影子寄存器的加载时机,必须与CMPCTL[LOADMODE]中CMPA的加载模式匹配,以确保粗调和微调值同步更新。通常设置为与CMPA相同的加载点(如CTR=PRD)。
配置与使用HRPWM的步骤:
- 确保系统时钟和ePWM时钟配置正确,且芯片支持HRPWM功能。
- 配置TBPRD和CMPA,确定PWM的基本频率和占空比(粗调)。
- 配置HRCNFG寄存器,使能HRPWM并选择边沿模式和控制模式。
- 计算所需的微调步数,写入CMPAHR寄存器。微调步数与实际时间增量的关系需要根据芯片的MEP标定因子来确定,这个因子通常存储在芯片的OTP或需要通过软件测量得到。
// 假设已配置好ePWM1的基本频率和占空比 // 1. 使能HRPWM,对EPWMxA的上升沿进行微调(占空比控制模式) EPWM_enableHighResolutionPWM(EPWM1_BASE, EPWM_HRPWM_CTRL_DUTY, EPWM_HRPWM_EDGE_MODE_RISING); // 2. 设置CMPAHR的影子寄存器在CTR=PRD时加载,与CMPA同步 EPWM_setHighResolutionLoadMode(EPWM1_BASE, EPWM_HRPWM_LOAD_ON_CNTR_ZERO); // 或 LOAD_ON_CNTR_PERIOD // 3. 计算并设置微调值。假设我们需要将边沿位置精细调整约0.5个系统时钟周期。 // MEP步长 = (系统时钟周期) / (MEP标定因子)。假设标定因子为512,则每步约2ps(在200MHz下)。 // 要调整0.5个时钟周期(2.5ns),需要的步数 = 0.5 * 标定因子 = 256。 // 由于CMPAHR范围是1-255,我们取最大值255,实现最大程度的微调。 EPWM_setHighResolutionCompareValue(EPWM1_BASE, EPWM_HRPWM_COMP_A, 255);通过HRPWM,我们可以实现极其平滑的电压调节,这在诸如LLC谐振变换器频率控制、高性能线性电源的纹波抑制等场景中具有不可替代的价值。
3. EDMA3控制器架构与工作流程
当eHRPWM精确地产生着驱动波形,ADC同步采样着电流电压,海量的采样数据如何被高效、实时地搬运到内��中,而不占用宝贵的CPU时间?这就是EDMA3的舞台。它像一个不知疲倦的、高度智能的数据搬运工,完全由硬件调度,其效率直接决定了控制系统的带宽和实时性。
3.1 EDMA3核心概念与架构总览
EDMA3控制器并非一个简单的DMA,它是一个包含通道控制器和传输控制器的复杂系统。
- EDMA3通道控制器:这是程序员的主要接口。它负责接收“搬运任务”的请求(来自外设事件或软件),管理这些任务的参数表,并对任务进行优先级排序和调度。你可以把它想象成物流公司的调度中心。
- EDMA3传输控制器:这是实际的“搬运工”。它接收来自调度中心的详细“送货单”,然后通过系统总线执行具体的数据读取和写入操作。一个EDMA3CC可以连接多个EDMA3TC,实现并行搬运。
关键术语解析:
- PaRAM:参数RAM。这是EDMA3的“任务数据库”。每个“搬运任务”(称为一个参数集)占用32字节,详细定义了源地址、目的地址、数据量、传输模式等所有信息。EDMA3CC中有128个这样的参数集入口。
- DMA通道 vs QDMA通道:两者都用于发起传输,但触发方式不同。
- DMA通道:通常由外部事件(如ADC转换完成、PWM时间到)或软件手动写入事件置位寄存器来触发。适用于周期性的、与硬件事件严格同步的数据搬运。
- QDMA通道:通过写入其关联的PaRAM参数集中的特定字来自动触发。适用于离散的、由软件发起的单次或小批量数据传输,触发效率极高。
- 传输维度:EDMA3支持三维传输,这是其强大灵活性的体现。
- A计数:单次同步传输的数据单元数(例如,一次传输连续10个16位数据)。
- B计数:A计数传输重复的次数。每次重复后,源/目标地址可以根据B索引进行偏移。
- C计数:B计数传输重复的次数。每次重复后,源/目标地址可以根据C索引进行偏移。
- 同步类型:
- A同步:每接收一个触发事件,完成一个A计数传输(即搬运A个数据单元)。
- AB同步:每接收一个触发事件,完成整个B数组的传输(即搬运A*B个数据单元)。这对于搬运一个二维数据块(如图像的一行)非常高效。
3.2 从事件到数据传输:EDMA3的完整工作流程
让我们跟随一个ADC采样数据搬运的典型场景,拆解EDMA3的工作流程:
步骤1:任务规划 - 配置PaRAM集假设我们需要将ADC结果寄存器(源地址)的数据,每次采样后自动搬运到内存中的一个数组(目的地址)。我们选择一个DMA通道,例如通道10,并将其映射到PaRAM集10。 我们需要填充PaRAM集10的8个32位字:
- 字0-1:源地址。指向ADC结果寄存器。
- 字2-3:目的地址。指向内存中的数组
adcResults[]。 - 字4:A计数和B计数。
A CNT = 1(每次触发搬一个采样值),B CNT = 16(我们想连续搬16次采样,构成一个数据块)。 - 字5:源/目的B索引。
SRC BIDX = 0(ADC结果寄存器地址固定),DST BIDX = 2(每个采样值是16位,即2字节,所以目的地址每次递增2字节)。 - 字6:链接地址、C计数等。
C CNT = 100(我们希望重复上述16次采样搬运100遍)。LINK = 0(暂时不链接到其他参数集)。 - 字7:选项字。这是配置的精华,包括:
- 传输宽度(8/16/32位)。
- 地址更新模式(递增、固定、或按索引递增)。
- 同步模式(设为A同步,即每个ADC事件触发一次传输)。
- 完成中断使能(在搬完100*16个样本后产生中断通知CPU)。
步骤2:任务派发 - 事件触发与队列
- ADC转换完成,产生一个硬件事件(例如
ADCINT1)。这个事件被映射到我们之前配置的DMA通道10。 - EDMA3CC的DMA通道逻辑检测到该事件,将其放入对应的事件队列(Queue)。每个队列深度为16,可以缓冲多个未处理的事件。
- 事件在队列中按先进先出顺序排队。如果同时有多个通道的事件,DMA通道的优先级高于QDMA通道,同类型中编号小的通道优先级更高。
步骤3:任务执行 - 传输请求提交与数据搬运
- 当通道10的事件到达队列头部时,调度逻辑读取PaRAM集10的内容,组装成一个传输请求包。
- TRP被提交给与该事件队列绑定的传输控制器。
- TC解析TRP,开始执行数据传输。它根据A/B/C计数和索引,自动计算地址,通过系统总线从ADC寄存器读取数据,写入到内存数组。整个过程完全无需CPU干预。
- 对于A同步传输,每完成一次A计数传输(即搬完一个样本),TC会等待下一个触发事件。由于我们设置了B CNT=16,所以需要16个ADC事件才能完成一个B数组(16个样本)的搬运。
步骤4:任务闭环 - 完成中断与链接
- 当整个传输(C CNT * B CNT * A CNT = 100161个样本)全部完成时,如果选项字中使能了完成中断,EDMA3CC会向CPU产生一个中断。
- 更高级的用法是链接。我们可以在PaRAM集10的链接字段中,填入另一个PaRAM集(例如集20)的地址。当集10对应的传输全部完成后,硬件会自动将集20的内容加载到当前通道的PaRAM集(覆盖集10),从而实现传输参数的自动重载。这常用于“乒乓缓冲”操作:集10将数据搬到缓冲区A,完成后自动链接到集20(将数据搬到缓冲区B),再链接回集10,如此循环。
3.3 QDMA的妙用:高效的数据初始化与搬运
与事件触发的DMA不同,QDMA的触发是“写触发”的。当你向QDMA通道关联的PaRAM集的特定字(触发字)执行一次写操作时,该QDMA传输立即被触发。
典型场景:在控制算法开始前,需要快速初始化一段内存(例如清零或填充默认值)。使用CPU循环效率低,使用DMA需要配置事件触发,而使用QDMA则异常简洁。
// 假设使用QDMA通道0,其触发字被映射到PaRAM集60的第6个字(链接地址字段) // 1. 先配置PaRAM集60:源地址指向一个包含0值的常量区,目的地址指向待清零的内存,A/B/C计数设置好。 // 2. 触发传输:只需要向触发字地址写入任意值(例如0) HWREG(QDMA_TRIGGER_WORD_ADDRESS) = 0; // 这一条写指令即触发整个数据传输优势:单次写操作即触发复杂传输,极大减少了软件开销,特别适合在中断服务程序或关键代码段中发起DMA传输。
3.4 区域访问与资源管理
在多核或复杂RTOS环境中,多个任务或核心可能都需要使用EDMA3。为了防止冲突,EDMA3引入了区域概念。通过区域寄存器,可以将DMA通道、中断等资源划分给不同的“区域”,每个区域由不同的EDMA3程序员(通常是不同的CPU核心或高权限任务)独占式管理。这提供了硬件级别的资源保护和隔离,是构建健壮多核系统的基础。
4. eHRPWM与EDMA3的协同实战:构建闭环控制系统
理论最终要服务于实践。在一个典型的电机矢量控制系统中,eHRPWM和EDMA3是如何携手工作的?
系统目标:实现三相PWM输出,同步采样两相电流,并通过DMA将采样数据送入CPU进行Park/Clark变换和PI调节。
硬件连接:
- eHRPWM1A/1B, ePWM2A/2B, ePWM3A/3B 驱动三相逆变桥。
- ADC模块采样相电流Iu和Iv(通过采样电阻或霍尔传感器)。
- ADC的转换完成信号(
ADCINT1)连接到EDMA3的事件输入。
软件配置流程:
eHRPWM配置:
- 配置时基模块为上下计数模式,产生中心对称PWM,载波频率设为20kHz。
- 配置动作限定模块,设置比较器CMPA/CMPB,生成带死区的互补PWM波。
- 关键一步:配置事件触发子模块,选择在
TBCTR = CMPA(递增或递减)时产生事件EPWMx_SOCA,并将此事件输出给ADC作为启动转换信号。这样,PWM的占空比更新点和ADC的采样点被硬件精确同步,消除了软件延迟带来的相位误差。
ADC配置:
- 配置ADC为序列采样模式,由
EPWMx_SOCA触发。 - 配置采样通道为Iu和Iv。
- 使能转换完成中断
ADCINT1,但不用于触发CPU中断,而是将其映射为EDMA3的触发事件。
- 配置ADC为序列采样模式,由
EDMA3配置:
- 分配一个DMA通道(如通道12),将其事件输入映射到
ADCINT1。 - 配置该通道对应的PaRAM集:
- 源地址:ADC结果寄存器(两个16位结果连续存放)。
- 目的地址:内存中的双缓冲区(Buffer A和Buffer B),每个缓冲区大小足以存放几十个电周期的采样点对(Iu, Iv)。
- 传输维度:A CNT=2(一次搬Iu和Iv两个值),B CNT=256(搬256对数据,填满半个缓冲区),C CNT=2(在两个缓冲区之间乒乓)。
- 同步模式:A同步(每个ADC事件触发搬一对数据)。
- 目的地址模式:B索引递增(每次搬完一对,地址+4字节),C索引设置为半个缓冲区的大小,用于在A/B缓冲区之间切换。
- 链接功能:配置两个PaRAM集(Set1和Set2),分别对应缓冲区A和B。在Set1的链接字段填入Set2的地址,Set2的链接字段填入Set1的地址,实现自动乒乓。
- 完成中断:在C计数完成(即缓冲区满)时,产生EDMA完成中断给CPU。
- 分配一个DMA通道(如通道12),将其事件输入映射到
系统运行:
- PWM开始运行,在每个周期的特定点(由CMPA决定)产生
SOCA信号。 - ADC接收到
SOCA,启动对Iu和Iv的采样转换。 - 转换完成后,ADC产生
ADCINT1事件。 - EDMA3通道12被触发,将ADC结果寄存器中的一对数据(Iu, Iv)搬运到当前活跃的缓冲区(例如Buffer A)中,并自动更新地址。
- 当Buffer A被填满(256对数据)后,EDMA3自动将参数集链接到Set2,开始向Buffer B搬运数据,同时产生一个完成中断。
- CPU在中断服务程序中,处理已经填满的Buffer A中的数据(进行坐标变换、电流环计算),并更新eHRPWM的CMPA/CMPB寄存器值,以调节PWM占空比,实现闭环控制。
- 在此期间,EDMA3继续无声无息地向Buffer B填充新的采样数据,CPU与DMA并行工作,互不阻塞。
- PWM开始运行,在每个周期的特定点(由CMPA决定)产生
通过这样的架构,ADC采样与PWM波形的同步精度达到纳秒级,数据搬运由DMA全权负责,CPU只需在缓冲区满时(频率较低,如每256个PWM周期一次)进行批处理,极大地提高了系统效率和实时性。整个控制环的延迟主要取决于算法执行时间,而数据采集和传输的延迟被降至最低。
5. 常见问题与调试技巧实录
即使理解了所有寄存器位和架构,实际调试中依然会遇到各种问题。以下是一些踩过的坑和总结出的技巧。
5.1 eHRPWM常见问题
问题1:PWM无输出或输出异常。
- 检查时钟:确认ePWM模块的时钟是否使能(
PCLKCR0/1寄存器)。没有时钟,一切皆空。 - 检查时基模式:
TBCTL寄存器中的CTRMODE是否已启动(不为00停止模式)?PHSEN是否使能了相位加载(如果需要同步)? - 检查动作限定器输出:
AQCTLA/AQCTLB寄存器是否配置了正确的动作(置高、置低、翻转)?比较器CMPA/CMPB的值是否在合理的范围内(0到TBPRD)? - 检查输出使能:
GPIO是否已正确复用为ePWM输出功能?有些芯片还需要在GPIO模块中配置输出类型(推挽、开漏等)。
问题2:HRPWM功能无效,微调不起作用。
- 确认芯片支持:并非所有C2000型号都支持HRPWM,或可能只在特定引脚上支持。
- 检查MEP标定:HRPWM的微调精度依赖于工厂预编程的MEP标定因子。你必须从芯片的OTP中读取此因子,或运行TI提供的校准程序来获取它,并在计算CMPAHR值时使用该因子。
- 检查CMPAHR值:确保写入的值在
0x01到0xFF之间。写入0x00会禁用HRPWM。 - 检查影子寄存器加载:确保
HRCNFG.HRLOAD与CMPCTL.LOADMODE的加载点匹配。如果CMPA在CTR=PRD时加载,那么CMPAHR也应该在CTR=PRD时加载。
问题3:故障保护不动作。
- 检查故障引脚映射:
TZSEL寄存器是否使能了正确的故障引脚(OSHTn/CBCn)? - 检查故障引脚极性:有些芯片的故障引脚是低电平有效,有些是高电平有效,需要检查数据手册并可能配置
GPIO或输入限定电路。 - 检查动作配置:
TZCTL寄存器是否为故障引脚配置了非“无动作”的行为? - 软件清除:对于OSHT故障,在故障条件移除后,必须向
TZCLR寄存器的对应位写1来清除故障标志,PWM输出才能恢复(如果TZCTL配置为高阻等动作)。
5.2 EDMA3常见问题
问题1:DMA传输没有启动。
- 检查事件触发:对于DMA通道,确认外部事件是否产生,或软件是否正确地写入了
ESR(事件置位寄存器)。使用ER(事件寄存器)和EMR(事件使能寄存器)来诊断事件状态。 - 检查PaRAM配置:这是最复杂的部分。逐项检查:
- 源地址和目的地址是否对齐(符合传输宽度的要求)?
- A/B/C计数是否有任何一个为0?A/B/C计数全为0的PaRAM集称为“空集”,触发会导致错误。
- 选项字中的同步类型、地址更新模式是否正确?
- 检查队列映射:
DMAQNUM寄存器是否正确地将该DMA通道映射到了一个有效的事件队列? - 检查通道使能:
EER(事件使能寄存器)是否使能了该通道?
问题2:DMA传输数据错误(错位、丢失)。
- 检查索引配置:
BIDX(B索引)和CIDX(C索引)的值计算是否正确?它们是以字节为单位指定的地址偏移量。例如,要传输一个uint32_t数组,BIDX应设为4。 - 检查传输宽度:选项字中的
SRC/DST传输宽度是否与源/目的数据的实际宽度匹配?例如,从16位ADC寄存器读取,宽度应设为16位。 - 检查地址更新模式:对于外设寄存器(如ADC结果寄存器),源地址通常应设为固定模式(不递增)。对于内存数组,目的地址通常设为递增模式。
问题3:链接功能不正常。
- 检查链接地址:PaRAM集中的链接地址字段,必须指向另一个有效的PaRAM集入口的字节地址。通常,PaRAM基地址 + 参数集编号 * 32。
- 检查链接PaRAM集内容:确保被链接的PaRAM集本身配置正确,特别是其自身的链接地址,否则可能形成死链或跳转到错误配置。
- 注意“空集”陷阱:如果一个传输完成后链接到一个所有计数都为0的“空集”,下次触发会导致传输错误。
5.3 调试技巧与工具
- 寄存器观察:在调试器中,实时观察关键寄存器是第一步。对于eHRPWM,关注
TBCTR(计数器值)、CMPA/CMPB、TZFLG、ETFLG。对于EDMA3,关注ER(事件寄存器)、IPR(中断挂起寄存器)、以及PaRAM区域的内容。 - 使用CCS的调试视图:Code Composer Studio提供了图形化的ePWM和EDMA配置视图,可以直观地检查和修改寄存器位域,比直接看十六进制值友好得多。
- 逻辑分析仪/示波器:这是验证PWM输出波形、死区时间、故障保护响应时间、以及ADC采样触发时刻同步性的终极工具。将PWM输出、故障引脚、ADC触发信号同时测量,可以清晰看到硬件时序关系。
- EDMA3调试寄存器:EDMA3CC提供了
QSTAT(队列状态)、CCSTAT(通���控制器状态)等调试寄存器,可以查看事件队列的深度、当前正在处理的通道等信息,对于诊断DMA请求是否被正确排队和处理非常有帮助。 - 从简单开始:在构建复杂的多通道、链接、乒乓缓冲之前,先配置一个最简单的单次传输DMA通道,确保能从A点搬一个数据到B点。然后再逐步增加维度、使能中断、最后实现链接。分步验证是调试复杂DMA系统的唯一捷径。
寄存器配置和DMA控制器是嵌入式系统工程师从“单片机编程”走向“硬件系统架构”必须跨越的门槛。它要求我们不仅关心软件逻辑,更要理解硬件是如何在时钟节拍下精确运作的。eHRPWM的每一个位域,EDMA3的每一个参数集,都是我们向硬件发出的精密指令。掌握它们,意味着你获得了在时间尺度和数据流层面驾驭系统的能力,从而能够构建出响应更快、效率更高、更可靠的嵌入式控制系统。这份控制力,正是嵌入式开发的精髓与乐趣所在。
