基于DSP28335实现多通道ADC采样的解决方案

2025-12-24

基于DSP28335实现多通道ADC采样的解决方案


一、硬件配置要点

  1. 时钟配置

    // 初始化系统时钟(100MHz SYSCLKOUT)
    InitSysCtrl();  
    // 配置ADC时钟分频(HSPCLK=25MHz)
    SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;  // 使能ADC时钟
    SysCtrlRegs.HISPCP.all = 3;            // HSPCLK = SYSCLKOUT/(2 * 3)=25MHz
    
  2. GPIO配置

    // 配置ADC输入通道(示例:GPIO0-7为模拟输入)
    EALLOW;
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;  // 设置GPIO0为模拟输入
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0;
    // ... 配置GPIO1-7
    EDIS;
    

二、ADC模块初始化

void InitAdc(void) {
    EALLOW;
    // 校准ADC
    AdcRegs.ADCTRL3.bit.CAL = 1;  
    while(AdcRegs.ADCTRL3.bit.CAL != 0);  
    
    // 基础配置
    AdcRegs.ADCTRL1.bit.ADCPWDWN = 0;  // 退出省电模式
    AdcRegs.ADCTRL3.bit.SMODE_SEL = 0; // 顺序采样模式
    AdcRegs.ADCTRL1.bit.SEQ_CASC = 0;  // 双序列发生器模式
    AdcRegs.ADCTRL1.bit.CONT_RUN = 1;  // 连续运行模式
    AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // 使能SEQ1中断
    
    // 通道配置(配置8个通道顺序采样)
    AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x7; // 最大转换数7
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // 通道0
    AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // 通道1
    AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2; // 通道2
    AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3; // 通道3
    AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4; // 通道4
    AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5; // 通道5
    AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6; // 通道6
    AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7; // 通道7
    EDIS;
}

三、中断服务程序

interrupt void adc_isr(void) {
    static Uint16 sampleIndex = 0;
    static float adcBuffer[8][100]; // 8通道环形缓冲区
    
    // 读取所有通道数据
    adcBuffer[0][sampleIndex] = (AdcRegs.ADCRESULT0) >> 4; // 通道0
    adcBuffer[1][sampleIndex] = (AdcRegs.ADCRESULT1) >> 4; // 通道1
    // ... 读取通道2-7
    
    // 数据滤波(移动平均)
    static float filterBuffer[8][10] = {0};
    for(int ch=0; ch<8; ch++) {
        filterBuffer[ch][sampleIndex%10] = adcBuffer[ch][sampleIndex];
        float sum = 0;
        for(int i=0; i<10; i++) sum += filterBuffer[ch][i];
        processedData[ch] = sum / 10.0f;
    }
    
    sampleIndex++;
    if(sampleIndex >= 100) sampleIndex = 0; // 环形缓冲区复位
    
    // 清除中断标志
    AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

四、触发模式配置

1. 软件触发模式

AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // 立即启动SEQ1

2. ePWM触发模式(示例:EPWM1触发)

// 配置EPWM1 SOCA事件
EPwm1Regs.TBPRD = 1000;             // PWM周期
EPwm1Regs.CMPA.half.CMPA = 500;     // 50%占空比
EPwm1Regs.ETSEL.bit.SOCAEN = 1;     // 使能SOCA
EPwm1Regs.ETPS.bit.SOCAPRD = 1;     // 每个周期触发一次

参考代码 TI的 DSP28335 多通道ADC采样程序 www.3dddown.com/csa/56837.html

五、关键优化策略

  1. 采样率控制

    // 设置采样窗口时间(单位:系统时钟周期)
    AdcRegs.ADCSOC0CTL.bit.ACQPS = 14; // 15个时钟周期采样保持
    
  2. 数据对齐

    // 右对齐12位数据(默认左对齐需右移4位)
    AdcRegs.ADCCTL2.bit.ADCREFSEL = 0; // 使用内部1.2V参考电压
    
  3. 多通道同步

    // 同步通道0-3的采样时间
    AdcRegs.ADCSOC0CTL.bit.CHSEL = 0x0;
    AdcRegs.ADCSOC1CTL.bit.CHSEL = 0x1;
    AdcRegs.ADCSOC0CTL.bit.ACQPS = 14; // 统一采样保持时间
    

六、调试技巧

  1. 示波器验证

    • 观察ADCSOC信号上升沿与模拟输入信号的同步性
    • 检查ADCINT中断信号频率是否符合预期
  2. 寄存器监控

    // 查看当前转换序列状态
    volatile Uint16 seqStatus = AdcRegs.ADCST.bit.SEQ1_STATE;
    
  3. 参考电压校准

    // 执行系统校准
    EALLOW;
    AdcRegs.ADCTRL3.bit.CAL = 1;
    while(AdcRegs.ADCTRL3.bit.CAL != 0);
    EDIS;
    

七、扩展应用

闭环控制系统集成示例

// 在中断服务程序中添加控制逻辑
interrupt void adc_isr(void) {
    // ... 原有数据读取代码
    
    // 闭环控制示例(PID调节)
    static float error_sum = 0;
    float current = processedData[0] * 3.3f; // 通道0电压值
    float error = target_voltage - current;
    error_sum += error;
    float pwm_duty = Kp*error + Ki*error_sum + Kd*(error - prev_error);
    EPwm1Regs.CMPA.half.CMPA = (Uint16)(pwm_duty * 1000); // 更新占空比
    prev_error = error;
}

建议结合TI官方示例程序(如ADCSOC_INT)进行深度优化,并参考《TMS320F28335 Technical Reference Manual》第14章ADC模块说明。