CMPSS硬件比较器子系统:实时控制中的峰值检测与保护利器

1. 项目概述:为什么需要CMPSS?

在开发高性能的实时控制系统,尤其是开关电源、电机驱动或者功率因数校正电路时,我们经常面临一个核心挑战:如何快速、准确且可靠地检测电流或电压的瞬时峰值,并立即做出保护或控制响应?如果仅仅依赖软件通过ADC采样、计算再判断,延迟太大,很可能在过流发生的几个微秒内,你的MOSFET就已经“光荣牺牲”了。这时候,硬件比较器就成了救命稻草——它能以纳秒级的响应速度,直接比较模拟信号,输出一个干净利落的数字信号来触发保护。

然而,现实世界中的模拟信号从来都不是“干净”的。开关噪声、振铃、毛刺无处不在。一个没有经过处理的比较器输出信号,可能会因为瞬间的噪声干扰而频繁误触发,导致系统误保护甚至无法正常工作。这就是为什么在像TI C2000这样的高端微控制器中,比较器子系统显得如此重要。它不是一个孤立的比较器,而是一个集成了可编程参考DAC、数字滤波器和斜坡发生器的完整信号链解决方案。

以TMS320F2838x中的CMPSS为例,它把工程师从繁琐的外部电路设计中解放出来。你不再需要外接一个DAC芯片来生成可变的比较阈值,也不需要设计复杂的RC滤波电路来抑制噪声,更不用搭建一个模拟斜坡发生器来做峰值电流控制。所有这些功能,都被集成在芯片内部,通过寄存器进行灵活配置。这不仅仅是节省了几个外围元件,更重要的是,它带来了确定性、可重复性和极高的集成度,让系统设计更简洁,性能更可靠。

我接触过不少从通用MCU转向C2000做电源开发的工程师,最初往往会对CMPSS这一大堆寄存器感到头疼。但一旦理清了其内部数据流和配置逻辑,你就会发现它是一把解决实时控制难题的“瑞士军刀”。本文的目标,就是带你深入CMPSS的内部,不仅看懂手册上的框图,更要理解每个模块“为什么”要这么设计,以及在实际项目中“如何”配置才能避开那些潜在的坑。

2. CMPSS架构深度拆解:不止于比较

CMPSS的完整性和复杂性,远超一个简单的电压比较器。我们可以把它理解为一个专为功率控制优化的“模拟-数字事件处理流水线”。它的核心任务是将一个模拟输入信号(如电流采样电阻上的电压)转换成一个稳定、无毛刺的数字事件信号(如ePWM的跳变或触发源),并能在过程中进行动态的阈值调整。

2.1 核心模块互联与数据流

一个CMPSS实例包含两个独立的比较器通道,通常标记为“H”(高)和“L”(低)。这种设计非常巧妙,它天然支持窗口比较功能。例如,在过流和欠流保护中,你可以用高比较器设置过流点,用低比较器设置欠流点,从而实现双向保护。

每个比较器的正输入端(CMPINxP)通常连接到一个外部引脚,用于引入待监控的模拟信号(如电流采样电压)。而其负输入端的选择则构成了系统的灵活性核心:

  • 外部引脚输入:用于与另一个外部参考电压进行比较。
  • 内部12位参考DAC输入:这是最常用且强大的模式。DAC可以生成一个精确、可编程的电压阈值,这个阈值甚至可以在运行时由软件或斜坡发生器动态改变。

比较器输出的数字信号(高或低)会兵分三路,形成三条并行的处理路径:

  1. 异步路径:原始的比较器输出,不经任何延迟,直接通向CTRIPxCTRIPOUTx信号选择器。这条路径速度最快,用于需要极限响应速度的场景。
  2. 同步路径:原始输出经过一个简单的同步器(1-2个系统时钟周期延迟),以消除亚稳态,然后进入选择器。
  3. 滤波路径:原始输出送入一个可配置的数字滤波器,滤除毛刺后,可以选择是否经过一个锁存器,再进入选择器。

最终,通过配置COMPCTL寄存器中的CTRIPxSELCTRIPOUTxSEL位,我们可以决定哪一路信号作为最终的CTRIPx(通常连接到ePWM的Trip Zone,用于紧急关断)和CTRIPOUTx(连接到Output X-BAR,可用于驱动其他外设或GPIO)。

2.2 参考DAC:可编程阈值的核心

CMPSS内部的12位DAC是其精度和灵活性的基石。它的输出电压计算公式非常直观:DACOUT = (1 + DACVALA) / 4096 * DACREF其中,DACVALA是DAC的12位有效值寄存器(范围0-4095),DACREF是参考电压,可选择为芯片模拟电源VDDA或内部VDAC

这里有一个极其关键且容易被忽略的细节:每个DAC都有影子寄存器DACxVALS)和有效寄存器DACxVALA)。影子寄存器是软件直接写入的地方,而有效寄存器才是真正控制DAC输出电压的。两者之间的加载方式由COMPDACCTL[SWLOADSEL]位控制:

  • 立即加载SWLOADSEL=0):写入DACxVALS后,DACxVALA立即更新。这适用于需要快速改变阈值的场景。
  • 同步加载SWLOADSEL=1):写入DACxVALS后,需要等待一个来自ePWM模块的EPWMSYNCPER同步信号,DACxVALA才会更新。这是实现与PWM周期严格同步的关键,在峰值电流模式控制中必不可少,可以确保每个开关周期开始时,DAC阈值被刷新,斜坡从预设值开始下降。

实操心得:DAC的“扰动”与设计禁忌技术手册中明确警告了一个硬件特性:当高、低两个比较器中的一个发生跳变时,可能会短暂地“扰动”另一个DAC的输出电压(参数为“CMPSS DAC output disturbance”和“CMPSS DAC disturbance time”)。这意味着,如果你同时使用两个比较器,并且它们的阈值设置得比较接近,一个比较器的动作可能会导致另一个比较器产生误触发。

避坑指南

  1. 非对称设计:如果可能,尽量让两个比较器的阈值点拉开足够的距离,确保在一个比较器触发期间,输入信号不会因为DAC扰动而越过另一个比较器的阈值。
  2. 单路使用规范:如果只使用高比较器(COMPH),必须将低DAC的值DACLVALS设置为0。反之,如果只使用低比较器(COMPL),必须将高DAC的值DACHVALS设置为最大值(0xFFF)。这是为了防止未使用的比较器因其DAC输出不确定而产生随机跳变,进而通过内部耦合影响正在使用的通道。这个细节在初始化时务必检查,否则会引入难以排查的间歇性故障。

2.3 数字滤波器:从“毛刺”到“确信”

数字滤波器是CMPSS抗干扰能力的灵魂。它不是一个简单的延时,而是一个基于多数表决机制的智能滤波器。其工作原理可以通过三个关键参数来理解:

  • 采样窗口SAMPWIN。它定义了滤波器观察多少个连续的采样点来做决策。内部实际使用的窗口大小是SAMPWIN + 1。例如,SAMPWIN = 9,则窗口包含10个样本。
  • 表决阈值THRESH。它定义了需要多少个相反状态的样本出现在窗口内,才能让滤波器输出改变状态。内部实际使用的阈值是THRESH + 1。这个值必须大于SAMPWIN/2且小于等于SAMPWIN
  • 时钟预分频CLKPRESCALE。它决定了滤波器的采样频率,即每CLKPRESCALE + 1个系统时钟周期,滤波器对输入信号采样一次。

滤波器决策逻辑(用工程师能懂的话说):

  1. 滤波器内部维护一个长度为SAMPWIN+1的FIFO,不断移入新的采样值。
  2. 如果当前滤波器输出是0,它会数一数窗口里有多少个1。如果1的数量大于等于THRESH+1,它就把输出翻���为1。
  3. 如果当前滤波器输出是1,它会数一数窗口里有多少个0。如果0的数量大于等于THRESH+1,它就把输出翻转为0。
  4. 否则,输出保持不变。

这种机制能有效滤除持续时间短的噪声毛刺。例如,设置SAMPWIN=4(5个样本窗口),THRESH=3(需要4个相反样本)。如果一个真实的跳变伴随1-2个时钟周期的毛刺,由于毛刺数量达不到阈值,输出不会翻转,从而抑制了误触发。

配置技巧与延迟权衡: 滤波器的引入必然带来延迟。总延迟 =(CLKPRESCALE+1) * (SAMPWIN+1)个系统时钟周期。在200MHz系统时钟下,一个典型的配置(CLKPRESCALE=0,SAMPWIN=4)会带来至少5个时钟周期,即25ns的延迟。你需要根据开关频率和噪声特性来权衡:

  • 高频开关(>500kHz):窗口不宜过大,SAMPWIN选择1或2,THRESH设为SAMPWIN(即需要全部样本一致),牺牲一些抗扰性换取速度。
  • 强噪声环境:增大CLKPRESCALE来降低采样率,可以滤除更高频率的噪声;同时适当增大SAMPWINTHRESH
  • 初始化:在使能滤波器前,务必通过设置FILINIT位来初始化FIFO窗口的内容,使其与当前比较器输出状态一致,避免上电时的误判。

2.4 斜坡发生器:峰值电流模式的引擎

斜坡发生器是CMPSS用于实现峰值电流模式控制的专用硬件。它的工作模式非常固定:产生一个只降不升的斜坡信号,并将其高12位作为高比较器DAC(DACH)的输入值。

其工作流程可以概括为:

  1. 装载与启动:当COMPDACCTL[DACSOURCE]=1时,斜坡发生器被选为DACH的源。在使能或收到EPWMSYNCPER信号时,RAMPSTS寄存器从RAMPMAXREFS(影子寄存器)加载初始值。
  2. 延迟递减:启动后,RAMPSTS并不会立即开始递减。它会先等待一个由RAMPDLYA定义的延迟周期数(每个周期为一个SYSCLK)。这个延迟通常用于对齐PWM开关事件的特定相位。
  3. 斜坡生成:延迟结束后,在每个SYSCLK周期,RAMPSTS的值会减去RAMPDECVALA中设定的步进值。
  4. 停止与重置:当高比较器触发(COMPHSTS置位)时,斜坡递减会立即停止。RAMPSTS的当前值会被锁定,直到下一个EPWMSYNCPER信号到来,它才会被重新装载为RAMPMAXREFS,开始下一个周期的斜坡。

关键参数计算: 假设系统时钟SYSCLK = 200 MHz,PWM开关频率fsw = 100 kHz,周期Tsw = 10 us。我们希望斜坡在每个PWM周期内从最大值线性下降到0。

  • RAMPMAXREFS:设置为斜坡的起始值,通常对应DAC的最大输出或某个设定值,例如0xFFFF。
  • RAMPDECVALA:步进值。计算方式为:RAMPMAXREFS / (Tsw * SYSCLK)。例如,如果RAMPMAXREFS = 65535,则RAMPDECVALA = 65535 / (10e-6 * 200e6) = 65535 / 2000 ≈ 33。这意味着每个SYSCLK周期,斜坡值减少33。
  • RAMPDLYA:延迟周期数。如果需要斜坡在PWM周期开始后一段时间再启动,可以设置此值。例如,设置延迟为开关周期的10%,即0.1 * 10e-6 * 200e6 = 200个周期。

这种硬件斜坡与PWM周期的严格同步,使得在每个开关周期内,电流峰值可以被一个线性下降的电压阈值精确限制,从而实现稳定、快速的峰值电流控制,无需CPU干预。

3. 寄存器配置实战:从零搭建一个CMPSS应用

理解了架构,我们进入实战环节。我将以一个常见的“过流保护+滤波输出”场景为例,展示如何一步步配置CMPSS寄存器。假设我们使用CMPSS1的高比较器(COMPH),通过内部DAC设置一个2.5V的阈值(假设VDDA=3.3VDACREF=VDDA),并对输出进行数字滤波,最终将滤波后的跳变信号通过GPIO输出,同时将异步跳变信号连接到ePWM1的Trip Zone。

3.1 初始化步骤与寄存器详解

步骤1:使能模块时钟与解锁寄存器在配置任何外设前,首先要确保其时钟已使能,并且相关寄存器可写(C2000很多关键寄存器受EALLOW保护)。

// 使能CMPSS1模块时钟 (假设使用C2000 DriverLib库) SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS1); // 解除寄存器写保护 EALLOW;

步骤2:配置比较器控制寄存器COMPCTL寄存器是CMPSS的总开关和路由控制器。

Cmpss1Regs.COMPCTL.all = 0; // 先清零 Cmpss1Regs.COMPCTL.bit.COMPDACE = 1; // 使能比较器和DAC Cmpss1Regs.COMPCTL.bit.COMPHSOURCE = 0; // 高比较器负端选择内部DAC Cmpss1Regs.COMPCTL.bit.COMPHINV = 0; // 输出不反相 (正端电压 > DAC电压时输出高) Cmpss1Regs.COMPCTL.bit.CTRIPHSEL = 0; // CTRIPH选择异步输出,用于快速触发ePWM Trip Cmpss1Regs.COMPCTL.bit.CTRIPOUTHSEL = 2; // CTRIPOUTH选择滤波后输出,用于GPIO观察 Cmpss1Regs.COMPCTL.bit.ASYNCHEN = 0; // 本例不使用异步路径与锁存输出的“或”逻辑
  • CTRIPHSELCTRIPOUTHSEL分离:这是CMPSS的一个强大特性。你可以让一路信号(如CTRIPH)不经滤波直接去快速关断PWM(Trip Zone),同时让另一路信号(如CTRIPOUTH)经过滤波后用于状态指示或逻辑控制,互不干扰。

步骤3:配置DAC值计算DAC值:目标电压2.5V,参考电压3.3V。根据公式DACVAL = (Vout / Vref) * 4096 - 1DACVAL = (2.5 / 3.3) * 4096 - 1 ≈ 0.7576 * 4096 - 1 ≈ 3103 - 1 = 3102(0xC1E)。

// 配置高DAC的影子和有效寄存器 Cmpss1Regs.DACHVALS.bit.DACVAL = 3102; // 写入影子寄存器 // 由于COMPDACCTL[SWLOADSEL]默认为0(立即加载),DACHVALA会自动更新 // 如果不使用低比较器,必须将低DAC设为0 Cmpss1Regs.DACLVALS.bit.DACVAL = 0;

步骤4:配置数字滤波器假设系统时钟200MHz,我们希望滤除宽度小于100ns的毛刺。采样窗口设为5个样本(SAMPWIN=4),阈值设为需要4个一致样本才翻转(THRESH=3),采样周期设为2个系统时钟(CLKPRESCALE=1)。

  • 理论滤波能力:毛刺宽度需大于(CLKPRESCALE+1) * THRESH / SYSCLK = 2 * 4 / 200e6 = 40ns。小于40ns的毛刺会被滤除。
  • 引入延迟:(CLKPRESCALE+1) * (SAMPWIN+1) / SYSCLK = 2 * 5 / 200e6 = 50ns
Cmpss1Regs.CTRIPHFILCTL.bit.SAMPWIN = 4; // 样本窗口=5 Cmpss1Regs.CTRIPHFILCTL.bit.THRESH = 3; // 表决阈值=4 Cmpss1Regs.CTRIPHFILCLKCTL.bit.CLKPRESCALE = 1; // 采样时钟=SYSCLK/2 // 初始化滤波器FIFO内容 Cmpss1Regs.CTRIPHFILCTL.bit.FILINIT = 1;

步骤5:配置输出路由CTRIPH连接到ePWM1的Trip Zone输入,将CTRIPOUTH连接到某个GPIO。

// 需要配置Input X-BAR和Output X-BAR (此处为示意,具体寄存器请参考手册) // 假设CTRIPH连接到INPUTXBAR1,然后INPUTXBAR1连接到ePWM1的TZ1 InputXbarRegs.INPUT1SELECT = 60; // CTRIPH的映射值,需查表 EPwm1Regs.TZSEL.bit.OSHT1 = 1; // 使能ePWM1的One-Shot Trip源1 // 将CTRIPOUTH连接到OUTPUTXBAR3,再映射到GPIO14 OutputXbarRegs.OUTPUT3MUX0TO15CFG.bit.MUX0 = 3; // 选择CMPSS1.CTRIPOUTH GPIO_setPinConfig(GPIO_14_OUTPUTXBAR3); // 配置GPIO14为Output X-BAR3功能

步骤6:重新锁存寄存器并退出EALLOW

EDIS; // 重新锁存受保护的寄存器

3.2 斜坡发生器配置实例(峰值电流模式)

假设我们要在ePWM1的每个周期同步启动一个斜坡。

EALLOW; // 1. 配置DAC源为斜坡发生器 Cmpss1Regs.COMPDACCTL.bit.DACSOURCE = 1; // 2. 选择同步信号源为ePWM1的SYNCPER Cmpss1Regs.COMPDACCTL.bit.RAMPSOURCE = 0; // 对应EPWM1SYNCPER // 3. 配置斜坡参数 Cmpss1Regs.RAMPMAXREFS.all = 0xFFFF; // 斜坡起始最大值 Cmpss1Regs.RAMPDECVALS.all = 33; // 每个SYSCLK递减步长,根据计算得出 Cmpss1Regs.RAMPDLYS.all = 0; // 无延迟启动 // 4. 配置DAC加载方式为同步加载(与斜坡同步) Cmpss1Regs.COMPDACCTL.bit.SWLOADSEL = 1; // 5. 配置斜坡在COMPH触发时,从RAMPMAXREFA重载(实现周期复位) Cmpss1Regs.COMPDACCTL.bit.RAMPLOADSEL = 0; // 注意:还需要配置ePWM1,使其产生正确的SYNCPER信号(通常在每个周期开始)。 EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // 例如,禁止同步输出,但内部仍会产生SYNCPER EDIS;

4. 高级应用与故障排查实录

4.1 CMPSS校准:消除误差,提升精度

即使是最好的硬件,也存在偏移误差。CMPSS的误差主要来自两方面:比较器输入参考偏移DAC静态偏移。手册中会给出这两个参数(例如,典型值±10mV)。对于高精度应用,软件校准是必要的。

校准流程(当比较器负端使用内部DAC时)

  1. 在比较器正端(CMPINxP)施加一个已知的、稳定的直流电压V_target(例如,使用精密电压源或通过高精度ADC测量得到)。
  2. 禁用迟滞功能(COMPHYSCTL = 0),并配置一个适中的数字滤波器以抑制噪声。
  3. 将DAC值设置为一个远高于V_target的初始值(例如最大值0xFFF)。
  4. 以1 LSB的步长递减DAC值。
  5. 每次递减后,等待DAC稳定(通常几个微秒),然后清除状态锁存(COMPSTSCLR.bit.HLATCHCLR = 1)。
  6. 稍作延迟,检查锁存状态(COMPSTS.bit.COMPHLATCH)。
  7. 一旦锁存置位,记录当前的DAC值DAC_trip。此时DAC_trip对应的电压V_dac应该等于V_target加上系统总偏移。
  8. 计算偏移误差:Offset_Error = V_target - ( (DAC_trip + 1) / 4096 * DACREF )
  9. 在后续应用中,设置DAC值时,将此偏移误差补偿进去。

校准注意事项

  • 校准应在系统上电稳定、温度相对恒定的环境下进行。
  • 如果输入信号有噪声,务必启用数字滤波器并合理设置参数,否则校准结果会跳动。
  • 校准值可以存储在非易失性存储器中,供后续上电使用。

4.2 与ePWM的协同:实现精准的逐周期限流

CMPSS与ePWM的联动是其最经典的应用。CTRIPH/L信号可以直接连接到ePWM的Trip Zone输入,实现硬件级的过流保护。配置ePWM的Trip Zone为单次触发模式后,一旦CMPSS输出跳变,ePWM会立即强制其输出引脚进入预设的安全状态(高、低或高阻),并且这个状态会一直保持,直到软件清除Trip标志。这种响应速度是软件中断无法比拟的。

更高级的用法是利用EPWMSYNCPEREPWMBLANK信号。

  • EPWMSYNCPER:用于同步DAC影子寄存器的加载和斜坡发生器的重启,确保每个PWM周期阈值更新的一致性。
  • EPWMBLANK:用于扩展LATCHCLR信号。在电机驱动中,功率管开关瞬间会产生巨大的电压尖峰和噪声(即“Blanking Time”)。在此期间,我们希望屏蔽CMPSS的触发,防止误保护。可以将ePWM的BLANK窗口信号连接到CMPSS,在这个窗口内,即使比较器跳变,其输出也会被强制清零。

4.3 常见问题排查速查表

在实际调试中,CMPSS的问题往往表现为“该触发时不触发”或“不该触发时乱触发”。下面是一个快速排查指南:

现象可能原因排查步骤与解决方法
比较器无输出1. 模块时钟未使能。
2.COMPCTL.COMPDACE未置1。
3. 输入电压未超过DAC阈值(或逻辑反了)。
4. 输出路径选择错误。
1. 检查SysCtl_enablePeripheral
2. 确认COMPCTL配置。
3. 用万用表测量CMPINxP引脚电压,计算并确认DACVAL设置正确。检查COMPHINV位。
4. 检查CTRIPxSELCTRIPOUTxSEL位,并用示波器或GPIO回读验证。
输出持续为高/低1. 输入引脚配置错误(仍是GPIO功能)。
2. DAC未正确输出。检查DACSOURCESWLOADSEL
3. 数字滤波器初始化异常。
1. 检查GPIO复用配置,确保引脚已设置为模拟比较器输入功能。
2. 如果使用斜坡发生器,检查RAMPSTS寄存器是否在变化。如果使用软件DAC,检查影子/有效寄存器加载机制。
3. 尝试设置FILINIT位,或暂时旁路滤波器(SAMPWIN=0, THRESH=0)。
触发不准确,有偏移1. 未进行偏移校准。
2. DAC参考电压DACREF选择错误或波动。
3. 输入信号路径阻抗过大,导致压降。
1. 执行前述的校准流程。
2. 确认COMPDACCTL[SELREF]设置,测量VDDAVDAC电压是否稳定。
3. 检查采样电路,确保运放驱动能力足够,走线短且粗。
在噪声环境下频繁误触发1. 数字滤波器未启用或参数过松。
2. 未启用输入迟滞。
1. 根据噪声特征调整SAMPWINTHRESH,增加滤波深度。用示波器观察CMPINxP信号,评估噪声宽度。
2. 尝试启用COMPHYSCTL中的迟滞功能,增加比较器的抗噪能力。
斜坡发生器不工作1.DACSOURCE未设置为1。
2. 未收到EPWMSYNCPER同步信号。
3.RAMPMAXREFSRAMPDECVALA为0。
1. 检查COMPDACCTL[DACSOURCE]
2. 检查COMPDACCTL[RAMPSOURCE]配置的ePWM模块是否已正确配置并运行。用寄存器或示波器检查EPWMSYNCPER信号。
3. 检查斜坡相关寄存器的值。
同时使用高低比较器时相互干扰违反了DAC设置禁忌。严格遵守:若只使用高比较器,DACLVALS必须设为0;若只使用低比较器,DACHVALS必须设为0xFFF。检查寄存器配置。

调试CMPSS,示波器代码调试器是黄金搭档。示波器用来观察模拟输入、DAC输出(如果芯片有测试点)以及最终的CTRIPOUTx数字信号。调试器则用于实时监控和修改关键寄存器(如RAMPSTSCOMPSTS),观察其动态变化是否符合预期。从我的经验来看,大部分CMPSS的问题都源于对数据流和同步机制的理解偏差,耐心地对照框图,一步步跟踪信号路径,总能找到症结所在。