F28335双采样保持器实战:如何同时采集两路传感器信号

在工业测控领域,多通道同步数据采集一直是工程师面临的经典挑战。想象一下这样的场景:当我们需要实时监测液压系统的运行状态时,压力传感器的瞬态波动与温度传感器的滞后响应往往存在微妙的时间差,这种毫秒级的偏差可能导致控制算法误判系统状态。而TMS320F28335数字信号处理器独有的双采样保持器(S/H)架构,正是为解决这类问题而生的利器。

本文将带您深入探索F28335的ADC模块设计精髓,重点解析其双采样保持器的协同工作机制。不同于普通ADC的顺序采样模式,这种硬件级并行采样能力可以让A0-A7和B0-B7两组输入通道实现真正的同步捕获,特别适合需要严格时序对齐的振动分析、功率测量等应用场景。我们将通过一个温度+压力双通道采集的完整案例,展示从寄存器配置到数据处理的每个技术细节。

1. 双采样保持器的架构奥秘

1.1 硬件结构解析

打开F28335的芯片手册,其ADC模块的框图会揭示一个精妙的设计:两套完全独立的采样保持电路S/H-A和S/H-B,就像拥有双瞳孔的眼睛,可以同时捕捉两个不同的信号瞬间。这种架构带来了三个关键优势:

  • 真正的物理并行:当S/H-A锁定ADCINA0电压值时,S/H-B可以同步锁定ADCINB0的电压,两者误差控制在纳秒级
  • 独立的通道组:A组(ADCINA0-7)与B组(ADCINB0-7)各有8个通道,通过交叉开关矩阵可灵活配置采样组合
  • 共享量化核心:两路采样信号通过多路复用器交替进入同一个12位SAR ADC进行转换,在保证精度的同时降低成本

1.2 时序同步机制

理解双采样保持器的触发时序是正确配置的关键。下图展示了典型的工作时序:

时间点 S/H-A动作 S/H-B动作 ADC核心状态
t0 开始采样 开始采样 空闲
t0+ts 保持 保持 转换A路
t0+ts+tc 释放 释放 转换B路
t0+2ts+tc 准备下一周期 准备下一周期 空闲

注:ts为采样时间(由ACQ_PS设定),tc为转换时间(约12个ADCCLK周期)

这种乒乓操作模式确保了在两路信号采样的间隔期内,ADC核心有充足时间完成前次转换。实际配置时需要特别注意:

// 关键时序参数设置示例
AdcRegs.ADCTRL1.bit.ACQ_PS = 0xF;  // 采样窗口=16个ADCCLK周期
AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x1; // ADCCLK=HSPCLK/2=12.5MHz

2. 双通道同步采集实战

2.1 硬件连接方案

假设我们需要同时采集热电偶(接ADCINA3)和压力变送器(接ADCINB2)信号,硬件连接需注意:

  • 信号调理电路:两组输入应配置相同的滤波参数(如RC时间常数)
  • 参考电压:确保VREFHI/VREFLO连接稳定,建议使用专用基准源
  • 接地处理:模拟地AGND与数字地DGND单点连接,避免地环路干扰

2.2 寄存器配置详解

以下是实现双通道同步采样的核心代码片段:

void InitDualSampleADC(void) {
    EALLOW;
    // 时钟配置
    SysCtrlRegs.HISPCP.all = 0x3;  // HSPCLK = 150MHz/(2*3)=25MHz
    AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x1; // ADCCLK=12.5MHz
    
    // 双采样保持器模式设置
    AdcRegs.ADCTRL1.bit.SEQ_CASC = 0;   // 双序列器独立模式
    AdcRegs.ADCTRL1.bit.SIMULATE_SAMPLING = 1; // 使能同步采样
    
    // 通道选择
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // SEQ1转换ADCINA3
    AdcRegs.ADCCHSELSEQ2.bit.CONV00 = 0xA; // SEQ2转换ADCINB2 (0xA=10)
    
    // 触发设置
    AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // SEQ1由ePWM1触发
    AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2 = 1; // SEQ2由ePWM1同步触发
    EDIS;
}

这段代码有几个精妙之处:

  1. SIMULATE_SAMPLING位实际控制着双采样保持器的同步使能,尽管名称容易误解
  2. 通过ePWM模块的SOCA和SOCB信号同步触发两个序列器,确保采样时刻一致
  3. 独立序列器模式下,SEQ1和SEQ2可以分别处理A组和B组通道

2.3 数据读取与对齐

同步采集的数据需要特殊处理才能保证时间戳对齐:

#pragma DATA_SECTION(SampleBuffer, "ADCBuf");
Uint16 SampleBuffer[4]; // 交替存储A/B路数据

void ReadDualSampleData(void) {
    while(!AdcRegs.ADCST.bit.INT_SEQ1 && !AdcRegs.ADCST.bit.INT_SEQ2);
    
    SampleBuffer[0] = AdcRegs.ADCRESULT0 >> 4; // A路数据
    SampleBuffer[1] = AdcRegs.ADCRESULT1 >> 4; // B路数据
    
    // 清除中断标志
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
    AdcRegs.ADCST.bit.INT_SEQ2_CLR = 1;
}

重要提示:在实际应用中建议启用DMA传输,避免频繁中断影响系统实时性。F28335的DMA控制器可以直接将ADCRESULTx寄存器内容搬运到指定内存区域。

3. 性能优化技巧

3.1 采样时序校准

双通道同步的精度可以通过以下方法进一步提升:

  1. 时钟相位调整

    AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x1; // 主时钟分频
    AdcRegs.ADCTRL3.bit.SMODE_SEL = 1;  // 采样时钟同步模式
    
  2. 窗口时间计算: 采样保持时间应满足: $$ t_{hold} > t_{aperture} + R_{source} \times C_{hold} \times ln(2^{N+1}) $$ 其中N为ADC分辨率(12位),典型配置:

    AdcRegs.ADCTRL1.bit.ACQ_PS = 0xF; // 16个ADCCLK周期@12.5MHz=1.28μs
    

3.2 抗干扰设计

工业环境中的噪声会影响同步精度,推荐措施:

  • PCB布局

    • 将A组和B组信号走线对称布置
    • 采样保持电容引脚放置去耦电容(10nF+100pF组合)
  • 软件滤波: 采用移动平均算法时,需保持两组数据窗口一致:

    #define FILTER_DEPTH 8
    Uint16 tempHistory[FILTER_DEPTH], pressHistory[FILTER_DEPTH];
    
    void DualChannelFilter(Uint16 temp, Uint16 press) {
        static int index = 0;
        tempHistory[index] = temp;
        pressHistory[index] = press;
        index = (index + 1) % FILTER_DEPTH;
    }
    

4. 典型应用场景剖析

4.1 三相功率测量

在电机控制中,需要同步采集三相电压和电流:

  1. 配置方案:

    • A组:ADCINA0-2接电压信号
    • B组:ADCINB0-2接电流信号
    • 触发源:ePWM1周期匹配触发
  2. 关键代码:

    AdcRegs.ADCCHSELSEQ1.all = 0x210; // A0,A1,A2
    AdcRegs.ADCCHSELSEQ2.all = 0xBA9; // B0,B1,B2
    AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;
    

4.2 振动信号分析

对于需要相位关系的振动传感器信号:

  • 采样率配置:

    // 设置1MHz采样率(每通道500ksps)
    SysCtrlRegs.HISPCP.all = 0x1; // HSPCLK=75MHz
    AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x0; // ADCCLK=37.5MHz
    AdcRegs.ADCTRL1.bit.ACQ_PS = 0x3; // 采样窗口=4周期@37.5MHz≈107ns
    
  • 数据缓存建议: 使用乒乓缓冲区存储连续采样数据,便于后续FFT分析:

    #define BUF_SIZE 1024
    Uint16 vibBufferA[BUF_SIZE], vibBufferB[BUF_SIZE];
    volatile int bufIndex = 0;
    
    __interrupt void adc_isr(void) {
        vibBufferA[bufIndex] = AdcRegs.ADCRESULT0 >> 4;
        vibBufferB[bufIndex] = AdcRegs.ADCRESULT1 >> 4;
        if(++bufIndex >= BUF_SIZE) {
            bufIndex = 0;
            // 触发数据处理
        }
    }
    

在完成这些配置后,一个常见的误区是忽视温度漂移对同步精度的影响。我在某次电机测试项目中曾发现,随着芯片温度升高,两路采样间隔会出现约0.5%的偏差。解决方法是在ADC初始化后启用内部温度传感器,定期校准采样时序参数。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐