瑞萨RA8P1微控制器GPT与PDG模块实现高精度PWM死区时间控制详解

发布时间:2026/6/28 15:54:45
瑞萨RA8P1微控制器GPT与PDG模块实现高精度PWM死区时间控制详解 1. 项目概述高精度PWM时序控制的必要性在电机驱动、数字电源或者高精度伺服控制的项目里我们经常需要生成一对互补的PWM信号来驱动半桥或全桥电路。一个核心的挑战就是“死区时间”的设置。死区时间太短上下管可能直通瞬间烧毁MOSFET死区时间太长又会降低输出效率引入波形失真。传统的做法是在软件里设置一个固定的延迟或者依赖定时器比较匹配的先后顺序但这种方法精度有限受限于CPU中断响应和指令执行时间难以做到纳秒级的精确控制尤其是在高频开关场景下几个时钟周期的误差都可能导致问题。瑞萨RA8P1微控制器里的GPT通用PWM定时器模块特别是其搭档PDGPWM延迟生成电路就是为了解决这个痛点而生的。它不是一个简单的定时器而是一个硬件的、可独立编程的“数字延迟线”。你可以把它想象成一个极其精密的可调延时器专门“卡”在GPT生成的原始PWM信号输出路径上。GPT负责生成基础的、周期和占空比可调的PWM波形而PDG则负责对这个波形的每一个边沿上升沿和下降沿进行独立的、高精度的“微调”。这个调整的精度可以达到GPT核心时钟GTCLK周期的1/128或1/64。假设你的GTCLK是160MHz那么一个时钟周期是6.25纳秒1/128的精度就是约49皮秒的调整能力——这已经进入了皮秒量级对于绝大多数电力电子应用来说这提供了巨大的设计余量和优化空间。我最初接触这个功能是在一个高频LLC谐振电源的设计中传统的软件死区补偿在500kHz开关频率下显得力不从心效率始终上不去。在深入研究手册并启用PDG后通过精细调整开通和关断延迟成功将开关损耗降低了近15%效果立竿见影。这个经历让我意识到用好PDG是从“能用”到“精调优化”的关键一步。本文将结合RA8P1的用户手册拆解GPT与PDG的协同工作机制、关键寄存器配置、初始化流程中的那些“坑”以及在实际编程中如何安全、有效地利用这个强大的硬件特性实现真正意义上的精密时序控制。2. GPT与PDG协同工作原理深度解析要玩转PDG必须首先理解它和GPT是如何“握手”合作的。PDG本身不是一个独立的定时器它更像一个依附于GPT通道的“后处理”模块。RA8P1的PDG模块拥有4个独立的延迟通道Channel 0-3每个通道可以独立连接到GPT32xx0-3定时器通道的输出上。2.1 信号流与核心时钟整个系统的核心是GPT核心时钟GTCLK。GPT的所有计数、比较匹配操作都基于GTCLK。PDG的延迟精度也正是基于GTCLK的分频。GTCLK的来源可以选择系统分频后的外设时钟PCLKD或专用的GPT时钟GPTCLK。选择哪个时钟源直接决定了你的延迟精度基数和系统灵活性。在电机控制等对时序抖动敏感的应用中通常建议使用独立的、稳定的GPTCLK以避免其他外设总线活动对PCLKD造成的干扰从而确保PWM边沿的绝对稳定性。PDG模块内部包含一个DLL延迟锁相环电路。这是实现高精度延迟的关键。DLL能够对GTCLK进行精细的相位分割生成多个具有固定相位差的内部时钟信号从而实现对输入信号进行以这些相位差为步进的延迟。当你在寄存器中设置DLY[6:0]0x01时并不是让信号简单地等待一个GTCLK周期而是通过DLL内部的一个特定相位点来“对齐”输出从而实现1/128个GTCLK周期的延迟。2.2 延迟施加的机制PDG对每个通道的两路输出GTIOCnA和GTIOCnB的上升沿和下降沿都可以独立设置延迟。这意味着你有四个独立的延迟寄存器来控制一个通道GTDLYRnA: 控制GTIOCnA引脚输出的上升沿延迟。GTDLYFnA: 控制GTIOCnA引脚输出的下降沿延迟。GTDLYRnB: 控制GTIOCnB引脚输出的上升沿延迟。GTDLYFnB: 控制GTIOCnB引脚输出的下降沿延迟。这里有一个非常重要的概念延迟是施加在边沿事件上的而不是持续地偏移整个信号。当GPT的比较匹配事件发生决定翻转某个引脚的电平时这个翻转命令并不会立即到达引脚。它首先进入PDG的延迟处理流水线。PDG根据当前是上升沿还是下降沿查找对应的延迟寄存器GTDLYRnx或GTDLYFnx然后启动一个以GTCLK分数周期为单位的延迟计数器。只有在这个精细延迟结束后实际的电平翻转才会发生在物理引脚上。因此你最终在示波器上看到的是一个边沿位置被精确“推移”了的PWM波形。2.3 互补PWM与死区时间生成在互补PWM模式下GTIOCnA和GTIOCnB通常被配置为互补输出用于驱动桥式电路的上管和下管。此时PDG的价值得到最大体现。你可以通过设置不同的上升沿和下降沿延迟来构建复杂的死区时间。例如在一个典型的半桥驱动中我们希望上管A关断后延迟一段时间死区时间再开启下管B。下管B关断后延迟一段时间死区时间再开启上管A。利用PDG我们可以这样实现设置GTDLYFnAA下降沿延迟为一个较小值或零让上管尽快关断。设置GTDLYRnBB上升沿延迟为一个较大的值让下管在A关断后再延迟开启。这个差值就是死区时间。同理设置GTDLYFnBB下降沿延迟较小GTDLYRnAA上升沿延迟较大形成另一个方向的死区。通过独立调整这四个参数你不仅可以生成对称或不对称的死区还能补偿由于MOSFET驱动芯片、PCB走线等因素造成的实际开关速度差异实现真正意义上的“门极驱动信号对齐”最大化系统效率。注意手册中特别强调在互补PWM模式下如果设置了GTIOR.CPSCIR1且同步清除后初始输出被禁用那么比较匹配寄存器GTCCRx的值必须至少设置为GTDVU值的两倍。GTDVU是GPT的一个死区时间设置寄存器。这个约束是为了确保在应用了PDG延迟后最终的PWM脉冲宽度仍然为正避免产生无效的零宽度或负宽度脉冲。在计算占空比和设置比较值时必须将这个约束考虑在内。3. PDG寄存器配置详解与初始化流程理解了原理下一步就是动手配置。PDG的寄存器不多但每个位都有其特定作用配置顺序也有讲究乱序可能导致模块无法正常工作或输出异常。3.1 核心控制寄存器GTDLYCR 与 GTDLYCR2GTDLYCR (PWM输出延迟控制寄存器)是整个PDG模块的总开关和配置入口。DLLEN位 (Bit 0): DLL操作使能。这是PDG精度之源必须使能。但初始化流程要求必须先将其清零进行配置最后再置1启动DLL。DLYRST位 (Bit 1): PDG电路复位。置1可复位整个PDG的内部状态。通常在初始化开始时将其置1在配置完所有参数后清零释放复位。FRANGE[1:0]位 (Bits 9:8): GPT核心时钟频率范围选择。这个设置必须在DLLEN0时进行00b: GTCLK频率范围 80 MHz 到 160 MHz。01b: GTCLK频率范围 155 MHz 到 300 MHz。其他值禁止设置。必须根据你实际配置的GTCLK频率正确选择否则DLL可能无法锁定或延迟精度不准。GTDLYCR2 (PWM输出延迟控制寄存器2)用于控制各个通道的使能与旁路。DLYENn位 (Bits 11,10,9,8 for n3,2,1,0): 通道n使能。0为使能延迟电路1为禁用断电。对于不使用的通道设为1以节省功耗。DLYBSn位 (Bits 3,2,1,0 for n3,2,1,0): 通道n旁路选择。这是理解信号路径的关键。0: 旁路。GPT的输出信号绕过PDG延迟电路直接输出到引脚。此时GTIOCnx引脚上的信号就是GPT原始生成的信号。1: 不旁路。GPT的输出信号经过PDG延迟电路处理后输出。手册明确指出一个信号如果经过PDG延迟会比直接旁路多延迟3个GTCLK周期。这个固定延迟在计算绝对时序时必须考虑进去。例如如果你设置了10个单位的延迟实际总延迟是10 * (GTCLK/128) 3 * GTCLK。3.2 延迟设置寄存器GTDLYRnx 与 GTDLYFnx这四个寄存器每个通道一套是设置具体延迟量的地方。它们都是7位宽DLY[6:0]可设置0x00到0x7F共128个值。但延迟的实际时间单位取决于GTDLYCR.FRANGE的设置。当 FRANGE[1:0] 00b (80-160MHz):延迟分辨率 1/128 * GTCLK周期。设置值N对应的延迟时间 N * (GTCLK周期 / 128)。N从1到127有效0表示无延迟。例如GTCLK160MHz (周期6.25ns)设置DLY0x40 (十进制64)则延迟 64 * (6.25ns / 128) 64 * 48.83ps ≈ 3.125ns。当 FRANGE[1:0] 01b (155-300MHz):延迟分辨率 1/64 * GTCLK周期。注意此时寄存器值到实际延迟的映射是非线性的相邻两个值可能对应相同的延迟见手册列表。这是为了在更高频率下优化DLL的工作范围。例如DLY0x02和0x03都对应1/64个GTCLK周期的延迟。在实际编程时最好以手册中的表格为准来设置需要的延迟等级而不是简单地进行线性计算。3.3 标准初始化流程与实操代码示例手册图24.2给出了PDG初始化的标准流程这个流程必须严格遵守否则DLL可能无法正确锁定导致延迟不准或完全失效。下面我结合代码进行分步解读/** * brief 初始化PDG模块以通道0为例 * param gtclk_freq_hz GPT核心时钟频率用于选择FRANGE */ void PDG_Channel0_Init(uint32_t gtclk_freq_hz) { // 步骤 1: 初始设置DLL关闭PDG复位通道旁路 // 1.1 确保DLL关闭这是配置FRANGE的前提 PDG.GTDLYCR.BIT.DLLEN 0; // 1.2 复位PDG内部电路确保状态已知 PDG.GTDLYCR.BIT.DLYRST 1; // 1.3 将通道0设置为旁路模式此时输出直接来自GPTPDG不工作 PDG.GTDLYCR2.BIT.DLYBS0 0; // 步骤 2: 根据GTCLK频率设置FRANGE范围 if((gtclk_freq_hz 80000000) (gtclk_freq_hz 160000000)) { PDG.GTDLYCR.BIT.FRANGE 0x0; // 00b } else if((gtclk_freq_hz 155000000) (gtclk_freq_hz 300000000)) { PDG.GTDLYCR.BIT.FRANGE 0x1; // 01b } else { // 不支持的频率可能需要错误处理 while(1); } // 步骤 3: 使能DLL并等待稳定 PDG.GTDLYCR.BIT.DLLEN 1; // 启动DLL // !!! 关键等待 !!! 手册要求等待至少20us让DLL锁定。 // 这里使用一个简单的延时循环实际项目中应使用精确的延时函数如基于SysTick volatile uint32_t i; for(i0; i(SystemCoreClock/1000000 * 20); i) { __NOP(); } // 步骤 4: 释放PDG复位 PDG.GTDLYCR.BIT.DLYRST 0; // 等待至少5个GTCLK周期让复位信号完全释放内部电路稳定 // 假设GTCLK160MHz5个周期约31.25ns。一个简单的NOP循环通常足够。 for(i0; i10; i) { __NOP(); } // 步骤 5: 关闭旁路使能PDG延迟功能 PDG.GTDLYCR2.BIT.DLYBS0 1; // 通道0不旁路信号进入PDG // 同时确保通道使能位是0使能 PDG.GTDLYCR2.BIT.DLYEN0 0; // 步骤 6: 配置具体的上升沿/下降沿延迟示例设置死区时间 // 假设我们需要在通道0的A、B互补输出上设置死区时间。 // 这里设置A上升沿延迟和B下降沿延迟较大形成死区。 // 注意寄存器地址偏移计算通道n的GTDLYRnA在基址0x0184*n // 以下为示例值具体需根据GTCLK频率和所需死区时间计算DLY值。 uint8_t rise_delay 0x10; // 举例上升沿延迟量 uint8_t fall_delay 0x04; // 举例下降沿延迟量 // 必须先解除GPT对应通道的写保护 (GPT320.GTWP.WP 0) // 假设已操作... GPT32.GTWP.BIT.WP 0; // 设置通道0的A信号延迟 PDG.GTDLYR0A.BIT.DLY rise_delay; // A上升沿延迟 PDG.GTDLYF0A.BIT.DLY fall_delay; // A下降沿延迟 // 设置通道0的B信号延迟互补对称设置 PDG.GTDLYR0B.BIT.DLY fall_delay; // B上升沿延迟与A下降沿对称 PDG.GTDLYF0B.BIT.DLY rise_delay; // B下降沿延迟与A上升沿对称 // 重新使能写保护如果需要 // GPT32.GTWP.BIT.WP 1; }实操心得第3步的20us等待至关重要。在早期调试时我曾忽略这个等待直接进行后续操作结果发现设置的延迟完全不起作用或者延迟量随机漂移。DLL是一个模拟电路需要时间来锁定相位。这个等待时间必须保证。最好使用定时器或RTOS的延时函数避免使用不精确的空循环尤其是在核心频率可变的情况下。4. 延迟设置的生效时机与关键约束配置了寄存器延迟并不是立即生效的。理解延迟设置的“生效时机”和相关的“约束条件”是避免出现诡异波形问题的关键。4.1 设置传输时序缓冲与同步手册24.3.2节详细说明了这一点。当你写入GTDLYRnx或GTDLYFnx寄存器时这个值并不是直接作用于当前的延迟电路。它首先被写入一个临时寄存器Buffer。这个临时寄存器的值会在一个特定的同步时刻被传输到真正控制延迟的生效寄存器中。这个同步时刻就是GPT计数器的特定相位点锯齿波模式Saw-wave在计数器溢出向上计数或下溢向下计数的时刻。三角波模式Triangle-wave在计数器的波谷trough时刻。图24.3和24.4清晰地展示了这个过程。这意味着你对延迟值的修改是“批次处理”的只在每个PWM周期的边界生效。这样设计的好处是避免了在PWM周期中间改变延迟可能造成的输出毛刺或半周期波形异常。编程影响如果你在运行时需要动态调整死区时间例如根据温度或电流进行自适应调整你必须在软件中规划好更新时机。最好在检测到计数器溢出/下溢中断或利用周期结束事件后立即更新延迟寄存器。这样新值会在下一个PWM周期开始时立即生效确保时序连贯。4.2 至关重要的约束条件何时不能修改延迟手册24.4.2节列出了一个极易踩坑的约束我称之为“延迟修改禁区”。当PWM延迟生成电路正在为某个波形生成延迟并且该波形是通过比较匹配来触发翻转时在特定的比较匹配值范围内禁止更改延迟设置寄存器。这个约束具体如下表所示PWM模式计数方向禁止修改延迟的比较匹配值范围锯齿波模式向上计数GTPR - 2 或更高锯齿波模式向下计数2 或更低三角波模式向下计数2 或更低这是什么意思我们以锯齿波向上计数为例。GTPR是周期寄存器。假设GTPR 1000。那么当用于决定边沿翻转的比较匹配寄存器例如GTCCRD它控制某个下降沿的值大于或等于 998 (1000-2)时你就不能去修改对应引脚例如GTIOC0A的下降沿延迟寄存器GTDLYF0A。为什么有这个约束我个人的理解是PDG内部需要一定的提前量来准备和施加延迟。当比较匹配点非常接近周期结束时对于上数就是接近GTPR对于下数就是接近0PDG处理流水线可能已经进入了为下一个边沿事件做准备的临界状态。此时强行修改延迟参数可能会扰乱内部状态机导致下一个或下几个周期的输出时序出现不可预测的错误例如边沿丢失、延迟量错误或产生毛刺。如何规避静态应用如果你的死区时间是固定的在GPT启动之前就配置好所有PDG寄存器这是最安全的方式。动态调整如果必须动态调整务必在软件中增加条件判断。在更新延迟寄存器前先读取当前的比较匹配寄存器值判断其是否处于“禁区”。如果是则等待到下一个PWM周期在计数器远离禁区例如对于上数当计数器值远小于GTPR-2时再进行更新。可以利用周期结束中断作为安全的更新窗口。// 伪代码安全更新延迟的函数 void SafeUpdateDelay(uint16_t compare_match_value, uint8_t new_delay) { // 假设是锯齿波向上计数模式GTPR已知为period_val uint16_t period_val GPT32.GTPR; uint16_t danger_zone_threshold period_val - 2; // 检查当前比较匹配值是否在“禁区” if(compare_match_value danger_zone_threshold) { // 处于禁区设置一个标志在下一个周期结束中断中再执行更新 g_delay_update_pending true; g_new_delay_value new_delay; } else { // 安全区域直接更新 PDG.GTDLYR0A.BIT.DLY new_delay; // 注意还需要考虑寄存器写入间隔约束见下文 } } // 在GPT周期结束中断服务函数中 void GPT32_Period_End_IRQHandler(void) { // ... 清除中断标志等操作 ... if(g_delay_update_pending) { // 在周期开始时比较匹配值远离禁区安全更新 PDG.GTDLYR0A.BIT.DLY g_new_delay_value; g_delay_update_pending false; } }4.3 寄存器写入间隔约束手册24.4.3节提到了另一个细节约束当GPT核心时钟选择GPTCLK而非PCLKD时如果对同一个延迟寄存器GTDLYRnA/GTDLYFnA/GTDLYRnB/GTDLYFnB进行连续写入两次写入之间的间隔必须大于一个特定值否则后一次的写入可能无法生效。计算公式为Write_Interval [ns] Period_of_PCLKA [ns] × 6 Period_of_GPTCLK [ns] × 4例如PCLKA 100MHz (周期10ns)GPTCLK 160MHz (周期6.25ns)则最小写入间隔 10ns * 6 6.25ns * 4 60ns 25ns 85ns。实操建议在需要频繁更新延迟的复杂算法中如实时死区补偿如果使用GPTCLK在连续写入同一个延迟寄存器后最好插入一个短暂的软件延迟或者确保两次写入操作之间有足够多的其他指令。更稳健的做法是避免在高速循环内连续写入同一个寄存器而是将更新请求排队在后台任务或低优先级中断中处理。5. 测试信号与调试技巧PDG模块还提供了一个非常实用的硬件调试功能测试选通信号。这个功能对于验证PDG是否按预期工作以及进行电路板级信号完整性调试非常有帮助。5.1 测试选通信号是什么如手册23.10.9节所述每个通道的PWM输出GTIOCxA/B都会产生一个对应的测试选通信号并输出到PWM延迟生成电路PDG。这个信号的行为是它监控GTIOCxA或GTIOCxB输出的每个上升沿或下降沿。当PWM输出发生跳变后经过恰好1个GTCLK周期该选通信号变为高电平1。在PWM周期结束的计数时钟处该选通信号恢复为低电平0。复位和周期结束都会使其清零。简单来说这个选通信号就是一个“边沿检测标志”其脉冲宽度大致等于从边沿发生到周期结束的时间实际为边沿后1个GTCLK到周期结束。5.2 如何利用它进行调试虽然这个信号是内部信号但我们可以通过它的行为来推断PDG和GPT的工作状态特别是在调试计数器启停与PDG的协同问题时。手册图23.174和23.175揭示了两个重要场景图23.174如果在计数器GTCNT停止时选通信号恰好为高1那么当计数器重新启动后第一个PWM周期内的选通信号不会正确生成保持为1直到第一个周期结束后才恢复正常。这意味着在计数器停止期间捕获到的边沿事件可能会干扰重启后第一个周期的内部状态。图23.175提供了一种解决方案在停止计数器前通过清除计数器对于锯齿波操作来人为产生一个“周期结束”事件从而将选通信号复位为0。这样在重启后第一个周期的选通信号就能正确生成。调试启示验证PDG使能如果你怀疑PDG没有工作信号被旁路了可以尝试测量PWM输出边沿与理论计算考虑延迟后的差异。更深入的方法是通过仿真器或芯片的调试模块尝试间接观察或触发与选通信号相关的事件。排查异常启停如果你的应用涉及动态启停GPT计数器例如突发模式、低功耗模式并且发现重启后的第一个PWM波形异常如死区不对就需要考虑是否是图23.174描述的问题。此时应参考图23.175的流程在停止计数器前确保选通信号被复位例如通过将计数器强制清零到产生一个周期结束事件。系统级验证在复杂的系统中GPT和PDG可能由不同任务或中断服务程序配置。测试选通信号的机制提醒我们配置的顺序和时机非常重要。确保在使能PDG和启动GPT计数器之前所有相关寄存器包括周期、比较值、延迟值都已稳定设置并且遵循正确的初始化序列。6. 低功耗模式下的注意事项在追求能源效率的应用中RA8P1的低功耗模式是必备功能。手册23.10.10节和24.4.1节分别从GPT和PDG的角度给出了重要提示。对于GPT在进入待机模式Standby Mode之前必须停止计数器操作设置GTCR.CST 0。这是一个基本的安全操作防止定时器在核心时钟可能不稳定的低功耗状态下继续运行导致不可预知的行为或增加功耗。对于PDG其功耗由模块停止控制寄存器DMSTPCRD管理。复位后PDG模块默认处于停止状态以节省功耗。在你打算使用PDG之前必须通过配置MSTPCRD相应位来释放模块停止状态。否则对PDG寄存器的访问可能无效或者模块根本不工作。完整的低功耗序列建议进入低功耗前停止所有活跃的GPT计数器GTCR.CST 0。如果需要保持PWM输出为固定电平配置好输出保持电平。通过MSTPCRD关闭PDG模块如果之前已开启。根据目标低功耗模式配置其他外设。从低功耗唤醒后系统时钟稳定后首先通过MSTPCRD使能PDG模块。严格遵循第3章所述的PDG初始化流程DLLEN0 - 设置FRANGE - DLLEN1 - 等待20us - 释放复位 - 关闭旁路。不能因为PDG之前配置过就跳过初始化。重新配置GPT相关寄存器周期、比较值等。最后启动GPT计数器。踩坑记录我曾在一个需要频繁进入/退出低功耗睡眠模式的产品中为了快速恢复PWM输出尝试在唤醒后不重新初始化PDG只重新使能GPT。结果发现PWM输出的延迟时间变得随机完全失控。根本原因就是DLL在低功耗模式下失锁唤醒后没有经过重新锁定和初始化的过程。教训是PDG的初始化流程尤其是DLL使能和等待在每次模块从停止状态唤醒后都必须完整执行。7. 实战案例构建一个可调死区的互补PWM驱动让我们综合以上所有知识完成一个完整的实战配置使用RA8P1的GPT32通道0和PDG通道0生成一对带可调死区时间的互补PWM信号驱动一个半桥电路。7.1 系统时钟与引脚配置假设系统配置如下PCLKD 200MHzGPTCLK 160MHz(作为GTCLK)PWM频率目标100kHz死区时间目标100ns引脚映射GTIOC0A- 上管驱动GTIOC0B- 下管驱动。首先在RA8P1的配置工具如RASC或直接寄存器编程中完成以下前置步骤配置系统时钟树确保PCLKD和GPTCLK正确产生。将GTIOC0A和GTIOC0B引脚功能配置为GPT输出模式。配置GPT32通道0的基本参数锯齿波向上计数模式周期寄存器GTPR决定频率。7.2 GPT基础参数计算与配置PWM周期计算PWM频率 GPTCLK / (GTPR 1)。目标100kHzGPTCLK160MHz。GTPR (GPTCLK / PWM_Freq) - 1 (160e6 / 100e3) - 1 1600 - 1 1599。设置GPT32.GTPR 1599。占空比设置假设我们需要50%初始占空比。在互补中心对齐模式下通常需要设置两个比较寄存器。这里以简单的锯齿波边沿对齐为例使用GTCCRA和GTCCRC来控制A和B的占空比。对于50%占空比比较值 GTPR * Duty 1599 * 0.5 ≈ 800。设置GPT32.GTCCRA 800(控制GTIOC0A的翻转点)。设置GPT32.GTCCRC 800(控制GTIOC0B的翻转点)。注意需要通过GTIOR寄存器将A、B输出配置为互补模式并设置极性。7.3 PDG延迟参数计算与配置我们的目标是产生100ns的死区时间。GTCLK周期 1 / 160MHz 6.25ns。 PDG延迟分辨率FRANGE00b时 6.25ns / 128 ≈ 48.83ps。所需延迟单位数N 所需死区时间 / 分辨率 100ns / (6.25ns/128) 100ns / 48.83ps ≈ 2048。这显然超过了7位寄存器最大值127的范围。这里是一个关键点PDG的延迟寄存器无法直接设置这么大的延迟值。100ns的死区时间相当于16个GTCLK周期因为100ns / 6.25ns 16。结论PDG的精细延迟1/128 GTCLK用于微调。主要的死区时间仍然需要依靠GPT本身的比较匹配点错位来产生。PDG则用于在这个粗调的基础上进行纳秒甚至皮秒级的精细补偿。标准做法用GPT比较寄存器设置基础死区将上管关断A下降沿和下管开启B上升沿的比较点错开16个计数。假设GTCCRA控制A的下降沿设为T_off_A。GTCCRC控制B的上升沿设为T_on_B。设置T_on_B T_off_A 16计数单位。这样就有了约100ns的基础死区。用PDG进行精细补偿假设由于PCB布局等原因实测发现上管关断实际比信号晚了2ns下管开启慢了1ns。我们可以用PDG来补偿上管需要提前2ns关断即让A下降沿提前。设置GTDLYF0A.DLY为一个负补偿不PDG只能增加延迟。所以我们需要让下管的开启再额外延迟1ns使得相对死区增加1ns。计算补偿值1ns / (6.25ns/128) ≈ 20.48 - 取整20。设置GTDLYR0B.DLY 20。这样B信号的上升沿将在GPT比较点的基础上再额外延迟约0.98ns使得实际死区时间从100ns增加到约100.98ns补偿了上管关断的延迟。PDG配置代码接初始化流程// 假设GPT已配置为互补PWM模式GTCCRA800 GTCCRC816基础死区16个计数 // PDG精细补偿让下管开启再延迟约1ns #define GTCLK_PERIOD_NS 6.25f #define PDG_RESOLUTION_PS (GTCLK_PERIOD_NS * 1000 / 128) // 约48.83ps float desired_fine_delay_ns 1.0f; // 希望额外补偿1ns uint8_t pdg_delay_value (uint8_t)((desired_fine_delay_ns * 1000) / PDG_RESOLUTION_PS 0.5f); // 四舍五入 // 计算得 pdg_delay_value ≈ 20 // 配置PDG通道0的B信号上升沿额外延迟 PDG.GTDLYR0B.BIT.DLY pdg_delay_value; // 约0.98ns延迟 // A信号的延迟可以根据需要设置例如补偿其下降沿 // PDG.GTDLYF0A.BIT.DLY some_value;7.4 完整启动序列与验证配置引脚和系统时钟。配置GPT32通道0设置计数模式、周期、比较值、输出模式互补、极性。先不要启动计数器GTCR.CST0。执行第3章所述的完整PDG初始化流程。启动GPT计数器设置GTCR.CST 1。验证使用示波器测量GTIOC0A和GTIOC0B引脚波形。检查PWM频率是否为100kHz。检查基础死区时间是否约为16 * 6.25ns 100ns。尝试微调GTDLYR0B.DLY的值例如从20改为40观察死区时间是否以约48.83ps的步进增加。这可以直观验证PDG是否工作。通过这个案例我们可以看到GPT和PDG是相辅相成的。GPT负责“宏观”的周期和占空比控制以及通过比较匹配点设置“粗粒度”的死区而PDG则像一个精密的“微调旋钮”负责消除硬件不对称性和传播延迟带来的“微观”误差从而实现极高精度的时序对齐。将两者结合使用是发挥RA8P1在高端数字电源和电机驱动应用中性能潜力的关键。