
1. SDFM数字滤波器从噪声中提取信号的“投票机”在电机控制、高精度电源或者任何需要精确测量模拟量的嵌入式系统里我们常常会遇到一个头疼的问题信号太“脏”了。传感器传回来的信号上叠加着各种开关噪声、电磁干扰就像在一个嘈杂的菜市场里想听清一个人说话。这时候光靠硬件上的RC滤波往往不够我们需要在芯片内部用数字的方式再做一次深度“清洁”。TMS320F28003x里的Sigma-Delta滤波器模块SDFM就是TI为我们准备的这样一位强大的“清洁工”兼“裁判员”。SDFM的核心任务是处理来自外部Σ-Δ调制器比如AMC1306的高速单比特数据流将其还原成高分辨率的数字量。但在这个过程中调制器时钟可能丢失数据可能异常我们需要及时知道。这就引出了两个关键部分数字滤波器和中断单元。数字滤波器负责“去噪”和“判决”而中断单元则是系统的“哨兵”及时报告“数据准备好了”或者“出问题了”。今天我们就深入SDFM的内部掰开揉碎地讲讲它的数字滤波器到底是怎么通过“投票”来稳定信号的以及如何配置那些令人眼花缭乱的中断让你的系统既稳健又灵敏。无论你是正在调试电机相电流采样还是设计一个高精度电压检测回路这篇文章都能帮你避开我当年踩过的那些坑。2. 数字滤波器工作原理多数表决与抗扰设计2.1 核心概念采样窗口与多数表决SDFM的数字滤波器其工作逻辑非常直观就像一个实时投票系统。它并不复杂高深但极其有效。想象一下你有一个大小为(SAMPWIN 1)的滑动窗口FIFO这个窗口持续观察输入信号来自比较器事件如CEVT1/CEVT2。每隔CLKPRESCALE个系统时钟周期窗口会移入一个新的采样值0或1并丢弃一个最旧的值。滤波器的输出不是简单地跟随最新输入而是基于整个窗口内的“民意”来决定。它有一个预设的阈值THRESH。只有当窗口内相反状态的样本数量达到或超过这个THRESH时滤波器的输出才会改变状态。如果达不到这个“多数派”要求输出就保持原样。官方文档里那段等效的C代码是理解的关键if (FILTER_OUTPUT 0) { if (Num_1s_in_SAMPWIN THRESH) { FILTER_OUTPUT 1; } } else { if (Num_0s_in_SAMPWIN THRESH) { FILTER_OUTPUT 0; } }这里有个至关重要的细节代码里判断的是Num_1s_in_SAMPWIN或Num_0s_in_SAMPWIN也就是窗口内与当前输出状态相反的样本数。如果当前输出是0它关心的是有多少个1如果当前输出是1它关心的是有多少个0。只有反对方票数足够多≥THRESH才会触发输出翻转。这确保了状态转换需要持续的、强有力的证据瞬间的毛刺无法改变输出。2.2 关键参数设计SAMPWIN与THRESH的权衡理解了原理配置参数就成了核心。这里有两个黄金法则THRESH SAMPWIN / 2这是硬件的要求也是逻辑的必然。阈值必须严格大于窗口大小的一半。如果阈值等于或小于一半可能会出现“平票”或“微弱优势就翻盘”的情况导致输出在噪声边缘反复振荡失去滤波意义。例如SAMPWIN7窗口8个样本那么THRESH最小必须设置为4但为了更稳定通常设置为5或6。响应速度 vs. 抗噪能力这是一个经典的权衡。增大SAMPWIN窗口越大观察的历史数据越多抗突发噪声的能力越强但系统对真实信号变化的响应也越慢延迟增加。增大THRESH在窗口大小固定时提高阈值意味着需要更一致的证据才能改变输出抗噪能力增强但同样会减慢对真实变化的响应。减小CLKPRESCALE提高采样频率可以让窗口更快地更新能更快地反映变化但对系统时钟资源消耗更大且可能采集到更多高频噪声。实操心得在电机控制中用于过流保护的比较器滤波器我通常将SAMPWIN设置得较小比如3或4THRESH设置为SAMPWIN即需要窗口内全部样本一致才翻转CLKPRESCALE根据系统时钟和噪声频率适当选取。这样能在保证一定抗噪性的前提下实现最快的故障响应。而对于非关键的数据滤波则可以放宽要求追求更好的平滑效果。2.3 滤波器初始化确保起点正确数字滤波器在上电或复位后其内部的FIFO样本是未知的。如果直接开始工作可能会因为初始垃圾数据而产生错误的输出跳变。因此手册强调了一个初始化序列配置参数先设置好SAMPWIN、THRESH和CLKPRESCALE。执行初始化将FILINIT位在SDCOMPxEVT1FLTCTL或SDCOMPxEVT2FLTCTL寄存器中置1。这个操作会将当前输入信号的值填充到整个滤波器的FIFO窗口中。务必确保在使能滤波器或中断之前完成此操作。注意事项FILINIT是一个“写1置位、自动清零”的位。你只需要写1硬件完成初始化后会将其清零。在代码中这是一个单次操作不应放在循环或中断服务程序中。3. 理论输出计算从调制器电压到数字值SDFM的强大之处在于它不仅能做比较过压、欠压判断还能通过数据滤波器输出高精度的数值。理解其理论输出是进行标定和量程转换的基础。3.1 核心计算公式解析手册给出了从模拟输入电压到最终滤波器输出值的完整计算链。我们结合AMC1306x25这个常用调制器的例子来走一遍比特流密度计算密度 (输入电压 Vclipping) / (2 * Vclipping)Vclipping调制器的最大差分输入电压范围。对于AMC1306x25这是±320mV即Vclipping 320mV。输入电压实际施加的差分电压AINP - AINN。例子中输入电压100mV代入得密度 (100mV 320mV) / (2 * 320mV) 420 / 640 0.65625。这个值表示在比特流中“1”所占的比例。比较器滤波器输出比较器输出 密度 * 最大滤波器输出(滤波器类型, COSR)最大滤波器输出这是一个与所选滤波器结构Sinc1, Sinc2, Sinc3和比较器过采样率COSR相关的常数。对于Sinc3最大值 (COSR)^3。例子中滤波器类型Sinc3COSR32则最大输出为32^3 32768。计算得比较器输出 0.65625 * 32768 21504。这个值会与设定的高/低阈值HLT/LLT进行比较产生CEVT事件。数据滤波器输出32位滤波器输出_32位 |输入电压| / Vclipping * 最大滤波器输出(滤波器类型, DOSR)最大滤波器输出同理对于数据滤波器其最大值与滤波器类型和数据过采样率DOSR有关。对于Sinc3最大值 (DOSR)^3。例子中DOSR100则最大输出为100^3 1,000,000。计算得滤波器输出_32位 (100mV / 320mV) * 1,000,000 312500。符号处理如果输入电压为负则最终输出的32位结果是上述计算值的二进制补码。数据滤波器输出16位滤波器输出_16位 滤波器输出_32位 移位值(滤波器类型, OSR)为了将内部高精度数据适配到16位寄存器或总线需要进行右移。移位值同样取决于滤波器类型和OSR。例子中对于Sinc3和DOSR100移位值为5。计算得滤波器输出_16位 312500 5 9765。这个值就是你从SDDATAx.DATA16寄存器中读到的结果。3.2 设计中的计算应用这些公式不是用来在运行时计算的而是用于设计阶段的参数选择和预期值验证。量程匹配假设你的信号范围是±200mV使用AMC1306x25±320mV。当输入为200mV时根据公式32位输出应为(200/320)*1,000,000 625,000。你需要确保这个值不会超过Sinc3滤波器在设定DOSR下的理论最大值并留有一定余量。移位值选择16位模式下移位值SDDPARMx.SH的配置至关重要。移少了数据可能溢出移多了分辨率损失严重。通常你可以根据满量程输入对应的32位理论输出值计算其所需位数然后决定右移多少位能将其适配到16位有符号数范围-32768 ~ 32767。例如上例中625,000约需20位表示2^195242882^201048576右移5位除以32后约为19531在16位范围内。阈值设定比较器滤波器的阈值HLT/LLT设置就可以基于此理论计算。如果你希望在电流达到±50A时触发保护而你的传感器和调制器链路对应输出电压为±100mV那么就可以计算出此时比较器滤波器的理论输出值并将其设置为阈值。4. 中断系统详解系统的“眼睛”与“耳朵”SDFM的中断系统是其作为“哨兵”的核心分为两大类错误中断SDy_ERR和数据就绪中断SDy_DRINTx。配置不当要么是故障发生了你都不知道要么是CPU被无用的中断频繁打断。4.1 错误中断SDy_ERR监控异常状态SDy_ERR是一个聚合中断任何使能了的错误事件都会触发它。它监控四种可能的问题比较器事件CEVT1/CEVT2当数据滤波器的输出超过高阈值HLT或低于低阈值LLT时触发。这常用于实现硬件级的过压、欠压或过流保护响应速度极快无需软件轮询。配置要点需要使能主中断SDCTL.MIE1和对应通道的比较器事件中断SDCPARMx.EN_CEVT1/21。阈值在SDFLTxCMPH1/LL1等寄存器中设置。调制器故障MFx当外部Σ-Δ调制器的时钟SD-Cx丢失超过64个SYSCLK周期时触发。这通常意味着传感器链路断开或严重故障。配置要点使能主中断和调制器故障中断使能位SDCPARMx.MFIE1。FIFO溢出SDFFOVFx当数据滤波器的FIFO中积压的数据超过其最大深度16个字时触发。这意味着CPU或DMA读取数据的速度跟不上数据产生的速度。配置要点需要先使能FIFOSDFIFOCTLx.FFEN1再使能FIFO溢出中断SDFIFOCTLx.OVFIEN1最后使能主中断。高阈值Z事件HZx这是一个特殊的比较事件通常用于检测过零Zero-Crossing或其他固定阈值但它不直接产生中断其状态反映在SDSTATUS.HZx位。它可以被用作触发其他事件的条件。关键操作流程中断标志任何事件发生时对应的标志位会在SDIFLG寄存器中置位。中断清除必须在中断服务程序ISR中手动清除标志位通过向SDIFLGCLR寄存器的对应位写1。这里有个硬件优先级问题如果在你写1清除的同一个周期硬件试图再次置位该标志硬件优先标志位将不会被清除。因此你的清除操作应确保在中断条件已消除后进行或者采用“读取-判断-清除”的稳健流程。4.2 数据就绪中断SDy_DRINTx高效的数据搬运触发器这是你获取转换结果的主要方式。每个数据滤波器通道x1~4都可以产生自己的数据就绪中断。其触发源有两种选择通过SDFIFOCTLx.DRINTSEL位配置非FIFO模式DRINTSEL 0选择AFx应答标志作为中断源。每当一个新的数据滤波器结果准备好即完成了一次完整的OSR周期积分SDIFLG.AFx标志置位若使能SDDFPARMx.AE1则产生中断。在此模式下你需要在中断中读取SDDATAx寄存器来获取数据读取操作会自动清除AFx标志。FIFO模式DRINTSEL 1选择SDFFINTxFIFO中断作为中断源。这需要使能FIFOFFEN1和FIFO中断FFIEN1。当FIFO中存储的数据字数SDFFST达到或超过你预设的触发水平SDFFIL时SDFFINTx标志置位并产生中断。在此模式下你可以在中断中从SDDATFIFOx寄存器连续读取多个数据最多16个非常适合配合DMA进行批量传输极大减轻CPU负担。模式选择建议单次、低速、低优先级数据使用非FIFO模式配置简单。高速、连续采样或需降低中断频率强烈推荐使用FIFO模式。例如设置SDFFIL 8这样每采集8个数据才产生一次中断你一次读取8个数据中断开销降低为原来的1/8。这对于高频采样如音频或CPU负载敏感的应用至关重要。4.3 中断配置清单与避坑指南配置一个可用的中断需要环环相扣缺一不可。下面是一个配置数据就绪中断FIFO模式的检查清单全局使能配置PIE模块将SDFM的中断向量如SD1_DRINT1映射到对应的CPU中断线并启用PIE和CPU全局中断。SDFM模块使能确保数据滤波器已使能SDDFPARMx.FEN 1。FIFO配置设置SDFIFOCTLx.FFEN 1使能FIFO。设置SDFIFOCTLx.DRINTSEL 1选择FIFO中断源。设置SDFIFOCTLx.FFIEN 1使能FIFO中断。设置SDFIFOCTLx.SDFFIL为你期望的触发深度例如8。主中断使能针对错误中断如果还需要错误中断设置SDCTL.MIE 1。清除残留标志在初始化最后读取SDIFLG寄存器然后向SDIFLGCLR寄存器相应位写1清除所有可能残留的中断标志。编写ISR在中断服务程序中读取SDIFLG判断中断源。若为SDFFINTx则循环读取SDDATFIFOx直到SDFFST为0。必须向SDIFLGCLR寄存器的对应位写1以清除中断标志。常见坑点中断不触发最常见的原因是SDDFPARMx.FEN滤波器使能没有置1。滤波器不工作自然没有数据也就没有中断。中断标志无法清除确保你在ISR中清除的是SDIFLGCLR寄存器而不是SDIFLG。SDIFLG是只读的状态寄存器。FIFO溢出如果中断服务程序处理太慢或者SDFFIL设置过大而FIFO深度只有16就可能发生溢出。一旦溢出SDFFOVFx置位后续数据会丢失。解决方案优化ISR或降低数据输出率增大DOSR或提高SDFFIL触发值让中断更早发生。多个中断源竞争SDy_ERR是多个错误的或门输出。如果只处理了其中一个事件标志而忽略了其他同时发生的事件中断标志将无法彻底清除导致中断持续触发。ISR中应检查所有可能的错误标志位。5. 寄存器精讲与实战配置寄存器是操控硬件的直接界面。面对SDFM大量的寄存器无需畏惧我们将其分类攻克。以下表格整理了最核心的寄存器组及其功能寄存器类别核心寄存器示例功能描述关键配置位控制与状态SDCTL模块级控制MIE主误中断总使能SDSTATUS状态读取HZx高阈值Z事件状态数据滤波器配置SDDFPARMx滤波器参数SST[1:0]滤波器结构 (Sinc1/2/3/fast)DOSR[7:0]数据过采样率 (DOSR 值1)AE非FIFO数据就绪中断使能FEN滤波器使能SDDPARMx数据参数DR数据格式 (016位132位)SH[4:0]16位模式下的右移位数比较器滤波器配置SDCPARMx比较器参数CEN比较器使能COSR[4:0]比较器过采样率EN_CEVT1/2比较器事件中断使能CS1_CS0比较器滤波器结构SDFLTxCMPH1/LL1高低阈值HLT[14:0],LLT[14:0]主高低阈值SDFLTxCMPHZ高阈值ZHLTZ[14:0]用于过零检测等的阈值数字滤波器配置SDCOMPxEVT1FLTCTLSDCOMPxEVT2FLTCTL数字滤波器控制SAMPWIN[4:0]采样窗口大小 (N 值1)THRESH[4:0]表决阈值FILINIT滤波器初始化SDCOMPxEVT1FLTCLKCTLSDCOMPxEVT2FLTCLKCTL数字滤波器时钟控制CLKPRESCALE[9:0]采样时钟预分频FIFO控制SDFIFOCTLxFIFO控制与状态FFENFIFO使能DRINTSEL中断源选择 (0AFx, 1SDFFINTx)FFIENFIFO中断使能OVFIEN溢出中断使能SDFFIL[4:0]FIFO中断触发水平SDFFST[4:0]FIFO状态只读同步控制SDSYNCx滤波器同步WTSYNCEN等待同步使能SYNCSEL[5:0]选择同步信号源如PWM数据寄存器SDDATAx数据滤波器结果 (非FIFO)DATA16[15:0],DATA32HI[15:0]根据DR位格式读取SDDATFIFOx数据滤波器结果 (FIFO)从FIFO读取数据的寄存器SDCDATAx比较器滤波器结果DATA16[15:0]比较器输出的16位值中断标志SDIFLG中断标志状态所有中断事件的标志位只读SDIFLGCLR中断标志清除向对应位写1以清除SDIFLG中的标志5.1 配置流程示例设置一个带FIFO和过流保护的数据采集通道假设我们需要配置SDFM1的通道1Filter1用于电流采样数据滤波器为Sinc3DOSR256即SDDFPARM1.DOSR 255。输出为16位右移10位SDDPARM1.SH 10,DR0。使用FIFO模式半满8个字时触发中断。同时配置比较器滤波器用于硬件过流保护阈值设为0x6000对应约正满量程的75%。// 1. 使能滤波器并配置参数 (注意先配置后使能是良好习惯) Sdfm1Regs.SDDFPARM1.bit.SST 3; // Sinc3 滤波器 Sdfm1Regs.SDDFPARM1.bit.DOSR 255; // DOSR 2551 256 Sdfm1Regs.SDDFPARM1.bit.AE 0; // 使用FIFO中断故关闭AF中断 Sdfm1Regs.SDDFPARM1.bit.FEN 1; // 使能数据滤波器 Sdfm1Regs.SDDPARM1.bit.DR 0; // 16位数据格式 Sdfm1Regs.SDDPARM1.bit.SH 10; // 右移10位 (对于Sinc3, OSR256) // 2. 配置FIFO和中断 Sdfm1Regs.SDFIFOCTL1.bit.FFEN 1; // 使能FIFO Sdfm1Regs.SDFIFOCTL1.bit.DRINTSEL 1; // 中断源选择 FIFO Sdfm1Regs.SDFIFOCTL1.bit.FFIEN 1; // 使能FIFO中断 Sdfm1Regs.SDFIFOCTL1.bit.SDFFIL 8; // FIFO半满8个字时触发中断 Sdfm1Regs.SDFIFOCTL1.bit.OVFIEN 1; // 使能溢出中断建议开启 // 3. 配置比较器滤波器用于过流保护 Sdfm1Regs.SDCPARM1.bit.CEN 1; // 使能比较器滤波器 Sdfm1Regs.SDCPARM1.bit.COSR 31; // COSR 311 32 Sdfm1Regs.SDCPARM1.bit.CS1_CS0 3; // Sinc3 结构 Sdfm1Regs.SDCPARM1.bit.EN_CEVT1 1; // 使能高阈值事件中断 // 注意CEVT1SEL默认为00即COMPH1作为事件源这符合我们的需求。 Sdfm1Regs.SDFLT1CMPH1.bit.HLT 0x6000; // 设置过流高阈值 Sdfm1Regs.SDFLT1CMPL1.bit.LLT 0x0000; // 低阈值设为0或根据需求设为负阈值 // 4. 配置数字滤波器抗毛刺 Sdfm1Regs.SDCOMP1EVT1FLTCTL.bit.SAMPWIN 3; // 窗口大小 31 4 Sdfm1Regs.SDCOMP1EVT1FLTCTL.bit.THRESH 3; // 阈值 3 (需要4个样本中3个为1才翻转) Sdfm1Regs.SDCOMP1EVT1FLTCTL.bit.FILINIT 1; // 初始化滤波器FIFO Sdfm1Regs.SDCOMP1EVT1FLTCLKCTL.bit.CLKPRESCALE 9; // 采样时钟 SYSCLK / (91) // 5. 使能主错误中断覆盖CEVT1和FIFO溢出 Sdfm1Regs.SDCTL.bit.MIE 1; // 6. 清除所有可能的中断标志初始化步骤 Sdfm1Regs.SDIFLGCLR.all 0xFFFFFFFF; // 写1清除所有标志位 // 7. 最后使能主滤波器如果使用MFE同步多个滤波器 // Sdfm1Regs.SDMFILEN.bit.MFE 1;5.2 同步功能SDSYNC的应用在多通道采样或需要与PWM开关事件严格同步的场合如电机控制中的相电流采样SDSYNC功能至关重要。通过SDSYNCx寄存器你可以让数据滤波器等待一个外部同步事件如某个PWM的周期起点才开始向FIFO填充数据。WTSYNCEN置1使能“等待同步”模式。在此模式下即使数据已就绪也不会存入FIFO。SYNCSEL选择同步信号源例如连接到某个EPWM的同步输出。WTSYNFLG只读标志指示SDSYNC事件是否已发生。WTSYNCLR写1清除WTSYNFLG标志。FFSYNCCLREN一个非常实用的功能。若置1则在SDSYNC事件发生时自动清空FIFO。这确保了每次同步周期开始时FIFO都是从空开始累积数据避免了新旧数据混合。应用场景在电机FOC控制中我们希望在PWM周期中心点采样电流以避开开关噪声。可以将PWM的周期起始信号作为SDSYNC源并设置FFSYNCCLREN1。这样每个PWM周期都会触发一次同步清空FIFO并开始新的采样序列CPU/DMA在周期结束时读取FIFO获得的就是本周期内同步采样的干净数据。6. 常见问题排查与调试技巧即使配置看起来正确实际调试中也可能遇到各种问题。这里分享一些实战中总结的排查思路和技巧。6.1 问题排查速查表现象可能原因排查步骤读不到数据/数据不变1. 数据滤波器未使能 (FEN0)。2. 调制器时钟未连接或配置错误 (MOD模式)。3. 主滤波器使能未置位 (MFE0若使用)。4. 同步模式使能(WTSYNCEN1)但同步事件未发生。1. 检查SDDFPARMx.FEN。2. 检查SDCTLPARMx.MOD用示波器测SD-Cx引脚。3. 检查SDMFILEN.MFE。4. 检查SDSYNCx.WTSYNFLG和同步信号源。中断不触发1. PIE/CPU中断未使能。2. SDFM内部中断未使能 (MIE,AE,FFIEN,EN_CEVTx等)。3. 中断标志已置位但未清除阻塞后续中断。1. 检查PIE和CPU INTM。2. 逐级检查所有相关中断使能位。3. 在ISR中检查并清除SDIFLG标志。中断频繁触发1. FIFO中断水平(SDFFIL)设置过低。2. 错误中断标志未彻底清除。3. 比较器阈值设置不当导致信号在阈值附近抖动。1. 适当提高SDFFIL值。2. ISR中检查所有错误标志位并清除。3. 调整比较器阈值或数字滤波器参数(SAMPWIN,THRESH)。数据噪声大/跳变1. 数据滤波器OSR (DOSR) 过低。2. 数字滤波器 (SAMPWIN,THRESH) 参数过于灵敏。3. 模拟前端或调制器信号质量差。1. 增加DOSR值牺牲带宽换精度。2. 增加SAMPWIN和THRESH。3. 检查PCB布局、电源去耦、调制器参考电压。FIFO溢出1. 中断服务程序处理太慢。2. FIFO中断触发水平(SDFFIL)设置过高如15。3. CPU被更高优先级任务阻塞。1. 优化ISR或使用DMA搬运数据。2. 降低SDFFIL值让中断更早发生。3. 检查中断优先级确保SDFM中断能及时响应。6.2 调试技巧与心得善用状态寄存器在调试初期不要急于开中断。先轮询SDSTATUS、SDIFLG和SDFIFOCTLx.SDFFST确认数据能正常产生、FIFO能正常填充、标志位能正常置位。这能帮你隔离是配置问题还是中断系统问题。计算与实测结合利用前面章节的理论公式计算出在给定输入下你预期的SDDATAx寄存器值。然后用调试器或通过GPIO输出该值与理论值对比。如果偏差巨大可能是时钟配置、OSR或移位设置错误。理解“数据就绪”的时机数据滤波器的输出速率由调制器时钟频率MCLK和DOSR共同决定。输出频率 MCLK / (DOSR1)。例如MCLK10MHzDOSR255(即256)则输出数据率约为39kHz。确保你的读取速度中断或轮询高于此频率否则会丢数据。数字滤波器的“惯性”数字滤波器SAMPWIN,THRESH会引入额外的延迟。这个延迟时间大约是(SAMPWIN1) * (CLKPRESCALE1) * T_sysclk。在要求快速保护的场合必须将这个延迟考虑在内。锁定寄存器注意SDCOMPxLOCK寄存器。一旦将COMP或SDCOMPxCTL位写1对应的配置寄存器将被锁定直到芯片复位。这是为了防止关键的安全配置如过流保护阈值被软件意外修改。建议在完成所有相关配置后最后再执行锁定操作。SDFM模块功能强大但配置项繁多最好的学习方式就是动手实践。从一个简单的通道开始先让数据能读出来再加上FIFO然后配置比较器保护最后尝试同步功能。每步都验证通过就能逐步搭建起稳定可靠的信号采集链路。在电机控制和数字电源这些对实时性和可靠性要求极高的领域深入理解并熟练运用SDFM是你设计出高性能产品的关键一步。