F2837xD ADC配置精解:从SOC触发到Burst模式实战

📅 2026/7/21 15:52:43 👁️ 阅读次数 📝 编程学习
F2837xD ADC配置精解:从SOC触发到Burst模式实战

1. 项目概述:为什么F2837xD的ADC值得深挖?

在电机控制、数字电源或者任何需要高精度实时信号采集的嵌入式项目里,ADC(模数转换器)往往是性能瓶颈和调试难点的集中地。你可能会遇到采样时序对不上PWM、多通道数据错位、或者采样值总感觉“差点意思”不够精准的问题。这些问题背后,往往不是ADC本身性能不行,而是配置没有吃透。

TI的TMS320F2837xD系列微控制器,作为C2000家族的高性能成员,其内置的ADC模块功能强大但结构也相对复杂。它绝不是一个简单的“配置通道、读取结果”的外设。其核心在于一套高度灵活的SOC(Start-Of-Conversion,转换启动)触发与仲裁机制,以及Burst(突发)模式这样的高级功能。理解它们,你就能从“ADC能用”进阶到“ADC用得精妙”,让采样行为完全贴合你的系统时序,榨干硬件性能。

官方技术手册(TRM)内容详尽,但超过一千六百页的篇幅和严谨的术语常常让开发者望而生畏。本文旨在结合我多年在电机驱动和电源项目中的实战经验,为你拆解F2837xD ADC配置的核心逻辑,特别是从最基础的SOC触发到高效的Burst模式应用,让你不仅知道寄存器怎么填,更明白为什么这么填,以及在实际项目中如何规避那些手册里没明说的“坑”。

2. ADC模块核心架构与配置层级解析

在动手写代码之前,我们必须像建筑师看蓝图一样,先理解ADC模块的整体架构。F2837xD的ADC不是一个单一模块,而是一个由“核心(Core)”和“包装器(Wrapper)”组成的系统。核心负责最本质的模数转换,而包装器则提供了让我们能够灵活编排采样任务的智能控制器。

2.1 全局配置与SOC级配置

这是最容易混淆的一点。ADC的某些属性是全局(Per Module)的,一旦设置,整个ADC模块都遵循此规则;而另一些是SOC级(Per SOC)的,可以为16个SOC(SOC0-SOC15)分别独立设置。理解这一点是正确配置的前提。

配置选项配置层级说明与影响
时钟(Clock)全局整个ADC模块的转换时钟(ADCCLK)由SYSCLK分频而来。关键点:不同ADC模块(如ADCA, ADCB)若设置不同分频,会导致它们异步工作,在需要同步采样的场景(如电机相电流)是致命错误。
分辨率(Resolution)全局选择12位或16位模式。重要限制:16位模式仅支持差分输入,12位模式仅支持单端输入。切换需在ADC空闲时进行。
信号模式(Signal Mode)全局选择单端(Single-Ended)或差分(Differential)输入模式。这决定了你如何理解引脚和转换结果。
参考电压源(Reference)全局(固定)F2837xD采用外部参考,由VREFHI和VREFLO引脚提供。这是硬件设计时必须确定的,软件无法更改模式。
触发源(Trigger Source)SOC级每个SOC可以独立选择由谁触发:软件、ePWM、CPU定时器、GPIO或ADC中断。这是实现复杂采样序列的基石。
转换通道(Channel)SOC级每个SOC可以指定采集哪个具体的ADCINx引脚(单端)或引脚对(差分)。
采样窗口(Acquisition Window)SOC级每个SOC可以独立设置采样保持电容的充电时间(ACQPS),以适应不同信号源的驱动能力。
突发模式(Burst Mode)全局使能后,会改变SOC的触发逻辑,用单个触发按顺序启动一批转换。

实操心得一:配置顺序的黄金法则我的习惯是遵循“从全局到局部”的配置顺序:1) 初始化系统时钟后,首先配置ADC的全局时钟分频(ADCCLK);2) 调用ADC_setMode()AdcSetMode()函数一次性设置分辨率信号模式(这两个必须用函数设置以加载正确的校准参数);3) 然后才开始逐个配置SOC的触发、通道和采样窗口。这个顺序能避免很多因依赖关系导致的诡异问题。

2.2 输入模式与结果计算:从硬件连接到数据解读

你的硬件电路决定了应选择单端还是差分模式,而软件必须与之匹配,并正确解读转换结果。

单端模式最简单,ADCINx引脚的电压相对于VREFLO进行测量。其转换公式决定了你的测量范围:结果码 = 4096 * (ADCINx - VREFLO) / (VREFHI - VREFLO)(12位模式) 结果范围是0到4095。例如,VREFLO=0V, VREFHI=3.0V,那么1.5V的输入对应的理想结果就是2048。

差分模式则用于抑制共模噪声,测量的是两个引脚(ADCINxP, ADCINxN)的电压差。其16位模式公式为:结果码 = 65536 * [ (ADCINxP - ADCINxN) + (VREFHI - VREFLO) ] / [ 2 * (VREFHI - VREFLO) ]这个公式看起来复杂,其实它做了一个映射:将电压差-(VREFHI-VREFLO)+(VREFHI-VREFLO)的范围,线性映射到0到65535。这里有一个关键陷阱:很多人误以为差分输入时,负输入端(ADCINxN)可以接地(VSSA)。但公式要求(ADCINxP + ADCINxN)/2这个共模电压必须接近(VREFHI + VREFLO)/2。如果简单地将ADCINxN接地,而VREFLO也接地,那么共模电压就是输入电压的一半,很可能不满足要求,导致精度下降甚至损坏。正确的做法是使用运算放大器等电路来提供合适的共模电压。

注意事项:通道选择的“潜规则”手册的通道选择表(Table 11-6)需要仔细看。在差分模式下,CHSEL值选择的是引脚对。例如,CHSEL设置为0或1,都会选择ADCIN0作为正输入(ADCINxP),ADCIN1作为负输入(ADCINxN)。这意味着,如果你希望用ADCIN2和ADCIN3做差分,设置CHSEL=2或3都可以。但通道12(ADCIN12)和ADC-A的温度传感器通道是例外,它们永远以12位单端模式工作,与全局设置无关,这在设计采样方案时要提前规划。

3. SOC机制深度剖析:从触发到完成的完整链条

SOC是ADC灵活性的灵魂。你可以把它想象成一个“采样任务工单”。每个SOC(共16个)都是一张独立的工单,上面写明了:“当某个触发信号到来时,去某个通道,用多长的采样时间,采集一个样本。”

3.1 SOC配置寄存器详解

每个SOC的工单由ADCSOCxCTL寄存器定义,主要包含三个字段:

  • TRIGSEL: 选择工单的“派发员”。可以是具体的ePWM模块(如ePWM1_SOCA)、CPU定时器、外部GPIO中断,或者最简单的“软件派发员”(立即启动)。
  • CHSEL: 指定去哪个“工地”(ADC通道)采样。
  • ACQPS: 规定“采样作业”(给采样电容充电)的时间长度。计算公式为采样窗口时间 = (ACQPS + 1) * SYSCLK周期。例如,SYSCLK=200MHz(周期5ns),需要100ns采样窗口,则ACQPS = 100ns / 5ns - 1 = 19

3.2 采样窗口(ACQPS)的计算与实战选择

ACQPS的设置绝非随意。它必须满足两个条件:1) 大于等于数据手册规定的最小采样时间(例如,在特定输入阻抗和温度下的最小值);2) 保证采样电容能充电到目标精度(如0.5 LSB)以内。

计算步骤

  1. 确定信号源阻抗: 查看你的前端电路(如运放输出阻抗、分压电阻网络、滤波RC电路),计算从信号源看进去的戴维南等效电阻Rs
  2. 查阅ADC输入模型: 在数据手册的“ADC电气特性”部分,找到Ron(内部开关电阻)和Ch(采样电容)的值。图11-3和图11-4的模型就是用来做这个计算的。
  3. 计算RC时间常数: 总电阻Rtotal = Rs + Ron,总电容Ctotal = Ch + CpCp为寄生电容,通常很小)。时间常数τ = Rtotal * Ctotal
  4. 计算所需时间: 要达到N位精度,采样电容电压需稳定到最终值的1/(2^(N+1))以内。对于12位精度,需稳定到1/8192以内。根据电容充电公式V(t) = Vfinal * (1 - e^(-t/τ)),解出t。通常,达到7~8个时间常数(7τ ~ 8τ)即可满足12位精度要求。
  5. 转换为ACQPS值所需SYSCLK周期数 = ceil(t / SYSCLK周期),然后ACQPS = 周期数 - 1

实操心得二:给ACQPS留足余量理论计算是基于典型值的。在实际项目中,尤其是环境温度变化、电源波动或使用不同批次的芯片时,Ron等参数会有偏差。我的经验是,在理论计算值上再增加20%-50%的余量。例如,计算需要15个SYSCLK周期,我会设置ACQPS=20(即21个周期)。多花几个时钟周期对系统影响微乎其微,但能极大提升采样稳定性和可靠性,避免因采样不充分引入的随机噪声。

3.3 转换优先级仲裁:当多个工单同时到来

当多个SOC的触发条件同时满足(比如多个ePWM在同一时刻发出SOC信号),或者软件同时强制触发多个SOC时,ADC需要决定先处理谁。这里有两种策略:

1. 轮询优先级(Round-Robin): 这是默认模式。它维护一个指针(RRPOINTER),指向上一次完成转换的SOC。优先级最高的SOC是RRPOINTER + 1(超过15则回到0)。这保证了所有SOC被公平对待,不会出现低序号SOC一直霸占资源的情况。图11-5的流程图非常直观地展示了这个过程。

2. 高优先级(High-Priority): 你可以通过ADCSOCPRIORITYCTL.SOCPRIORITY字段,将一部分SOC(SOC0到SOCn-1)设置为高优先级。高优先级SOC可以中断当前的轮询队列。如果多个高优先级SOC同时被触发,编号小的优先。高优先级SOC完成后,轮询指针恢复,继续服务普通优先级的SOC。图11-6展示了高优先级SOC(SOC0-SOC3)如何插队。

一个关键场景:在电机控制中,我们通常希望电流采样(与PWM中心点对齐)具有最高优先级和确定性延时。这时,可以将用于电流采样的SOC(例如SOC0, SOC1)设置为高优先级,并采用ePWM触发。而将用于温度、直流母线电压等慢速信号的SOC设置为轮询优先级,由定时器触发。这样就能确保关键电流采样不被延迟。

4. 从理论到实践:典型SOC配置案例详解

让我们通过几个逐渐复杂的例子,将上述理论转化为实实在在的代码。假设系统时钟SYSCLK为200MHz(周期5ns)。

4.1 案例一:ePWM触发单次转换

这是最基础的场景,常用于与PWM同步的采样。

// 目标:用 ePWM3 的周期匹配事件(SOCB)触发,对 ADCINA1 进行一次采样,采样窗口100ns。 // 计算 ACQPS: 100ns / 5ns - 1 = 19 // 选择 SOC5 作为本次转换的“工单” AdcaRegs.ADCSOC5CTL.bit.CHSEL = 1; // SOC5 转换通道 ADCINA1 (CHSEL=1) AdcaRegs.ADCSOC5CTL.bit.ACQPS = 19; // 采样窗口 = (19+1)*5ns = 100ns AdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 10; // 触发源选择 ePWM3 SOCB (TRIGSEL值需查表,此处10为示例)

当ePWM3产生SOCB信号时,SOC5被置位。若ADC空闲,则立即开始对ADCINA1进行100ns的采样,随后进行模数转换。结果自动存入AdcaResultRegs.ADCRESULT5寄存器。

4.2 案例二:ePWM触发过采样(Oversampling)

过采样是提高有效分辨率、抑制噪声的常用技术。其本质是用同一个触发,让多个SOC对同一个通道进行连续采样。

// 目标:用 ePWM3 SOCB 触发,对 ADCINA1 进行4次过采样。 // 配置 SOC5, SOC6, SOC7, SOC8 执行相同的任务 AdcaRegs.ADCSOC5CTL.bit.CHSEL = 1; // 都转换 ADCINA1 AdcaRegs.ADCSOC5CTL.bit.ACQPS = 19; AdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 10; AdcaRegs.ADCSOC6CTL.bit.CHSEL = 1; AdcaRegs.ADCSOC6CTL.bit.ACQPS = 19; AdcaRegs.ADCSOC6CTL.bit.TRIGSEL = 10; AdcaRegs.ADCSOC7CTL.bit.CHSEL = 1; AdcaRegs.ADCSOC7CTL.bit.ACQPS = 19; AdcaRegs.ADCSOC7CTL.bit.TRIGSEL = 10; AdcaRegs.ADCSOC8CTL.bit.CHSEL = 1; AdcaRegs.ADCSOC8CTL.bit.ACQPS = 19; AdcaRegs.ADCSOC8CTL.bit.TRIGSEL = 10;

当ePWM3的SOCB信号到来,SOC5-SOC8会依次被转换。最终,4个结果分别存入ADCRESULT5ADCRESULT8。在中断服务程序中,你可以将这4个值取平均,得到一个更稳定、噪声更低的采样值。注意:由于轮询指针的存在,这4个转换的执行顺序一定是SOC5->SOC6->SOC7->SOC8吗?不一定,但最终都会完成。如果你需要严格的顺序,最好将它们设置为高优先级。

4.3 案例三:CPU定时器触发多通道序列采样

这个场景适用于需要以固定频率采集多个不同信号,且每个信号所需采样时间可能不同的情况。例如,同时采集电流(快信号)、电压(中速信号)和温度(慢信号)。

// 目标:用 CPU1 Timer 2 触发,按顺序采集4个不同通道,每个通道采样时间根据需求定制。 // 假设信号与需求如下表: // | 信号 | ADC引脚 | 所需采样窗口 | 计算ACQPS (SYSCLK=200MHz) | // |--------|---------|--------------|---------------------------| // | 电流 | ADCINA5 | >120ns | ceil(120/5)-1 = 23 | // | 电压 | ADCINA0 | >444ns | ceil(444/5)-1 = 88 | // | 温度1 | ADCINA3 | >110ns | ceil(110/5)-1 = 21 | // | 温度2 | ADCINA2 | >291ns | ceil(291/5)-1 = 58 | AdcaRegs.ADCSOC0CTL.bit.CHSEL = 5; // SOC0 -> ADCINA5 (电流) AdcaRegs.ADCSOC0CTL.bit.ACQPS = 23; // 24个SYSCLK周期 = 120ns AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 3; // 假设3对应CPU1 Timer2 AdcaRegs.ADCSOC1CTL.bit.CHSEL = 0; // SOC1 -> ADCINA0 (电压) AdcaRegs.ADCSOC1CTL.bit.ACQPS = 88; // 89个周期 = 445ns AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 3; AdcaRegs.ADCSOC2CTL.bit.CHSEL = 3; // SOC2 -> ADCINA3 (温度1) AdcaRegs.ADCSOC2CTL.bit.ACQPS = 21; // 22个周期 = 110ns AdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 3; AdcaRegs.ADCSOC3CTL.bit.CHSEL = 2; // SOC3 -> ADCINA2 (温度2) AdcaRegs.ADCSOC3CTL.bit.ACQPS = 58; // 59个周期 = 295ns AdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 3;

配置完成后,每次CPU1 Timer 2超时,都会触发SOC0-SOC3依次执行。整个序列的转换时间 = 各通道采样时间之和 + 各通道转换时间之和。你需要确保这个总时间小于定时器的触发周期,否则会发生任务堆积。

4.4 软件强制触发

无论SOC配置了什么触发源,你都可以通过写ADCSOCFRC1寄存器来立即启动它们。这在系统初始化后的第一次采样,或者需要手动启动一个采样序列时非常有用。

// 软件立即触发上面案例中配置好的 SOC0, SOC1, SOC2, SOC3 AdcaRegs.ADCSOCFRC1.all = 0x000F; // 二进制 0000 0000 0000 1111, 置位SOC0-SOC3的标志位

写入后,相应的SOC会立即进入待转换队列,优先级仲裁逻辑开始工作。

5. 进阶利器:Burst模式原理与应用实战

当你的采样需求变得更加动态,比如需要在不同时刻采集不同的传感器组时,Burst模式就派上用场了。它不是一种新的转换方式,而是一种智能的SOC触发管理机制

5.1 Burst模式核心思想

使能Burst模式(ADCBURSTCTL.BURSTEN = 1)后,所有配置为轮询优先级的SOC,其TRIGSEL设置将被忽略,转而统一由ADCBURSTCTL.BURSTTRIG字段指定的触发源(如某个ePWM或��时器)来管理。

关键参数BURSTSIZE定义了一次触发启动多少个连续的SOC转换。实际启动的SOC数量是BURSTSIZE + 1。例如,BURSTSIZE = 1,则一次触发启动2个SOC转换。

工作流程:

  1. 使能Burst模式,设置BURSTTRIGBURSTSIZE
  2. 配置一批SOC为轮询优先级(通过SOCPRIORITY设置,例如SOCPRIORITY=12表示SOC0-11为高优先级,SOC12-15为轮询)。
  3. BURSTTRIG信号到来,ADC不会触发所有轮询SOC,而是从当前轮询指针指向的下一个SOC开始,连续触发BURSTSIZE+1个SOC。
  4. 转换完成后,轮询指针移动到这批转换的最后一个SOC。下次触发到来时,再从新的指针位置开始下一批。

5.2 Burst模式典型应用:交替采样两组信号

这是一个非常实用的场景,比如在电机控制中,你想在一个PWM周期采样A相和B相电流,在下一个PWM周期采样B相和C相电流(节省ADC资源),如此交替。

// 目标:使用CPU1 Timer 2触发,交替采样两组信号。 // 第一组:ADCINA7, ADCINA5 // 第二组:ADCINA2, ADCINA3 // 采样窗口均为100ns (ACQPS=19) AdcaRegs.ADCBURSTCTL.bit.BURSTEN = 1; // 使能Burst模式 AdcaRegs.ADCBURSTCTL.bit.BURSTTRIG = 3; // 触发源:CPU1 Timer 2 AdcaRegs.ADCBURSTCTL.bit.BURSTSIZE = 1; // 一次触发启动 1+1=2 个转换 AdcaRegs.ADCSOCPRIORITYCTL.bit.SOCPRIORITY = 12; // SOC0-11为高优先级,SOC12-15为轮询 // 配置用于Burst的四个SOC (SOC12-SOC15) AdcaRegs.ADCSOC12CTL.bit.CHSEL = 7; // SOC12 -> ADCINA7 AdcaRegs.ADCSOC12CTL.bit.ACQPS = 19; // TRIGSEL在Burst模式下被忽略,但仍需配置一个值 AdcaRegs.ADCSOC12CTL.bit.TRIGSEL = 0; // 可设为任意值,例如0(禁用) AdcaRegs.ADCSOC13CTL.bit.CHSEL = 5; // SOC13 -> ADCINA5 AdcaRegs.ADCSOC13CTL.bit.ACQPS = 19; AdcaRegs.ADCSOC13CTL.bit.TRIGSEL = 0; AdcaRegs.ADCSOC14CTL.bit.CHSEL = 2; // SOC14 -> ADCINA2 AdcaRegs.ADCSOC14CTL.bit.ACQPS = 19; AdcaRegs.ADCSOC14CTL.bit.TRIGSEL = 0; AdcaRegs.ADCSOC15CTL.bit.CHSEL = 3; // SOC15 -> ADCINA3 AdcaRegs.ADCSOC15CTL.bit.ACQPS = 19; AdcaRegs.ADCSOC15CTL.bit.TRIGSEL = 0;

运行过程解析

  1. 初始状态,轮询指针RRPOINTER=16(复位值),最高优先级轮询SOC是SOC12。
  2. 第一次Timer2触发:启动SOC12和SOC13的转换。转换完成后,RRPOINTER指向SOC13。
  3. 此时最高优先级轮询SOC变为SOC14。
  4. 第二次Timer2触发:启动SOC14和SOC15的转换。转换完成后,RRPOINTER指向SOC15。
  5. 此时最高优先级轮询SOC又变回SOC12(因为SOC15之后是SOC12)。
  6. 第三次Timer2触发:再次启动SOC12和SOC13的转换。 如此循环,实现了两组信号的交替采样。结果分别存放在ADCRESULT12/13ADCRESULT14/15中。

关键警告与排查点BURSTSIZE的约束:手册中明确强调,(BURSTSIZE + 1)必须小于或等于配置为轮询优先级的SOC数量。在上例中,轮询SOC是12,13,14,15共4个,因此BURSTSIZE最大可以设为3(一次触发4个转换)。如果你错误地设为4或更大,Burst模式的行为将是未定义的,很可能导致采样序列混乱。这是配置Burst模式时必须检查的第一条规则。

5.3 Burst模式与高优先级SOC的协同

Burst模式只管理轮询优先级的SOC。高优先级SOC仍然遵循其原有的中断逻辑。图11-7清晰地展示了混合场景:当Burst触发和高优先级SOC触发同时到来时,高优先级SOC会立即中断当前的Burst序列,在其转换完成后,Burst序列再从被中断的地方继续。这种机制允许你将最关键的、实时性要求最高的采样任务(如故障保护电流采样)设置为高优先级,而将常规的、序列化的采样任务(如多路温度巡检)交给Burst模式,从而精细地控制ADC资源。

6. 实战配置流程、常见问题与深度调试技巧

掌握了核心原理和案例,让我们梳理一个完整的ADC配置流程,并探讨那些让工程师头疼的典型问题。

6.1 完整的ADC初始化与配置流程

  1. 系统级准备: 确保系统时钟(SYSCLK)已正确配置并稳定。计算所需的ADCCLK,并设置ADCCTL2.PRESCALE。记住,ADCCLK最大频率需查阅芯片数据手册。
  2. ADC模块初始化
    // 假设使用TI的driverlib库 ADC_disableConverter(ADCA_BASE); // 关闭转换器 ADC_enableConverter(ADCA_BASE); // 上电并等待稳定 (参考手册要求的时间) DELAY_US(1000); // 典型延时1ms ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_2_0); // 设置ADCCLK分频 ADC_setMode(ADCA_BASE, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_DIFFERENTIAL); // 设置16位差分模式
  3. SOC配置: 根据你的采样方案,逐个配置ADCSOCxCTL寄存器,设定CHSEL,ACQPS,TRIGSEL
  4. 优先级与Burst配置: 如果需要,配置ADCSOCPRIORITYCTL设置高优先级SOC。如果需要Burst模式,配置ADCBURSTCTL
  5. 中断配置: 如果需要转换完成中断,配置相应的ADCINT中断选择寄存器(ADCINTSELxNy),指定由哪个SOC的完成(EOC)来触发哪个ADC中断(ADCINT1-4),然后在PIE模块中使能对应的中断。
  6. 启动触发源: 最后,使能你选择的硬件触发源(如启动ePWM模块、CPU定时器等)。

6.2 常见问题排查清单

当你发现ADC采样值不对、时序混乱或中断不触发时,可以按以下清单排查:

现象可能原因排查步骤
采样值全为0或固定值1. 通道配置错误(CHSEL)。
2. 硬件连接问题(线断了、引脚复用错误)。
3. 参考电压(VREFHI/LO)异常。
4. 信号超出量程(低于VREFLO或高于VREFHI)。
1. 用万用表测量实际输入引脚电压。
2. 检查GPIO复用寄存器,确认引脚已配置为ADC功能。
3. 测量VREFHI和VREFLO引脚电压。
4. 尝试输入一个中间电平(如VREFHI/2)测试。
采样值噪声大、跳动1. 采样窗口(ACQPS)太短,采样不充分。
2. 前端信号调理电路阻抗过高或驱动能力不足。
3. 电源或地噪声大。
4. 数字开关噪声耦合(未做模拟/数字隔离)。
1.逐步增大ACQPS值,观察噪声是否减小。这是最直接的验证方法。
2. 检查前端运放是否工作在线性区,输出阻抗是否足够低。
3. 检查PCB布局,模拟部分是否使用了独立的LC滤波和单点接地。
转换序列不按预期顺序执行1. 优先级仲裁机制理解有误(轮询指针影响)。
2. 高优先级SOC中断了预期序列。
3. Burst模式下BURSTSIZE设置错误。
1. 在调试器中观察ADCSOCPRIORITYCTL寄存器和RRPOINTER值的变化。
2. 检查是否意外配置了高优先级SOC。
3. 核对轮询SOC数量与BURSTSIZE+1的关系。
ADC中断无法进入1. 中断配置错误(SOC到ADCINT的映射、PIE组使能、CPU级IER使能)。
2. 中断标志未清除。
3. 转换未完成(EOC未产生)。
1. 检查ADCINTSELxNyPIEIERIER寄存器配置。
2. 在中断服务程序(ISR)开头,读取并清除ADCINTFLGPIEACK标志。
3. 检查触发源是否正常工作,SOC是否被正确触发。
双ADC同步采样失败1. 两个ADC的时钟(ADCCLK)不同步(PRESCALE设置不同)。
2. 触发信号未同步到达两个ADC。
3. SOC配置不一致(如ACQPS不同导致转换结束时间不同)。
1.确保ADCA和ADCB的PRESCALE值完全相同
2. 使用同一个ePWM模块的SOCA/SOCB信号分别触发两个ADC的SOC。
3. 检查两个ADC对应SOC的ACQPSCHSEL配置是否对称。

6.3 深度调试技巧:利用时间戳与状态寄存器

F2837xD的ADC提供了强大的诊断功能:

  • ADCCOUNTER寄存器: 这是一个自由运行的计数器,在每个ADCCLK周期递增。你可以在SOC触发时(通过中断或查询)和转换完成时读取它,精确计算从触发到采样的延时,以及采样窗口的实际持续时间。这对于验证精确定时应用(如PWM中心对齐采样)至关重要。
  • ADCSOCFLG1寄存器: 每个SOC都有一个标志位。当SOC被触发(pending)时,对应位置1;当转换启动(START)时,该位清零。监控这些标志位,可以清晰地看到SOC的触发、排队和执行状态。
  • ADCSOCFRC1寄存器: 除了用于软件触发,你也可以读取它来了解哪些SOC被强制触发了。

一个实用的调试方法:在初始化完成后,先不使用硬件触发,而是通过软件触发(ADCSOCFRC1)一个简单的单通道转换,然后在循环中查询结果寄存器。如果这样能得到正确值,说明ADC基础功能、通道和参考电压是好的。然后再逐步加入硬件触发、多SOC、中断等复杂逻辑,这样能有效隔离问题。