1. 项目概述与核心价值
在嵌入式电机控制,尤其是无刷直流(BLDC)电机驱动的世界里,一个看似微小的时序细节——死区时间(Dead-Band)——往往是决定系统成败的关键。新手工程师常常困惑,为什么明明PWM波形逻辑正确,电机驱动板却莫名其妙地发热、冒烟甚至烧毁功率管。其根源往往在于忽略了功率开关管(如MOSFET或IGBT)的开关并非理想瞬间完成,存在导通延迟和关断延迟。如果控制同一桥臂上下两个开关管的互补PWM信号没有足够的“安全间隔”,就会发生可怕的“直通(Shoot-Through)”现象,即上下管同时导通,形成从电源到地的低阻通路,瞬间产生大电流,轻则导致效率骤降、发热严重,重则直接损毁硬件。
因此,死区插入功能是现代电机控制MCU中定时器模块的“标配”高级功能。它通过在互补的PWM信号之间自动插入一段可控的延迟,强制确保一个开关管完全关断后,另一个才被允许导通,从而从硬件层面杜绝直通风险。德州仪器(TI)的CC35xx系列无线MCU,虽然主打无线连接,但其内置的通用定时器(GPT)模块在电机控制方面同样功能强大,提供了完整的死区插入、故障保护(Fault)和停车(Park)机制。
本文将以CC35xx的GPT模块为例,不仅深入解析其死区插入的工作原理、寄存器配置的每一个比特,更会结合一个完整的三相BLDC电机六步换相驱动实例,手把手带你从理论走到实践。你会看到如何将三个GPT通道配置成三对带死区的互补PWM输出,如何通过软件在恰当的时机切换相位,以及如何处理紧急故障信号。无论你是正在评估CC35xx用于电机控制项目,还是希望深入理解嵌入式定时器的死区机制,这篇文章都将提供可直接“抄作业”的详细指南和避坑经验。
2. 死区插入功能深度解析
死区插入,本质上是一种对参考PWM信号进行“整形”的逻辑。GPT模块在检测到系统支持死区功能(SYS_HDBF=1)后,可以将一路参考PWM信号(例如OUT0),生成两路频率相同但相位上存在固定延迟的互补信号:IO[n]和IO_C[n](n代表通道号,如0, 1, 2)。这段插入的延迟时间就是“死区”,在这段时间内,两路输出都处于无效状态(通常为低电平),为功率器件的状态切换留出安全窗口。
2.1 死区时序生成机制
CC35xx GPT的死区逻辑非常直观,其核心由两个寄存器控制:DBDLY.RISEDLY(上升沿延迟)和DBDLY.FALLDLY(下降沿延迟)。这里的“上升沿”和“下降沿”是针对参考信号OUTn而言的。
RISEDLY(上升沿延迟):当参考信号OUTn发生上升沿时,IO[n]信号的上升沿将被延迟,而IO_C[n]信号的下降沿将被延迟。延迟的时间为(RISEDLY + 1)个系统时钟周期。FALLDLY(下降沿延迟):当参考信号OUTn发生下降沿时,IO[n]信号的下降沿将被延迟,而IO_C[n]信号的上升沿将被延迟。延迟的时间为(FALLDLY + 1)个系统时钟周期。
为什么是+1?这是硬件逻辑设计使然。寄存器值N代表插入N+1个时钟周期的延迟。例如,设置RISEDLY = 4,则实际延迟为5个系统时钟周期。设计时需要将这个+1考虑进你的时间计算中。
此外,文档明确指出,由于死区插入逻辑本身会引入一个系统时钟周期的延迟,因此IO和IO_C信号相对于原始OUT信号,整体上还会额外延迟一个时钟周期。在计算最坏情况下的开关时序时,这个固定延迟也需要纳入考量。
2.2 关键限制与“陷阱”
手册中的两条Note至关重要,是配置时必须遵守的“军规”:
RISEDLY过长:如果配置的RISEDLY值大于或等于参考信号OUTn的高电平脉冲宽度,会导致IO输出恒定为低电平。这是因为IO的上升沿被延迟到了其下一个下降沿之后,导致其有效高电平宽度为0。FALLDLY过长:如果配置的FALLDLY值大于或等于参考信号OUTn的低电平脉冲宽度,会导致IO_C输出恒定为低电平。原理同上,IO_C的上升沿(对应OUTn下降沿)被过度延迟。
实操心得:在动态调整PWM占空比的应用中(如电机调速),必须确保在任何占空比下,高电平和低电平的宽度都大于你设置的最大死区时间。例如,系统时钟为80MHz,每个周期12.5ns。若设置RISEDLY = FALLDLY = 79,则死区时间为(79+1)*12.5ns = 1us。那么,你的PWM信号的高电平和低电平宽度必须始终大于1us,这对应着PWM周期不能太短,或者极端占空比(接近0%或100%)需要特殊处理。
2.3 基础配置流程示例
假设我们需要在通道0上启用死区插入,生成IO[0]和IO_C[0]。以下是基于手册的配置步骤,我补充了具体的寄存器操作和思考逻辑:
配置PWM输出:首先,需要让GPT的通道0产生一个基础的PWM信号作为参考。这通常通过配置通道0的捕获/比较动作(
C0CFG.CCACT)为0xB(在零点置位,在比较点翻转)或0xA(在零点清零,在比较点翻转),并设置好目标值(TGT,决定频率)和比较值(C0CC,决定占空比)。同时,使能通道0控制输出0(C0CFG.OUT0 = 1)。这一步是生成OUT0信号。// 假设使用向上计数模式(UP_PER)生成边沿对齐PWM GPT->C0CFG.OUT0 = 1; // 通道0控制输出0 GPT->C0CFG.CCACT = 0xB; // Set on zero, toggle on compare repeatedly (边沿对齐PWM) GPT->TGT = period_ticks - 1; // PWM周期 = (period_ticks) * 定时器时钟周期 GPT->C0CC = duty_ticks; // 比较值,决定占空比设置死区延迟:根据你选用的功率器件规格(查看其数据手册中的
t_d(off)关断延迟和t_d(on)导通延迟),计算所需的安全死区时间,并转换为系统时钟周期数,填入DBDLY寄存器。记住公式:寄存器值 = (所需死区时间 / 系统时钟周期) - 1。// 假设系统时钟 SysClk = 80MHz,周期为12.5ns // 要求死区时间 DeadTime = 1us uint32_t sysclk_cycles_needed = 1000ns / 12.5ns = 80; uint32_t reg_value = sysclk_cycles_needed - 1; // 因为硬件会+1 GPT->DBDLY.RISEDLY = reg_value; // 设置为79 GPT->DBDLY.FALLDLY = reg_value; // 设置为79,通常上升下降延迟设相同值启用死区生成:通过
DBCTL寄存器,指定对哪个通道的参考信号进行死区处理。GPT->DBCTL.IO0 = 1; // 对IO0/IO_C0启用死区插入启动定时器:最后,配置定时器控制寄存器
CTL,选择工作模式(如MODE = UP_PER)并启动定时器。GPT->CTL.MODE = 2; // 设置为UP_PER(向上计数周期模式)
完成以上步骤后,IO[0]和IO_C[0]引脚上就会输出带死区的互补PWM信号,可以直接连接到半桥驱动器的输入。
3. 故障与停车状态下的死区保持策略
在电机驱动中,安全至高无上。除了正常的PWM生成,GPT还提供了**故障(Fault)和停车(Park)**功能,用于在过流、过压等异常情况下快速关断输出,将电机置于安全状态。但这里有一个关键问题:当系统因故障或调试命令进入“Park”状态时,输出会被强制拉到一个预设的安全电平(高或低)。如果IO和IO_C的Park状态是互补的(一个高一个低),那么直接切换不会导致直通,这与正常PWM操作类似。但如果它们的Park状态相同(例如都需要拉低以关闭所有桥臂),直接切换就可能有���题。
3.1 非互补Park状态的切换难题
设想一个场景:发生故障时,我们需要将三相桥臂的所有高侧和低侧开关管全部关断,即IO[0],IO_C[0],IO[1],IO_C[1],IO[2],IO_C[2]全部Park到低电平。如果从正常的带死区PWM状态直接切换到全低Park状态,在切换瞬间,IO和IO_C可能同时为低,这看起来安全,但硬件切换路径可能绕过死区逻辑,存在理论上的风险。
3.2 GPT的智能切换逻辑
CC35xx的GPT硬件提供了一种优雅的解决方案,确保即使在Park状态相同时,切换过程也严格遵守死区插入原则。其核心思想是分步锁定和参考信号切换:
- 立即锁定参考信号:当Park被激活(由故障或调试信号触发)时,死区逻辑的参考输入信号
OUTn会立即被设置为IO的Park状态。假设Park状态是低电平,OUTn立即变低。 - 延迟并锁定IO输出:由于
OUTn变低,经过FALLDLY延迟后,IO输出会变为低电平(Park状态)。一旦IO输出达到Park状态,硬件会将其“锁定”,意味着后续参考信号的变化不再影响IO输出。此时,IO已安全进入Park状态。 - 切换参考并设置IO_C:在
IO被锁定的同时,死区逻辑的参考信号被切换到IO_CPark状态的反相。如果IO_C的Park状态也是低,那么参考信号就被切换为高。这个高电平的参考信号,再经过RISEDLY延迟,会使IO_C输出变为低电平(Park状态)。 - 完成切换:由于
IO已被锁定,第二步中参考信号从低变高的变化不会影响它。最终,IO和IO_C都安全地进入了低电平Park状态,且两者之间的状态切换依然通过死区逻辑进行了隔离。
这个过程保证了从任何状态切换到Park状态,IO和IO_C都不会出现同时导通的风险。手册给出了切换时间的计算公式:
- 当
IO和IO_C的Park状态相反时,切换时间为max(FALLDLY, RISEDLY) + 1个周期。 - 当
IO和IO_C的Park状态相同时,切换时间为(FALLDLY + RISEDLY + 2)个周期。
注意事项:在计算系统故障响应时间时,必须将这个额外的切换延迟考虑进去。如果你的应用对故障响应时间有严格要求(例如在数微秒内必须关断),那么就需要权衡死区时间的大小和Park切换时间。
4. BLDC电机六步换相驱动实战
理解了死区、故障和Park机制后,我们来看一个完整的应用:用CC35xx的GPT驱动一个三相BLDC电机。这是GPT高级功能的一个经典综合应用。
4.1 硬件连接与驱动拓扑
我们使用一个典型的三相全桥逆变电路。六个功率管(Q0-Q5)组成三个半桥,分别驱动电机的A、B、C三相。CC35xx GPT的三个通道(0, 1, 2)正好对应三对互补PWM输出:
IO[0]和IO_C[0]控制半桥A(Q0高侧, Q1低侧)IO[1]和IO_C[1]控制半桥B(Q2高侧, Q3低侧)IO[2]和IO_C[2]控制半桥C(Q4高侧, Q5低侧)
每个半桥的上下管绝不能同时导通,这正是死区插入要解决的问题。
4.2 六步换相原理与GPT配置
BLDC电机采用电子换相,需要按特定顺序给两相通电,产生旋转磁场。一个电周期分为6个步进(Phase)。在每个步进中,只有两个功率管进行PWM调制(用于调速),第三个相悬空(高阻)。下表展示了一个典型的六步换相顺序:
| 步进 (Phase) | 通电相(电流流入->流出) | 高侧PWM管 | 低侧常通管 | 悬空相 |
|---|---|---|---|---|
| 1 | A -> B | Q0 (A高) | Q3 (B低) | C |
| 2 | A -> C | Q0 (A高) | Q5 (C低) | B |
| 3 | B -> C | Q2 (B高) | Q5 (C低) | A |
| 4 | B -> A | Q2 (B高) | Q1 (A低) | C |
| 5 | C -> A | Q4 (C高) | Q1 (A低) | B |
| 6 | C -> B | Q4 (C高) | Q3 (B低) | A |
GPT的配置策略: 我们需要三个独立的PWM通道,分别对应A、B、C三相的高侧开关(Q0, Q2, Q4)。每个通道都配置为带死区的互补输出。低侧开关(Q1, Q3, Q5)在某个步进中作为常通管,不需要PWM,直接由GPIO或GPT的IOCTL寄存器控制为固定低电平。
全局初始化:
// 1. 使能GPT时钟 (CLKCFG.ENABLE) GPT->CLKCFG.ENABLE = 1; // 2. 配置预分频器 (PRECFG),设定PWM定时器时钟频率。例如,系统时钟80MHz,预分频到1MHz用于PWM。 GPT->PRECFG.TICKSRC = 0; // 系统时钟源 GPT->PRECFG.TICKDIV = 79; // 分频系数 = 80 - 1, 定时器时钟 = 80MHz / 80 = 1MHz // 3. 配置死区时间,假设需要2us死区,系统时钟80MHz。 uint32_t deadtime_ticks = (2000ns / 12.5ns) - 1; // 2000/12.5=160, 160-1=159 GPT->DBDLY.RISEDLY = deadtime_ticks; GPT->DBDLY.FALLDLY = deadtime_ticks; // 4. 对三个通道都启用死区 GPT->DBCTL.IO0 = 1; GPT->DBCTL.IO1 = 1; GPT->DBCTL.IO2 = 1;通道独立配置: 以通道0(控制A相)为例,配置为产生中心对齐PWM(更适合电机控制,谐波更少):
// 通道0配置 GPT->C0CFG.OUT0 = 1; // 通道0控制输出0 (IO0/IO_C0) GPT->C0CFG.CCACT = 0xA; // 0xA = Clear on zero, toggle on compare repeatedly (中心对齐PWM) GPT->C0CFG.INPUT = 0; // 输入源选择,这里用不到捕获,选事件 fabric 或 IO 均可 GPT->C0CFG.EDGE = 0; // 输入边沿检测关闭 // 设置PWM周期和占空比 GPT->TGT = pwm_period_ticks - 1; // 中心对齐模式下,周期 = (2 * TGT) * 定时器时钟周期 GPT->C0CC = pwm_duty_cycle_ticks; // 比较值,决定占空比 // 通道1和通道2进行类似配置,OUT1/OUT2分别对应IO1/IO_C1和IO2/IO_C2 GPT->C1CFG.OUT1 = 1; GPT->C1CFG.CCACT = 0xA; GPT->C2CFG.OUT2 = 1; GPT->C2CFG.CCACT = 0xA; // 注意:C1CC和C2CC的初始占空比可以设为0 GPT->C1CC = 0; GPT->C2CC = 0;设置工作模式并启动:
// 设置为中心对齐的上下计数模式 GPT->CTL.MODE = 3; // UPDWN_PER: Count up and down periodically // 启动定时器 // 注意:在启动前,所有通道的输出是未定义的。通常先通过IOCTL将所有输出强制置为安全状态(全低)。 GPT->IOCTL = 0x155; // 假设OUT0/1/2和COUT0/1/2都配置为‘驱动低’(01b),即0x01 01 01 01 01 01 // 然后再启动定时器
4.3 软件换相逻辑实现
定时器负责产生三路带死区的PWM波,但六步换相的时序需要软件来控制。软件需要根据转子位置(通过霍尔传感器或反电动势检测)来决定当前处于哪个步进,并相应地配置GPT的输出。
关键操作在于IOCTL寄存器:这个寄存器可以手动覆盖每个IO和IO_C输出的状态,优先级高于通道自动生成的PWM。在换相时,我们利用这个功能来关闭不需要的PWM输出,并将低侧常通管拉低。
以**换相到Phase 1 (A->B)**为例:
目标:A相高侧PWM(Q0),B相低侧常通(Q3),C相关闭。
GPT硬件状态:三个通道的PWM都在运行,但我们只想让通道0(A相)的PWM输出生效。
软件操作:
- 通过
IOCTL寄存器,将IO_C[0](对应Q1,A相低侧)设置为取反(COUT0=3)。因为A相高侧需要PWM,低侧必须为互补的带死区信号,IO_C[0]本身已是IO[0]的互补输出,所以设置为“取反”实际上会使其输出与IO[0]相同的PWM波?等等,这里需��仔细理解。IOCTL的“取反”是对当前输出值取反。如果我们将IO_C[0]配置为“取反”,而IO[0]正在输出PWM,那么IO_C[0]就会输出一个完全反相的PWM,这正好是我们需要的互补信号!但这里有个更简单的做法:我们本就已经为通道0启���了死区,IO[0]和IO_C[0]会自动生成互补PWM。在Phase 1,我们需要A相高侧(Q0)PWM,低侧(Q1)是互补的PWM。所以,对于A相,我们不需要用IOCTL覆盖,保持硬件自动生成即可。 - 对于B相:我们需要B相低侧(Q3)常通低电平。B相的高侧(Q2)应关闭。因此,我们将
IO[1](对应Q2)强制拉低(OUT1=1),将IO_C[1](对应Q3)强制拉低(COUT1=1)。这样,无论通道1的PWM是什么,B相上下管都关闭。但等等,Phase 1要求B相低侧常通低电平。所以IO_C[1]应该拉低,IO[1]应该保持高阻或关闭?实际上,为了关闭B相高侧,IO[1]应该拉低;为了开启B相低侧,IO_C[1]应该拉高?不对,IO_C是互补输出,当IO为低时,其互补输出IO_C为高。但如果我们用IOCTL将IO_C[1]强制拉低,它就固定为低了。这不符合要求。这里手册的示例描述可能容易引起误解。更合理的做法是:- 我们不使用
IOCTL来产生常通低电平,因为IOCTL会覆盖PWM。 - 相反,我们利用通道的PWM生成能力。对于需要常通低电平的相,我们可以将该通道的PWM占空比设置为0%。在中心对齐PWM模式下,占空比为0%意味着输出恒为低(对于
IO输出,取决于CCACT配置,对于0xA模式,输出在零点被清零,如果比较值CxCC为0,则永远不会发生翻转,输出保持低)。同时,其互补输出IO_C则会恒为高。 - 但是,我们需要的是低侧管常通低电平,即
IO_C输出低。这可以通过将通道配置为另一种模式,或者交换IO和IO_C的物理连接来实现。更常见的实践是:软件不直接控制低侧管的常通,而是将整个半桥配置为PWM模式,但通过设置极高的占空比(100%)或极低的占空比(0%)来模拟常通。例如,要让低侧管常通,可以设置高侧管占空比为0%(常关),低侧管自然就是常通(因为互补输出)。但这要求驱动电路是“高侧有效、低侧互补”的逻辑。
- 我们不使用
鉴于手册示例的表述(“let IOC[1] (Q2) out. All other outputs are configured low”)可能过于简化,在实际工程中,更清晰的做法是:
重新梳理Phase 1的软件操作(基于常见实践):
- 目标:A相:高侧PWM,低侧互补PWM。B相:高侧关闭,低侧常通(低电平)。C相:完全关闭。
- 实现:
- A相 (通道0):保持其PWM配置不变(
CCACT=0xA,占空比由C0CC决定)。IO[0]驱动Q0(高侧),IO_C[0]驱动Q1(低侧),死区已自动插入。 - B相 (通道1):我们需要B相低侧(Q3)常通低电平。这意味着
IO_C[1]需要输出恒低。我们可以通过IOCTL寄存器强制IO_C[1]输出低(COUT1 = 1)。同时,B相高侧(Q2)必须关闭,即IO[1]输出低。同样,用IOCTL强制IO[1]输出低(OUT1 = 1)。这样,无论通道1的PWM状态如何,B相输出都被强制控制。 - C相 (通道2):需要完全关闭,即
IO[2]和IO_C[2]都输出低。同样使用IOCTL强制(OUT2=1,COUT2=1)。 - 关键一步:由于
IOCTL的手动控制优先级高于通道的自动PWM生成,所以上述设置会覆盖通道1和通道2的PWM输出。对于通道0,我们没有手动覆盖,所以其PWM正常输出。
- A相 (通道0):保持其PWM配置不变(
对应的代码片段可能如下:
void switch_to_phase1(void) { // 配置IOCTL寄存器,手动控制输出状态 // Bit fields: [COUT2][OUT2][COUT1][OUT1][COUT0][OUT0] // 每个字段2bits: 00=正常, 01=驱动低, 10=驱动高, 11=取反 // Phase 1: A相正常(PWM), B相全低, C相全低 // OUT0 (Q0): 00 (正常,受PWM控制) // COUT0 (Q1): 00 (正常,互补PWM) // OUT1 (Q2): 01 (强制低) // COUT1 (Q3): 01 (强制低) // OUT2 (Q4): 01 (强制低) // COUT2 (Q5): 01 (强制低) uint32_t ioctl_value = (0b01 << 10) | // COUT2: 驱动低 (0b01 << 8) | // OUT2: 驱动低 (0b01 << 6) | // COUT1: 驱动低 (0b01 << 4) | // OUT1: 驱动低 (0b00 << 2) | // COUT0: 正常 (0b00 << 0); // OUT0: 正常 GPT->IOCTL = ioctl_value; }其他Phase的切换逻辑类似,根据换相表调整
IOCTL寄存器中对应位的配置即可。- 通过
4.4 换相时机与同步
软件如何知道何时换相?常见有两种方法:
- 基于位置传感器:使用霍尔传感器或编码器获取转子位置,在位置信号变化时触发中断,在中断服务程序中进行换相。
- 无传感器反电动势检测:在未通电的相上检测反电动势过零点,通过计算或定时器预估换相点。CC35xx的ADC可以配合GPT的触发功能,在PWM周期的特定点(如PWM关断期间)采样反电动势电压。
一个重要的同步技巧:为了确保换相发生在PWM周期的边界,避免在PWM脉冲中间切换导致电流断续,可以利用GPT的ZERO中断(计数器回零中断)。在ZERO中断服务程序中进行换相计算和IOCTL的更新,可以保证换相动作与PWM周期同步,使运行更平稳。
5. 关键寄存器详解与配置避坑指南
5.1 核心寄存器速查表
| 寄存器名称 | 偏移地址 | 核心功能简述 | 配置要点 |
|---|---|---|---|
CTL.MODE | 0xCh | 定时器工作模式 | 1: UP_ONCE,2: UP_PER,3: UPDWN_PER。配置顺序最后,启动定时器。 |
PRECFG | 0x18h | 时钟预分频 | TICKSRC选时钟源,TICKDIV决定分频。定时器时钟 = 源时钟 / (TICKDIV+1)。 |
DBDLY | - | 死区延迟 | RISEDLY,FALLDLY。死区时间 = (寄存器值+1) * 系统时钟周期。 |
DBCTL | - | 死区使能 | 按位使能对应通道的死区插入功能。 |
CxCFG(x=0,1,2) | 0xC0h, 0xC4h, 0xC8h | 通道配置 | OUTx: 控制哪个物理输出。CCACT: 通道行为(PWM、捕获等)。EDGE: 捕获边沿。 |
TGT | 0x13Ch | 计数器周期值 | 决定PWM频率。UP模式周期=(TGT+1)定时器时钟;UPDWN模式周期=(2TGT)*定时器时钟。 |
CxCC(x=0,1,2) | 0x140h, 0x144h, 0x148h | 通道比较值 | 决定PWM占空比。注意PCxCC(流水线版本)用于无抖动更新占空比。 |
IOCTL | 0x48h | 输出强制控制 | 手动设置/清除/取反每个IO。优先级最高,用于换相和故障安全控制。 |
PTGT,PCxCC | 0xFCh, 0x100h等 | 流水线目标/比较值 | 写入后在下个周期生效,用于同步更新周期和占空比,避免PWM波形抖动。 |
5.2 配置流程与常见陷阱
初始化顺序很重要:错误的配置顺序可能导致意外的输出毛刺。推荐顺序:
- 关闭定时器 (
CTL.MODE = 0)。 - 配置
PRECFG,TGT,CxCC,CxCFG,DBDLY,DBCTL等所有参数。 - 通过
IOCTL将所有输出强制置于安全状态(如全低)。 - 最后,设置
CTL.MODE启动定时器。
- 关闭定时器 (
死区时间计算与验证:务必根据系统时钟频率和所需死区时间准确计算寄存器值。上电后,最好用示波器同时测量
IO[n]和IO_C[n]的波形,验证死区时间是否与设定值相符,并确保没有重叠。PWM频率与分辨率权衡:PWM频率 = 定时器时钟频率 / (周期计数值)。周期计数值(
TGT)也决定了PWM占空比的分辨率。例如,定时器时钟1MHz,TGT设为999,则PWM频率为1kHz,占空比分辨率为1/1000。更高的频率需要更小的TGT,会降低分辨率。需要根据电机电感和控制环路需求折中。使用流水线寄存器更新:在电机运行中动态调整PWM频率(
TGT)或占空比(CxCC)时,直接写入TGT或CxCC可能会在当前周期中间生效,导致产生一个宽度异常的PWM脉冲(抖动)。应使用流水线寄存器PTGT和PCxCC进行写入。硬件会在下一个计数器周期开始(CNTR为零时)自动将流水线寄存器的值载入工作寄存器,实现同步更新,保证波形平滑。故障输入与Park配置:CC35xx的GPT支持故障(Fault)输入引脚。需要配置相关寄存器(通常在IO控制器或系统层面)将故障引脚映射到GPT的Fault事件。一旦故障发生,GPT会根据
PARK寄存器的设置,将输出强制切换到安全状态(并遵循前述的死区保持逻辑)。务必在初始化时配置好PARK状态。中断使用:合理使用
TGT(周期结束)、ZERO(计数器零值)和CxCC(比较匹配)中断,可以用于换相计算、电流采样触发、通信同步等。注意在中断服务程序中及时清除中断标志(通过读/写CxCC、TGT寄存器或写ICLR寄存器)。
6. 调试技巧与问题排查
没有PWM输出:
- 检查GPT时钟是否使能(
CLKCFG.ENABLE)。 - 检查
CTL.MODE是否已设置为非零值(如UP_PER)。 - 确认对应通道的
CxCFG.OUTx位是否使能。 - 用逻辑分析仪或示波器检查
IO引脚,确认是否有输出。可能是引脚复用功能未正确配置为GPT输出。
- 检查GPT时钟是否使能(
PWM输出频率不对:
- 检查系统时钟和
PRECFG.TICKDIV分频设置。 - 确认
CTL.MODE选择是否正确。UP_PER和UPDWN_PER的周期计算方式不同。 - 检查
TGT寄存器的值是否符合预期计算。
- 检查系统时钟和
死区不生效或时间不对:
- 确认
SYS_HDBF是否为1(芯片支持)。 - 检查
DBCTL是否已使能对应通道。 - 验证
DBDLY寄存器值。用示波器测量死区时间,对比(寄存器值+1)*系统时钟周期。 - 检查
IO和IO_C输出是否接反。
- 确认
换相时电机抖动或噪音大:
- 检查换相时机是否准确。尝试在
ZERO中断中进行换相,确保与PWM周期同步。 - 确认
IOCTL的强制控制操作是否在一步内完成(即对一个寄存器的写入),避免中间状态。 - 检查电源电压和电流是否充足,以及电机相序是否正确。
- 检查换相时机是否准确。尝试在
使用调试器暂停时电机异常:如果使用调试器暂停CPU,GPT计数器可能也会停止,导致PWM输出冻结在某个状态,可能引起过流。可以配置
EMU寄存器的HALT和CTL位,让定时器在CPU暂停时完成当前周期后停止在安全状态(如Park状态)。
通过深入理解CC35xx GPT的死区插入、多通道PWM生成以及灵活的IOCTL控制功能,你可以构建出非常稳健的BLDC电机驱动器。这套方案不仅限于CC35xx,其设计思路和注意事项也适用于其他拥有类似高级定时器模块的MCU。在实际项目中,务必结合硬件驱动电路的特性(如驱动芯片的传播延迟、功率管的开关速度)来精细调整死区时间,并通过实验验证,才能达到最优的性能和可靠性。