1. SDFM模块寄存器全景概览与设计哲学
在深入TMS320F2837xD的Sigma-Delta滤波器模块(SDFM)寄存器细节之前,我们得先搞清楚一个核心问题:为什么需要这么一套复杂的寄存器体系?如果你用过传统的逐次逼近型ADC,可能会觉得配置几个时钟、通道和触发源就差不多了。但SDFM完全不同,它处理的不是直接的模拟电压采样,而是来自外部Σ-Δ调制器的高速、低精度(通常1位)比特流。这套比特流里,信号信息被“编码”在过采样的密度里,要把它还原成高精度的数字量,就需要一个强大的数字抽取滤波器,这就是SDFM的核心任务。因此,它的寄存器设计必须同时兼顾数据路径的配置和实时监控与响应两大需求。
从你提供的寄存器列表能清晰地看到这种设计哲学。寄存器被分成了几个清晰的层次:首先是全局控制与状态层(SDCTL, SDMFILEN, SDIFLG, SDIFLGCLR),它们像指挥中心,管理着整个模块的开关、中断总闸和状态汇总。然后是四个完全独立的通道层(Channel 1-4),每个通道都有一套完整的、镜像的寄存器组(SDCTLPARMx, SDDFPARMx, SDDPARMx, SDCMPHx, SDCMPLx, SDCPARMx, SDDATAx)。这种结构非常直观,一个通道就是一个完整的信号处理链:从调制器接口模式(MOD)、数据滤波器配置(SST, DOSR)、数据格式处理(DR, SH),到比较器阈值(HLT, LLT)和中断使能(IEH, IEL, MFIE),最后到数据读取(SDDATA)。每个通道都能独立工作,互不干扰,这对于多相电流采样或者多路传感器监控的场景是至关重要的。
寄存器地址的偏移量也很有规律,从0h开始是全局寄存器,从10h开始是通道1,20h是通道2,以此类推,每个通道占用连续的7个寄存器地址。这种规律性大大简化了我们在代码中用结构体(struct)或基地址+偏移量的方式去访问它们。比如,你可以定义一个指向SDFM基地址的指针,然后通过pSdfmRegs->SDDATA1、pSdfmRegs->SDDATA2这样的方式直接访问,代码可读性和可维护性会好很多。
注意:在访问这些寄存器时,务必留意它们的“写保护”属性。像SDCTL、SDMFILEN以及所有带“PARM”后缀的参数寄存器,它们的描述里都标注了“EALLOW”。这意味着在写这些寄存器之前,你必须先执行
EALLOW汇编指令(在C/C++中通常由EALLOW;宏实现),解除写保护;操作完成后,再执行EDIS指令重新上锁。这是TI C2000系列DSP的一个安全特性,防止关键配置被意外修改。而像SDIFLGCLR这种实时操作的寄存器,则没有这个限制,可以直接写入。
2. 核心寄存器功能深度解析与配置逻辑
面对这一大堆寄存器,如果只是死记硬背每个比特位的定义,很快就会晕头转向。我的经验是,把它们按照功能分组,理解每组寄存器协同工作的逻辑,配置起来就事半功倍了。下面我挑几个最核心、最容易出错的寄存器组,结合我的踩坑经验,给你掰开揉碎了讲。
2.1 中断管理的双剑客:SDIFLG 与 SDIFLGCLR
这是你与SDFM模块实时交互最重要的窗口。SDIFLG(中断标志寄存器)是一个只读的状态寄存器,它像一块告示板,实时显示着模块内部发生的各种事件。它的位域划分非常清晰:
- 位[31] MIF (Master Interrupt Flag):这是总中断标志。只要下面任何一个通道的任何一个中断标志(AFx, MFx, IFLx, IFHx)被置位,MIF就会自动变成1。它是一个很好的“快速检查”位,在中断服务程序(ISR)里,可以先读MIF,如果是0,那可能不是SDFM产生的中断,可以快速退出。
- 位[15:12] AFx (Acknowledge Flag):数据就绪标志。当对应通道的数据滤波器完成一次数据转换,新的数据已经就绪在SDDATAx寄存器里时,该位被硬件置1。这是最常用的中断源,用于周期性地读取转换结果。
- 位[11:8] MFx (Modulator Failure Flag):调制器故障标志。当SDFM检测到对应通道的输入调制器时钟(SDx_CLK)或数据(SDx_DAT)信号出现异常(比如丢失)时,该位被置1。这在电机驱动中至关重要,用于检测电流传感器或编码器信号是否断线。
- 位[7:0] IFLx 和 IFHx (Low/High-Level Interrupt Flag):低/高阈值比较中断标志。当对应通道的比较器输出低于低阈值(SDCMPLx)或高于高阈值(SDCMPHx),并且相应的中断使能位(IEL, IEH)打开时,这些标志位被置1。用于实现硬件级的过流、过压快速保护。
理解了SDIFLG是“状态看板”,那SDIFLGCLR(中断标志清除寄存器)就是“清洁工”。它的位布局与SDIFLG一一对应,但操作逻辑是写1清零(W1S)。这里有个极其关键的细节:你只能通过写SDIFLGCLR来清除SDIFLG中的标志位,直接向SDIFLG写入是无效的。例如,要清除通道1的数据就绪标志,你需要执行SdfmRegs.SDIFLGCLR.bit.AF1 = 1;。写0会被硬件忽略。
实操心得:在中断服务程序中,务必在读取SDDATAx数据或执行完保护动作后,再清除对应的中断标志。顺序错了可能会导致丢失中断。一个推荐的流程是:1) 进入ISR;2) 读取SDIFLG判断中断源;3) 根据中断源读取数据或执行动作;4) 写SDIFLGCLR清除对应标志;5) 必要时检查MIF是否已清零(因为可能有其他未处理的中断挂起);6) 退出ISR。另外,手册里特别提到一个竞争条件:如果软件写SDIFLGCLR清零的同一时刻,硬件正试图置位该标志,那么硬件有优先权,标志位不会被清除。这意味着你的ISR可能需要设计成能处理这种“残留”标志,或者确保清除操作在硬件不可能置位的“安全窗口”进行。
2.2 数据滤波器配置核心:SDDFPARMx 寄存器
这个寄存器决定了你如何从1位比特流中“雕刻”出高质量的数字信号。它的每一个配置都直接影响最终数据的精度、延迟和带宽。
- SST[1:0] (Data Filter Structure):选择滤波器结构。这是精度与延迟的权衡。
00- Sincfast:最快,但阻带衰减最差。适用于对速度要求极高、对噪声不敏感的场景。01- Sinc1:一阶Sinc滤波器。速度较快,抑制50Hz/60Hz工频干扰效果好。10- Sinc2:二阶Sinc滤波器。最常用的选择,在速度、抑制带外噪声和建立时间之间取得了很好的平衡。对于电机电流采样,Sinc2是标准配置。11- Sinc3:三阶Sinc滤波器。提供最好的带外噪声抑制和更高的精度,但建立时间最长,延迟最大。适用于高精度、低速的测量,如温度或精密电压监测。
- DOSR[7:0] (Oversampling Ratio):过采样率设置。这是决定输出数据速率和滤波器截止频率的关键参数。实际过采样率 =DOSR + 1。例如,DOSR = 255 (0xFF) 时,过采样率为256。输出数据速率(ODR)的计算公式为:ODR = 调制器时钟频率 (SDx_CLK) / (Sinc滤波器阶数 × (DOSR + 1))。假设调制器时钟是10MHz,选用Sinc2滤波器(阶数2),DOSR设为255,那么ODR = 10MHz / (2 * 256) ≈ 19.53kHz。提高DOSR会降低数据率,但能提升信噪比和分辨率。
- FEN (Filter Enable):滤波器使能位。必须置1,对应的数据滤波器才开始工作。注意,它需要和全局的MFE (Master Filter Enable, 在SDMFILEN寄存器中)同时为1才有效。MFE相当于总开关,FEN是分路开关。
- AE (Acknowledge Enable):数据就绪中断使能。置1后,每当该通道有新数据就绪,SDIFLG中的AFx标志就会置位。如果你采用查��方式,可以关闭此位以节省中断资源。
- SDSYNCEN (Data Filter Reset Enable):这是一个高级功能,允许通过外部PWM比较输出(如EPWM模块的SOC信号)来同步复位所有数据滤波器。这在需要多个SDFM通道或与其他ADC采样严格同步的应用中非常有用。置1后,当指定的PWM比较事件发生时,所有数据滤波器的累加器会清零并重新开始积分,确保所有通道的数据在同一时刻“对齐”。
2.3 比较器与保护机制配置:SDCPARMx 与 SDCMPHx/SDCMPLx
这套寄存器组合实现了硬件级的实时监控与快速保护,是系统安全运行的基石。
- SDCPARMx.IEH 和 IEL:高/低阈值中断使能。只有使能后,比较结果才会触发SDIFLG中的IFHx/IFLx标志。在电机控制中,过流保护是性命攸关的,通常需要使能IEH(高阈值中断),并将其关联到高优先级的PIE中断,甚至直接连接到EPWM的Trip Zone进行硬件关断。
- SDCPARMx.COSR[4:0]:比较器过采样率。和DOSR类似,实际速率=COSR+1。比较器滤波器独立于数据滤波器,通常使用更低的过采样率(更快的响应速度)来快速检测异常。例如,可以设置COSR=0(OSR=1)实现每个调制器时钟周期都比较一次,达到最快的保护速度,但抗噪能力差。折中的做法是设为4或7,在速度和抗噪间平衡。
- SDCPARMx.CS1_CS0:比较器滤波器结构。选择逻辑与SST类似。为了快速保护,通常选择Sincfast (
00) 或 Sinc1 (01) 以最小化延迟。 - SDCMPHx 和 SDCMPLx:高/低阈值寄存器。这里存放的是无符号的阈值绝对值。关键点在于:这个阈值是和什么值比较?它比较的对象是比较器滤波器的输出,而这个输出是经过其自身独立的Sinc滤波器(由COSR和CS1_CS0配置)处理后的数据。你需要根据你的信号量程、比较器滤波器的增益(与结构有关)来计算出对应的阈值数字。例如,如果你的信号满量程对应比较器输出为±32767(16位有符号),那么想要在80%满量程触发高阈值保护,就需要将SDCMPHx设置为
0.8 * 32767 ≈ 26214。
2.4 数据格式处理:SDDPARMx 寄存器
这个寄存器负责将滤波器内部的高精度数据“包装”成你最终要读取的格式。
- DR (Data Representation):数据表示位。这是最重要的选择之一。
0:16位有符号整数(2‘s complement)。数据存放在SDDATAx寄存器的低16位(DATA16)。这是最常用的格式,节省内存和带宽。1:32位有符号整数。数据存放在整个32位的SDDATAx寄存器中,高16位在DATA32HI,低16位在DATA16。当你的DOSR设置得非常高,或者需要极高的动态范围时,才需要使用32位模式。
- SH[4:0] (Shift Control):移位控制。这个参数极易配置错误,但至关重要。当DR=0(16位模式)时,SH决定了如何将内部更宽的数据(比如24位或32位)截断/舍入到16位。你可以把它理解为软件增益。左移(SH为正数)相当于放大信号,但可能导致溢出(饱和);右移(SH为负数,在寄存器中以补码形式表示)相当于衰减信号,会损失分辨率。正确的SH值取决于你的滤波器结构(SST)、过采样率(DOSR)以及你期望的输入信号满量程对应的数字量。TI通常会在应用笔记或库函数中给出推荐值。一个常见的起始点是:对于Sinc2滤波器,SH可以设置为
(滤波器阶数 + 1),例如Sinc2时SH=3,这能将数据左移3位(放大8倍),充分利用16位的动态范围。
3. 从零开始:SDFM模块完整配置与初始化流程
光讲理论不够,我们直接来看一套针对电机相电流采样的、可落地的SDFM初始化代码流程。假设我们使用通道1和通道2来采样两相电流,调制器时钟为10MHz,目标数据更新率为20kHz,采用Sinc2滤波器,并启用高阈值硬件保护。
3.1 步骤一:系统级与全局寄存器配置
首先,我们需要使能SDFM模块的时钟,并配置其与PIE中断的连接(如果使用中断)。这部分通常由DSP的SysConfig工具或初始化函数完成。接着,配置全局寄存器:
// 假设 SdfmRegs 已定义为指向 SDFM 寄存器组的结构体指针 EALLOW; // 解除写保护 // 1. 配置主控制寄存器 SDCTL // 使能主中断输出。如果使用查询法,可以关闭MIE。 SdfmRegs.SDCTL.bit.MIE = 1; // 允许中断标志触发CPU中断 // 2. 配置主滤波器使能寄存器 SDMFILEN // 打开所有数据滤波器的总使能开关。 SdfmRegs.SDMFILEN.bit.MFE = 1; EDIS; // 重新使能写保护3.2 步骤二:通道参数化配置(以通道1为例)
这是配置的核心,我们按照信号流的顺序来设置各个参数寄存器。
EALLOW; // 1. 配置控制参数寄存器 SDCTLPARM1 // 设置调制器接口模式。假设调制器输出数据速率等于时钟速率(最常见情况)。 SdfmRegs.SDCTLPARM1.bit.MOD = 0; // 00: Clock speed = Data rate // 2. 配置数据滤波器参数寄存器 SDDFPARM1 SdfmRegs.SDDFPARM1.bit.SST = 2; // 10: Sinc2 滤波器结构 // 计算DOSR:ODR = SDx_CLK / (Sinc阶数 * (DOSR+1)) // 目标 ODR = 20kHz, SDx_CLK = 10MHz, Sinc2阶数=2 // => DOSR = (SDx_CLK / (ODR * 阶数)) - 1 = (10e6 / (20e3 * 2)) - 1 = 250 - 1 = 249 SdfmRegs.SDDFPARM1.bit.DOSR = 249; // 过采样率 = 250 SdfmRegs.SDDFPARM1.bit.AE = 1; // 使能数据就绪中断(Acknowledge) SdfmRegs.SDDFPARM1.bit.FEN = 1; // 使能本通道数据滤波器 SdfmRegs.SDDFPARM1.bit.SDSYNCEN = 0; // 本例不使用外部PWM同步复位 // 3. 配置整数参数寄存器 SDDPARM1 SdfmRegs.SDDPARM1.bit.DR = 0; // 使用16位数据格式 // 设置移位。对于Sinc2滤波器,TI常推荐SH=3。这需要根据实际传感器和调制器比例调整。 SdfmRegs.SDDPARM1.bit.SH = 3; // 左移3位,增益为8 // 4. 配置比较器参数寄存器 SDCPARM1 SdfmRegs.SDCPARM1.bit.CS1_CS0 = 0; // 00: 比较器使用Sincfast结构,响应最快 SdfmRegs.SDCPARM1.bit.COSR = 0; // 比较器过采样率 = 1,最快速度比较 SdfmRegs.SDCPARM1.bit.IEH = 1; // 使能高阈值中断(用于过流保护) SdfmRegs.SDCPARM1.bit.IEL = 0; // 本例不使能低阈值中断 SdfmRegs.SDCPARM1.bit.MFIE = 1; // 使能调制器故障中断(重要!) // 5. 配置高低阈值寄存器 SDCMPH1 和 SDCMPL1 // 假设经过SH移位和滤波器处理后,电流传感器±50A对应数字量范围约为±30000。 // 设置过流保护阈值为±40A。 // 计算:阈值数字量 = (保护电流 / 满量程电流) * 满量程数字量 // = (40A / 50A) * 30000 = 0.8 * 30000 = 24000 // SDCMPHx/LLT为无符号数,存放的是绝对阈值。 // 对于高阈值,我们比较的是“正”的过流,所以直接设置。 // 对于低阈值,我们比较的是“负”的过流(或欠流),但寄存器是无符号的。 // 实际上,IFL标志在数据 <= LLT时触发。如果我们设置LLT为-24000对应的无符号数, // 需要小心处理二进制补码。更常见的做法是,如果只关心正向过流,可以先将LLT设为0或一个很小的值, // 而主要依靠IEH和SDCMPH1进行保护。 int16_t overcurrent_threshold = 24000; SdfmRegs.SDCMPH1.bit.HLT = overcurrent_threshold; // 设置高阈值 SdfmRegs.SDCMPL1.bit.LLT = 0; // 低阈值设为0,或根据需求设置负向保护值(需转换) EDIS;通道2的配置与通道1完全类似,只需将上述代码中的所有SDxxxPARM1、SDCMPH1等改为SDxxxPARM2、SDCMPH2即可。地址偏移是连续的,硬件结构是对称的。
3.3 步骤三:中断服务程序(ISR)编写要点
配置好硬件,软件侧必须正���响应。以下是PIE中断服务程序的核心框架:
// SDFM1通道1的中断服务例程(假设已关联到PIE中断) __interrupt void sdfm1IsrChannel1(void) { uint16_t intFlags = SdfmRegs.SDIFLG.all; // 读取全局中断标志 // 1. 检查并处理调制器故障(最高优先级) if (intFlags & 0x0100) { // 检查MF1位 (bit8) // 发生调制器故障!立即执行保护动作,如关闭PWM输出 EPwm1Regs.TZFRC.bit.OST = 1; // 触发一次软件Trip // 记录故障,可能需要停机检查 systemFaultStatus |= MODULATOR_FAILURE_CH1; // 清除故障标志 SdfmRegs.SDIFLGCLR.bit.MF1 = 1; } // 2. 检查并处理高阈值过流(硬件保护) if (intFlags & 0x0002) { // 检查IFH1位 (bit1) // 高阈值触发!硬件已可能通过Trip Zone关断PWM,此处进行软件记录 systemFaultStatus |= OVERCURRENT_FAULT_CH1; // 清除标志 SdfmRegs.SDIFLGCLR.bit.IFH1 = 1; } // 3. 检查并处理数据就绪(常规数据采集) if (intFlags & 0x1000) { // 检查AF1位 (bit12) // 读取最新的电流采样值 int16_t current_raw = SdfmRegs.SDDATA1.bit.DATA16; // 进行必要的标度变换和滤波处理 float current_amps = ((float)current_raw / 32768.0f) * CURRENT_SENSOR_GAIN; // 将处理后的值送入电流环控制器 // ... // 清除数据就绪标志 SdfmRegs.SDIFLGCLR.bit.AF1 = 1; } // 4. 检查主中断标志MIF是否因其他未处理中断仍为1(可选,但建议) // 如果本ISR只处理了部分中断,而其他通道也产生了中断,MIF会立刻再次置位。 // 这可以确保PIE能再次收到中断请求。 // 清除PIE组中断标志,应答中断 PieCtrlRegs.PIEACK.all = PIEACK_GROUPx; // 替换为实际的组号 }4. 高级应用与性能调优实战
当你掌握了基础配置后,下面这些高级技巧和调优经验能帮你把SDFM用到极致。
4.1 多通道同步采样策略
在电机矢量控制(FOC)中,三相电流需要在同一时刻采样,以准确计算Clarke/Park变换。SDFM本身各通道独立运行,如何实现同步?
- 使用SDSYNCEN(外部同步复位):这是最精确的硬件同步方式。将一个EPWM模块的SOC(Start-of-Conversion)信号连接到SDFM的外部同步输入。配置
SDDFPARMx.bit.SDSYNCEN = 1。当EPWM的SOC事件发生时,所有使能了此功能的SDFM通道的数据滤波器会同时复位并开始新的积分周期。这样,经过相同的滤波延迟后,所有通道的数据会在同一时刻就绪。你需要精心计算EPWM的周期、SDFM的DOSR,使得数据就绪率与你的控制频率匹配。 - 软件同步法:如果硬件同步不方便,可以在中断服务程序中处理。使能所有通道的数据就绪中断(AFx)。在ISR中,当收到第一个通道的AFx中断时,读取所有通道的SDDATAx寄存器。由于各通道配置相同,它们的转换完成时间几乎一致,短时间内的先后读取误差在大多数应用中可接受。为了更可靠,可以检查其他通道的AFx标志是否也已置位。
4.2 滤波器参数(SST与DOSR)的选型计算
选择SST和DOSR是一个权衡艺术,核心公式是:输出数据率 ODR = f_mod / (N * (DOSR + 1)),其中f_mod是调制器时钟频率,N是Sinc滤波器的阶数(Sinc1为1,Sinc2为2,Sinc3为3,Sincfast可视为1)。
场景A:高速动态响应(如电流环):
- 需求:ODR > 50kHz,带宽足够高。
- 方案:选择Sinc2 (
N=2) 以保证较好的噪声抑制。假设f_mod = 20MHz,要求ODR=100kHz。 - 计算:
DOSR = f_mod / (N * ODR) - 1 = 20e6 / (2 * 100e3) - 1 = 100 - 1 = 99。 - 设置:
SST=2 (Sinc2),DOSR=99。此时滤波器建立时间约为N * (DOSR+1) / f_mod = 2*100/20e6 = 10us,延迟可控。
场景B:高精度测量(如直流母线电压):
- 需求:极高的信噪比和分辨率,速度要求不高(ODR ~ 1kHz)。
- 方案:选择Sinc3 (
N=3) 以获得最好的噪声整形。假设f_mod = 10MHz。 - 计算:为了高分辨率,需要大的DOSR。设
DOSR = 1023(最大值附近)。 - ODR = 10e6 / (3 * 1024) ≈ 3.26kHz。信噪比(SNR)理论值约为
6.02*N + 1.76 + 10*log10(DOSR+1)dB,代入可得极高SNR。 - 设置:
SST=3 (Sinc3),DOSR=1023。注意建立时间会很长,约3*1024/10e6 = 307us,不适合高速控制环。
4.3 数据格式与移位(SH)的校准实战
SDDPARMx.bit.SH的设置不当,会导致数据要么溢出饱和,要么分辨率利用不足。校准流程如下:
- 搭建测试环境:给Σ-Δ调制器输入一个已知的、稳定的直流电压(例如,对应0A或传感器中间量程)。
- 初步配置:设置一个合理的DOSR和SST,将SH设为0。
- 读取数据:使能滤波器,连续读取SDDATAx的值。观察读到的数据是否稳定在一个值附近(比如
raw_val)。 - 分析与调整:
- 如果
raw_val的绝对值非常小(例如,小于1000),说明信号幅度太小,大量高位未使用。可以增大SH。每次增加1,相当于放大2倍,直到数据范围接近满量程(例如±30000)但又不饱和。 - 如果
raw_val经常达到极限值(如-32768或32767),说明信号溢出。需要减小SH,或者检查输入信号是否确实超范围。 - 目标:在输入信号为最大预期值时,使输出数字量达到满量程的80%-90%。例如,±50A电流对应数字量±30000左右。这样既能充分利用ADC的动态范围,又留有一定的裕量防止偶然过冲导致饱和。
- 如果
- 记录比例系数:确定好SH后,计算最终的比例系数
K = (物理量程) / (对应的数字量范围)。例如,输入±50A时,数字量输出为±28000,则K = 50.0 / 28000.0 A/count。在软件中将读取的raw_data乘以K得到实际电流值。
5. 典型故障排查与调试技巧实录
即使配置看起来正确,SDFM也可能“沉默”或行为异常。下面是我在项目中总结的排查清单。
5.1 问题一:读不到数据,SDIFLG.AFx标志永不置位
- 检查1:时钟与数据信号。这是最常见的问题。用示波器测量连接到SDx_CLK和SDx_DAT引脚的信号。确保:
- 时钟频率是否符合预期(与寄存器MOD设置匹配)?
- 数据线是否有随模拟输入变化的脉冲?
- 信号幅度和边沿质量是否满足DSP的电气要求?
- 检查2:双重使能开关。确认
SDMFILEN.bit.MFE和SDDFPARMx.bit.FEN都已置1。缺一不可。 - 检查3:滤波器配置是否合理。过大的DOSR会导致输出数据率极低,你可能等待时间不够。计算一下ODR,看看是否在预期之内。用简单的
for循环延时一段时间再查询标志位。 - 检查4:中断与查询方式。如果你在用中断,确认PIE和CPU中断已正确使能,并且中断向量表已关联。如果使用查询法,确保在循环中不断读取SDIFLG寄存器。
5.2 问题二:数据值不正确(全零、恒定或乱跳)
- 检查1:SH移位配置。SH设置不当是主因。按照上面第4.3节的校准流程重新调整SH值。
- 检查2:数据格式DR。确认你读取的数据位与DR设置匹配。如果DR=0(16位),你应该读
SDDATAx.bit.DATA16;如果DR=1(32位),你需要将SDDATAx.bit.DATA32HI和SDDATAx.bit.DATA16组合成一个32位整数。 - 检查3:调制器模式MOD。确认MOD设置与外部调制器芯片的输出格式一致。最常用的是模式0(时钟=数据率)。如果模式选错(如选了曼彻斯特解码而输入不是),数据必然错误。
- 检查4:信号地与电源。确保模拟地(AGND���和数字地(DGND)在调制器侧和DSP侧单点连接良好。电源噪声也会导致数据跳动。
5.3 问题三:比较器中断(IFHx/IFLx)不触发或误触发
- 检查1:中断使能链路。这是一个三级使能链:1)
SDCPARMx.bit.IEH/IEL(通道使能);2)SDCTL.bit.MIE(主中断使能);3) PIE和CPU级中断使能。缺一不可。 - 检查2:阈值寄存器值。SDCMPHx和SDCMPLx是无符号数。如果你期望在-10000(补码形式)触发低阈值中断,你不能直接写入-10000。你需要理解比较器输出的数据格式。通常,比较器输出与数据滤波器输出同格式。假设数据是16位有符号数,你想在-10000触发,那么你需要将
SDCMPLx设置为(uint16_t)(-10000)对应的无符号数(即65536-10000=55536)。更安全的做法是,在软件中处理负向保护,硬件比较器只用于正向过流保护(IFH),这样逻辑更清晰。 - 检查3:比较器滤波器配置。如果COSR设置过大或使用了高阶Sinc滤波器,比较器的响应会变慢,可能导致短暂的过冲无法被捕获。对于快速保护,建议使用
CS1_CS0=0 (Sincfast)和COSR=0。
5.4 问题四:调制器故障中断(MFx)误报
- 检查1:信号完整性。MFx标志在检测到SDx_CLK或SDx_DAT长时间无跳变时置位。用示波器检查信号是否存在毛刺、振铃或间歇性中断。长距离传输时,需考虑阻抗匹配。
- 检查2:滤波电容。有些调制器输出端需要接一个小电容(如10-100pF)到地,以滤除高频噪声,防止DSP误判为信号活动。参考调制器芯片的数据手册。
- 检查3:软件去抖。在MFx中断服务程序中,可以加入简单的去抖逻辑:连续检测到几次故障后才确认,或者短暂延迟后重新检测标志位,避免单次干扰导致系统误停机。