TMS320F28003x CMPSS数字滤波器原理、配置与校准实战

发布时间:2026/7/20 10:09:13
TMS320F28003x CMPSS数字滤波器原理、配置与校准实战 1. 项目概述与核心价值在电机驱动、数字电源或者任何需要高精度实时保护的嵌入式控制系统中我们总会遇到一个让人头疼的问题来自传感器或比较器的模拟信号常常伴随着各种毛刺和噪声。这些瞬间的干扰如果直接用来触发保护或者控制PWM轻则导致系统误动作、性能波动重则可能直接损坏功率器件。我经历过不止一次因为一个尖峰噪声导致IGBT直通炸管的惨痛教训所以对信号滤波这件事格外上心。TMS320F28003x这款TI的明星级实时微控制器其内置的比较器子系统CMPSS里集成了一个相当精巧的数字滤波器模块。它不像软件滤波那样消耗宝贵的CPU周期而是在硬件层面通过一个基于多数表决Majority Vote算法的FIFO采样窗口对比较器的原始输出进行“去抖”和“整形”。这个模块的核心价值在于它用纯硬件的方式在信号进入后续的数字逻辑比如触发ePWM的Trip、产生中断之前就把不可靠的瞬态干扰给过滤掉了极大地提升了系统的鲁棒性和可靠性。理解并熟练配置这个数字滤波器是玩转F28003x进行高性能实时控制的关键一步。它不仅仅是配置几个寄存器那么简单其背后的采样窗口、阈值设定、时钟同步以及与斜坡发生器的联动共同构成了一套应对复杂电磁环境的信号调理方案。接下来我就结合手册里的原理图和多年的调试经验把这个滤波器的里里外外、配置要点和那些容易踩坑的细节给大家掰开揉碎了讲清楚。2. 数字滤波器核心原理与工作机制拆解2.1 多数表决算法硬件实现的“民主决策”CMPSS数字滤波器的核心思想非常直观它不相信一次采样的结果而是相信一段时间内“大多数”样本的倾向。这就像开会表决不是一个人说了算而是要看多数人的意见。滤波器内部维护着一个先进先出FIFO的采样窗口其大小由SAMPWIN寄存器定义。但这里有一个非常重要的细节实际使用的窗口大小是SAMPWIN 1。例如你设置SAMPWIN 9那么硬件实际监控的是连续10个样本。手册里特别强调了这一点对于THRESH阈值和CLKPRESCALE时钟预分频也是同样的“1”规则这个偏移量是理解所有计算的基础千万不能忽略。滤波器以固定的速率由系统时钟SYSCLK和CLKPRESCALE决定对比较器的原始输出0或1进行采样并将样本压入这个FIFO窗口。同时最老的样本会被丢弃窗口始终保持着最新的SAMPWIN1个样本。滤波器的输出是否翻转取决于一个称为“阈值”THRESH的参数。同样实际生效的阈值是THRESH 1。它的判定逻辑可以用一段非常清晰的C伪代码来描述这也是手册里给出的精髓if (FILTER_OUTPUT 0) { if (Num_1s_in_SAMPWIN THRESH) { FILTER_OUTPUT 1; } } else { if (Num_0s_in_SAMPWIN THRESH) { FILTER_OUTPUT 0; } }这段代码揭示了两个关键点非对称性判断逻辑取决于当前输出状态。当输出为0时只关心窗口内“1”的数量是否达到阈值当输出为1时只关心“0”的数量。这确保了状态翻转需要足够的“证据”。滞后效应一旦输出翻转要再次翻回来同样需要满足相反电平的样本数达到阈值。这本身就带来了一定的滞后特性有助于抑制信号在阈值附近的抖动。2.2 参数约束与物理意义要让这个“民主表决”机制正常工作参数设置必须满足基本规则THRESH必须大于SAMPWIN/2且小于等于SAMPWIN。为什么必须大于一半这是“多数”的数学定义。如果阈值小于或等于一半比如在10个样本的窗口中设置阈值为5实际为6那么可能5个“1”和5个“0”就能触发翻转这失去了多数表决的意义抗干扰能力会大大减弱。通常我们会设置THRESH SAMPWIN这意味着需要窗口内所有样本都是相反电平时才翻转这是最严格的滤波但响应也最慢。CLKPRESCALE决定了“开会”的频率它定义了每隔多少个SYSCLK周期采集一个样本。实际采样周期 (CLKPRESCALE 1) * T_sysclk。这个参数直接决定了滤波器能有效滤除的噪声脉冲的最大宽度。例如如果你的系统时钟是100MHzT_sysclk10ns设置CLKPRESCALE99那么采样周期就是1us。理论上宽度小于1us的孤立毛刺有很大概率被滤除除非它恰好覆盖了多个采样点并凑够了阈值。2.3 从原理图到行为理解手册中的图18-6非常形象地展示了这个过程。我们假设SAMPWIN9窗口10样本THRESH5阈值6。例一输出为1当前输出是1。某时刻窗口内10个样本中有8个是0。由于当前输出是1判断条件看“0”的数量是否≥6。8≥6条件满足因此滤波器输出翻转为0。例二输出保持1输出为1窗口内有6个0。6等于阈值条件满足输出翻转为0。例三输出保持0此时输出已是0。窗口内出现5个1。判断逻辑变为当前输出为0看“1”的数量是否≥6。56条件不满足因此输出保持为0不变。这就是“未达到多数维持原状”的体现。这个例子清晰地展示了滤波器输出不会因为噪声的偶尔出现而轻易翻转必须达到“压倒性”的证据才会改变状态。3. 滤波器配置详解与实操步骤理解了原理配置起来就有了方向。手册18.5.1节给出了推荐的初始化序列我们结合寄存器来细化每一步。3.1 初始化序列与寄存器配置第一步配置并使能比较器这是前置工作。通过COMPCTL寄存器配置比较器例如选择输入源内部DAC还是外部引脚、是否使能迟滞 (COMPHYSCTL)、是否输出取反等。最关键的是将COMPCTL.COMPDACE位置1使能比较器/DAC模块。// 示例使能高边比较器负端使用内部DAC不取反 Cmpss1Regs.COMPCTL.bit.COMPHSOURCE 0; // 负端输入来自内部DAC Cmpss1Regs.COMPCTL.bit.COMPHINV 0; // 输出不取反 Cmpss1Regs.COMPCTL.bit.COMPDACE 1; // 使能比较器和DAC第二步配置数字滤波器参数这是核心配置针对高 (CTRIPH) 和低 (CTRIPL) 比较器路径是独立配置的寄存器分别为CTRIPHFILCTL/CTRIPLFILCTL和CTRIPHFILCLKCTL/CTRIPLFILCLKCTL。设置采样窗口 (SAMPWIN)决定“民意调查”的样本数量。需要根据你期望滤除的噪声特性和系统允许的响应延迟来权衡。值越大滤波效果越好但信号变化的响应越慢。// 设置高边滤波器采样窗口为7实际窗口8个样本 Cmpss1Regs.CTRIPHFILCTL.bit.SAMPWIN 7;设置表决阈值 (THRESH)决定“多数”的门槛。必须满足SAMPWIN/2 THRESH SAMPWIN。为了强滤波常设置为THRESH SAMPWIN即全票通过才翻转。// 设置高边滤波器阈值为7实际需要8个样本全为相反电平才翻转 Cmpss1Regs.CTRIPHFILCTL.bit.THRESH 7; // SAMPWIN7, THRESH7 满足条件设置时钟预分频 (CLKPRESCALE)决定采样频率。这决定了滤波器能滤除多宽的噪声。滤波宽度 ≈ (CLKPRESCALE 1) * (SAMPWIN 1 - THRESH) * T_sysclk。这是一个近似值因为噪声需要持续足够长时间以覆盖够多的采样点。// 系统时钟100MHz希望采样周期约1us则 CLKPRESCALE 1us / 10ns - 1 99 Cmpss1Regs.CTRIPHFILCLKCTL.bit.CLKPRESCALE 99;第三步初始化滤波器FIFO (FILINIT)这是一个容易忽略但至关重要的步骤。上电或重新配置滤波器后FIFO窗口里的内容是未知的可能导致输出立即产生一个错误的跳变。通过将CTRIPxFILCTL.FILINIT位置1可以将FIFO窗口内的所有样本初始化为当前时刻的滤波器输入值即同步器后的比较器输出。这确保了滤波器从一个确定的状态开始工作。// 初始化高边滤波器FIFO Cmpss1Regs.CTRIPHFILCTL.bit.FILINIT 1; // 该位是自清零的硬件操作完成后会自动清零无需软件清除。第四步清除比较器状态锁存 (COMPSTSCLR)如果你打算使用锁存后的滤波器输出即CTRIPxSEL或CTRIPOUTxSEL配置为3那么需要在上电后清除可能存在的旧锁存状态。通过向COMPSTSCLR.HLATCHCLR或LLATCHCLR写1来实现一个单脉冲清除。// 清除高边比较器输出锁存 Cmpss1Regs.COMPSTSCLR.bit.HLATCHCLR 1;第五、六步配置信号路径与目的地选择滤波后的信号何去何从。通过COMPCTL寄存器的CTRIPHSEL,CTRIPOUTHSEL(高边) 和CTRIPLSEL,CTRIPOUTLSEL(低边) 字段你可以选择将异步比较器输出(0)、同步后输出(1)、滤波器直接输出(2)或滤波器锁存输出(3)连接到内部的CTRIP和CTRIPOUT信号。// 将高边滤波器的锁存输出连接到CTRIPH和CTRIPOUTH Cmpss1Regs.COMPCTL.bit.CTRIPHSEL 3; // CTRIPH 来源锁存的滤波器输出 Cmpss1Regs.COMPCTL.bit.CTRIPOUTHSEL 3; // CTRIPOUTH 来源锁存的滤波器输出最后你需要将这些CTRIP或CTRIPOUT信号通过X-BAR交叉开关路由到目标外设例如ePWM模块的Trip输入或者输出到GPIO。3.2 参数计算实例设计一个滤除100ns毛刺的滤波器假设你的应用场景是电机相电流保护比较器输出可能因开关噪声产生宽度约100ns的毛刺。系统时钟SYSCLK 200MHz(T_sysclk 5ns)。目标是设计一个滤波器能可靠滤除宽度小于150ns的干扰。确定采样周期为了捕捉并否决一个毛刺我们希望毛刺持续时间覆盖的采样点越少越好。但采样周期也不能太慢否则会影响正常信号的响应。一个经验法则是让采样周期略小于待滤除毛刺的宽度。这里我们选择采样周期T_sample 80ns。计算CLKPRESCALECLKPRESCALE T_sample / T_sysclk - 1 80ns / 5ns - 1 15。所以设置CLKPRESCALE 15实际周期为(151)*5ns80ns。确定窗口大小与阈值我们希望毛刺假设全为错误电平即使连续出现也无法在窗口内达到多数。一个150ns的毛刺在80ns的采样周期下最多覆盖ceil(150ns / 80ns) 2个采样点。因此只要阈值要求大于2即可滤除。为了留有余量并保证对真实信号的响应我们选择SAMPWIN 45个样本窗口THRESH 4需要5个相同样本才翻转。这样毛刺最多贡献2个错误样本远达不到5个的要求。计算滤波器响应延迟最坏情况下当真实信号变化时滤波器需要等待一个新的“多数”形成。假设信号从0变为1且变化恰好发生在一个采样点之后。那么滤波器需要等待接下来的5个采样点都是1输出才会翻转为1。因此最坏响应时间T_response_max (SAMPWIN1) * T_sample 5 * 80ns 400ns。这个延迟对于大多数电流保护环来说是可以接受的。通过这个实例你可以看到如何将实际的抗干扰需求转化为具体的寄存器参数。这个过程是滤波器设计的核心。4. 与ePWM的联动及延迟分析在电机控制和数字电源中CMPSS常常与ePWM模块紧密配合实现基于电流或电压的实时保护Trip。手册18.6节详细介绍了这几个关键的联动信号。4.1 关键控制信号LATCHCLR, EPWMSYNCPER, EPWMBLANKLATCHCLR这是一个复位信号用于将数字滤波器、同步块和锁存输出复位到0。它可以通过软件直接置位xLATCHCLR位产生也可以由EPWMSYNCPER信号在使能 (xSYNCCLREN1) 时触发。这常用于在每个PWM周期开始时清除上一个周期的保护锁存状态实现周期性的保护复位。EPWMSYNCPER来自ePWM时基子模块的周期同步信号。当COMPDACCTL.SWLOADSEL1时它还可以用于触发内部DAC值 (DACxVALA) 从影子寄存器 (DACxVALS) 的加载。一个非常重要的警告如果ePWM的计数器 (TBCTR) 和周期寄存器 (TBPRD) 都设为0EPWMSYNCPER会保持高电平导致DAC立即加载这可能不是你想要的行为。因此务必先配置好ePWM模块再设置SWLOADSEL1。EPWMBLANK来自ePWM数字比较子模块的空白区信号。当使能BLANKEN后EPWMBLANK信号可以用于扩展LATCHCLR的有效时间这在需要更长复位时间的场合很有用。4.2 同步与滤波带来的信号延迟任何数字处理都会引入延迟CMPSS路径上的延迟必须被考虑尤其是在设计高速保护电路时。手册18.6.2节给出了明确的延迟同步器延迟1-2个系统时钟周期 (sysclks)。这是将模拟比较器输出同步到数字域所必需的。数字滤波器延迟如果滤波器被旁路所有参数为0固定为2个sysclks。如果使能滤波器延迟主要取决于滤波器参数最坏情况如上一节计算的T_response_max但至少也会有几个sysclks的固定处理延迟。锁存延迟1个sysclk。总延迟估算假设系统时钟100MHz滤波器旁路则路径延迟至少为(1~2) 2 1 4~5个 sysclks即40ns~50ns。如果使能了滤波器延迟会显著增加需要根据SAMPWIN和CLKPRESCALE计算。在计算保护触发到PWM关闭的总体响应时间时必须加上这段CMPSS内部延迟。5. CMPSS校准实战消除偏移误差手册18.6.3节指出了CMPSS存在两种偏移误差比较器本身的输入参考偏移误差Input referred offset error和内部DAC的静态偏移误差Static offset error。当使用内部DAC作为比较器负端输入时我们主要关心并校准的是DAC的静态偏移误差因为它已经包含了比较器的偏移。不进行校准的后果是你以为DAC输出1.000V时比较器会翻转但实际上可能需要1.015V或0.985V这直接导致过流保护点不准系统存在安全隐患或性能下降。5.1 校准前的准备工作稳定的直流信号在比较器正端非反相输入端施加一个稳定、低噪声的直流电压V_target。这可以是你要监控的电压阈值或者一个已知的参考电压。禁用迟滞将COMPHYSCTL.COMPHYS设为0暂时关闭比较器迟滞功能让翻转点更清晰。校准完成后再根据需求重新使能。启用滤波器如果输入信号有噪声务必启用数字滤波器设置非零的SAMPWIN,THRESH并使用锁存输出 (CTRIPxSEL3)以确保校准逻辑检测到的是稳定的翻转状态而不是噪声。5.2 校准流程详解下法手册推荐了一种“下扫法”校准流程其核心思想是逐步降低DAC输出值直到比较器状态发生翻转。以下是基于此流程的详细步骤和代码思路步骤1设置初始DAC值将DAC值设置为最大值0xFFF对应参考电压VDDA或VDAC。这确保DAC初始电压高于正端电压V_target比较器输出为低假设正端接信号负端接DAC比较器输出高有效。Cmpss1Regs.DACHVALS 0xFFF; // 写入影子寄存器 Cmpss1Regs.COMPDACCTL.bit.SWLOADSEL 0; // 选择SYSCLK加载立即生效 // 或者通过触发EPWMSYNCPER加载取决于你的DAC更新策略步骤2-7循环递减与检测uint16_t dac_code 0xFFF; uint16_t trip_code 0xFFFF; // 用于存储找到的跳变点 bool trip_found false; // 可选如果知道V_target的大致电压可以计算一个更接近的起始DAC值加快校准。 // uint16_t estimated_code (V_target / V_ref) * 4095 margin; while ((dac_code 0) !trip_found) { dac_code--; // 步骤2递减DAC值 Cmpss1Regs.DACHVALS dac_code; // 步骤3等待DAC稳定。需要等待几个us具体时间参考数据手册DAC建立时间。 DELAY_US(5); // 示例延时 // 步骤4清除锁存状态准备检测新的比较结果 Cmpss1Regs.COMPSTSCLR.bit.HLATCHCLR 1; // 步骤5等待一段时间允许锁存可能被置位 DELAY_US(1); // 等待时间应大于滤波器响应时间路径延迟 // 步骤6检查锁存状态 if (Cmpss1Regs.COMPSTS.bit.COMPHLATCH 1) { trip_found true; trip_code dac_code; // 记录跳变点 // 可选的双重验证步骤 // dac_code; // 增加1 // ... 设置DAC清除锁存等待检查锁存是否清零。 // 如果清零则 trip_code 有效否则可能需要调整阈值。 } // 步骤7如果未触发循环继续 } if (trip_found) { // 校准成功trip_code 就是当输入为 V_target 时DAC的实际输出码值。 // 偏移误差 (理论码值 - trip_code) * LSB // 后续应用中设置保护DAC值时需要补偿这个偏移。 } else { // 校准失败可能信号连接有问题或V_target超出DAC范围。 }校准结果的应用找到的trip_code是使比较器在V_target输入下翻转的实际DAC码。假设V_target是你期望的2.5V过流点理论DAC码应为(2.5V / 3.3V) * 4095 ≈ 3102。如果校准得到的trip_code是3080那么偏移约为(3102-3080) * (3.3V/4095) ≈ 1.8mV。在实际设置过流点时你应该使用理论码值 - (理论码值 - trip_code) trip_code来直接设定DAC或者在软件中将计算出的理论值加上这个偏移量。5.3 校准注意事项与常见问题噪声影响如果V_target有噪声即使启用滤波器也可能导致在翻转点附近检测到多次跳变使trip_code不确定。解决办法是增加滤波器的严格度增大SAMPWIN和THRESH或对V_target进行硬件滤波。DAC建立时间步骤3中的等待至关重要。DAC从代码更新到电压稳定输出需要时间必须等待足够长查阅数据手册的DAC建立时间参数通常为几微秒否则会误判。双端输入校准如果比较器两端都接外部引脚校准流程类似但需要外部电路来精确扫描负端输入电压通常更复杂。温度漂移偏移误差会随温度变化。对于高精度应用可能需要在不同工作温度下进行校准并存储补偿曲线。6. 常见问题排查与调试技巧在实际项目中配置和使用CMPSS数字滤波器时总会遇到一些意想不到的情况。下面是我总结的几个典型问题及排查思路。6.1 滤波器似乎没有工作输出跟随输入抖动可能原因1滤波器参数配置错误。检查SAMPWIN和THRESH是否满足SAMPWIN/2 THRESH SAMPWIN的关系。一个常见的错误是设置了SAMPWIN0且THRESH0这实际上旁路了滤波器手册指出旁路时固定延迟2个sysclks。可能原因2信号路径选择错误。你配置了滤波器参数但CTRIPxSEL或CTRIPOUTxSEL可能仍然选择的是异步 (0) 或同步 (1) 路径而不是滤波器输出 (2) 或锁存输出 (3)。务必确认路径指向滤波器。可能原因3FILINIT未初始化。上电后FIFO内容随机可能导致初始状态异常。确保在配置参数后执行了FILINIT1的操作。排查方法使用CCS的寄存器观察窗口监控COMPSTS.COMPHSTS滤波器直接输出和COMPSTS.COMPHLATCH锁存输出的状态。注入一个已知宽度的脉冲观察这些位是否如预期那样保持稳定。6.2 校准流程无法找到跳变点trip_code可能原因1信号极性弄反。检查比较器正负输入端连接。如果V_target接在负端而DAC接在正端逻辑是反的。确保你理解COMPHINV位的设置以及你期待的翻转逻辑。可能原因2DAC参考源选择错误。检查COMPDACCTL.SELREF位。DAC输出电压 (DAC_VAL / 4095) * V_ref。如果你期望V_ref是VDDA3.3V但实际选择了VDAC通常也是3.3V但需确认可能没问题。但如果VDAC未使能或电压不对DAC输出就不对。可能原因3电压范围不匹配。V_target可能超出了DAC的输出范围0~V_ref或者非常接近边界导致在整个扫描范围内都无法翻转。可能原因4硬件连接问题。使用万用表测量DAC输出引脚电压确认其随着代码变化而变化。测量比较器正端输入电压确认是稳定的V_target。排查方法先简化问题。将DAC输出通过一个运放缓冲后直接接到比较器正端负端接一个固定的中间电压。编写一个简单循环让DAC输出一个三角波用示波器同时观察DAC输出和比较器输出GPIO直观地查看翻转点这能快速排除软件配置以外的硬件问题。6.3 与ePWM联动的保护功能不正常可能原因1LATCHCLR信号冲突。如果你使能了EPWMSYNCPER来清除锁存 (xSYNCCLREN1)同时又用软件周期性写xLATCHCLR可能导致锁存意外被清除无法触发保护。检查信号源确保只有一个有效的清除机制。可能原因2ePWM Trip输入路径未正确配置。CMPSS产生的CTRIPH/L信号需要通过X-BAR路由到ePWM模块的Trip输入。确保X-BAR的配置正确并且ePWM模块内的Trip子模块已使能并配置为相应的动作如强制高、强制低、高阻。可能原因3延迟未考虑。CMPSS的滤波延迟、同步延迟加上ePWM从Trip信号生效到PWM实际关闭的延迟可能导致总体保护响应时间过长。对于非常快速的过流如直通这个延迟可能无法有效保护。需要计算总延迟并与功率器件允许的短路承受时间进行比较。排查方法利用ePWM的Trip标志位和CMPSS的状态寄存器进行联合调试。在CCS中设置断点或状态触发当保护发生时同时捕获CMPSS的COMPHLATCH和ePWM的TZFLG寄存器分析两者的时间关系和逻辑关系。也可以用示波器同时观察比较器输入、CMPSS输出GPIO和PWM引脚直观分析时序。6.4 寄存器写入无效或系统异常可能原因EALLOW保护。CMPSS的许多关键配置寄存器如COMPCTL,COMPDACCTL,CTRIPxFILCTL等受EALLOW保护。在写入这些寄存器前必须调用EALLOW;指令写入后再调用EDIS;指令。EALLOW; Cmpss1Regs.COMPCTL.all 0x...; // 你的配置值 Cmpss1Regs.CTRIPHFILCTL.all 0x...; EDIS;忘记EALLOW是新手最常见问题之一会导致配置不生效。调试CMPSS数字滤波器核心是“化整为零逐级验证”。先从最简单的旁路滤波器、直接输出开始用示波器验证比较器基本功能然后逐步加入滤波器验证滤波效果再配置与ePWM的联动最后进行校准。每一步都通过寄存器状态和硬件信号进行双重确认就能高效地定位并解决问题。