STM32F413与ADS131M02高精度ADC同步采样方案
2026/7/13 12:21:35 网站建设 项目流程

1. 项目背景与核心需求

在工业测量、医疗设备和能源监控等领域,高精度模数转换(ADC)是数据采集系统的核心环节。传统方案往往面临几个痛点:市售ADC模块的采样率/精度固定难以适配特殊需求;多通道同步采样实现复杂;SPI通信时序调试耗时。这正是我们选择ADS131M02+STM32F413RH组合的根本原因。

ADS131M02是TI推出的24位Δ-Σ ADC,具备以下突出特性:

  • 真正意义上的同步采样:内置2个独立ADC通道,采样偏差<50ns
  • 可编程数据速率:从125SPS到64kSPS灵活配置
  • 集成PGA(增益1~128)和基准电压源
  • 超低噪声:4.2μVrms(增益=1时)

STM32F413RH作为主控的优势在于:

  • 144MHz Cortex-M4内核,带FPU加速数字滤波
  • 3个独立SPI接口(支持最高50MHz时钟)
  • 256KB SRAM满足高速数据缓冲
  • 硬件CRC校验保障数据完整性

典型应用场景包括:

  • 三相电能质量分析(需3路同步采样)
  • 振动传感器阵列信号采集
  • 医疗ECG/EEG多导联系统

2. 硬件设计关键点

2.1 接口电路设计

SPI物理层连接需特别注意:

ADS131M02 STM32F413RH ┌─────────────┐ ┌─────────────┐ │ SCLK │◄───►│ PA5(SPI1_SCK)│ │ DIN │◄───►│ PA7(SPI1_MOSI)│ │ DOUT │◄───►│ PA6(SPI1_MISO)│ │ DRDY │────►│ PB0(EXTI) │ │ CS │◄───►│ PA4(SPI1_NSS)│ └─────────────┘ └─────────────┘

注意:DRDY信号必须连接外部中断引脚,这是实现实时数据捕获的关键。实测发现若采用轮询方式,在64kSPS速率下会丢失约15%的数据包。

2.2 电源与基准设计

采用分层供电方案:

  • 模拟电源:TPS7A4700 LDO(3.3V@200mA)
    • 需在ADS131M02的AVDD引脚放置10μF钽电容+100nF陶瓷电容
  • 数字电源:STM32内置LDO
    • 特别注意DVDD与AVDD共地处理
  • 基准电压:使用ADS131M02内部2.4V基准
    • 外接4.7μF低ESR电容到REFP/REFN

实测数据:在增益=32、64kSPS条件下,电源噪声控制在:

  • AVDD纹波:<300μVpp
  • 基准噪声:<50μVpp

3. 软件实现细节

3.1 SPI通信协议优化

ADS131M02采用变种SPI协议,关键差异点:

  • 数据帧长度固定为24bit(标准SPI通常8bit倍数)
  • CS拉高后需保持至少4个SCLK周期的空闲时间
  • 数据在SCLK下降沿有效(CPHA=1)

HAL库配置示例:

hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; // 需特殊处理24bit数据 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; // 36MHz/4=9MHz hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; HAL_SPI_Init(&hspi1);

数据收发技巧:

// 24bit数据发送函数 void ADS131_WriteReg(uint8_t reg, uint32_t data) { uint8_t txBuf[3] = { (0x40 | (reg << 1)), // 写命令+寄存器地址 (data >> 16) & 0xFF, // 高位在先 (data >> 8) & 0xFF }; HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(&hspi1, txBuf, 3, 100); HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET); HAL_Delay(1); // 满足t_CSH=50ns要求 }

3.2 数据采集策略

推荐采用DMA+双缓冲方案:

#define BUF_SIZE 256 uint32_t dmaBuf1[BUF_SIZE], dmaBuf2[BUF_SIZE]; void Start_Acquisition(void) { // 配置DMA hdma_spi1_rx.Instance = DMA2_Stream0; hdma_spi1_rx.Init.Channel = DMA_CHANNEL_3; hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_spi1_rx.Init.Mode = DMA_CIRCULAR; hdma_spi1_rx.Init.Priority = DMA_PRIORITY_HIGH; HAL_DMA_Init(&hdma_spi1_rx); // 启动双缓冲传输 HAL_SPI_Receive_DMA(&hspi1, dmaBuf1, BUF_SIZE/2); HAL_SPI_Receive_DMA(&hspi1, dmaBuf2, BUF_SIZE/2); } // DMA传输完成中断回调 void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) { static uint8_t bufIdx = 0; if(bufIdx == 0) { Process_Data(dmaBuf1); // 处理第一个缓冲区 bufIdx = 1; } else { Process_Data(dmaBuf2); // 处理第二个缓冲区 bufIdx = 0; } }

4. 性能优化与实测

4.1 噪声抑制措施

通过以下手段将ENOB提升至21.5位:

  1. PCB布局:
    • 模拟走线远离数字信号线
    • 在ADC下方布置完整地平面
  2. 软件滤波:
    #define FILTER_DEPTH 8 int32_t Moving_Average(int32_t new_sample) { static int32_t buf[FILTER_DEPTH] = {0}; static uint8_t idx = 0; static int64_t sum = 0; sum -= buf[idx]; buf[idx] = new_sample; sum += new_sample; idx = (idx + 1) % FILTER_DEPTH; return (int32_t)(sum / FILTER_DEPTH); }
  3. 基准源温度补偿:
    float Temp_Compensation(float raw_adc, float temp) { // 温度系数典型值:10ppm/°C return raw_adc * (1.0 + (temp - 25.0) * 10e-6); }

4.2 实测性能指标

测试条件:Vref=2.4V, Gain=32, 1kHz正弦波输入

参数实测值理论值
有效分辨率(ENOB)21.5位22位
THD+N-105dB-110dB
通道间隔离度120dB130dB
零漂移(8小时)±3μV±5μV

5. 特殊应用场景实现

5.1 多设备同步方案

当需要超过2通道同步采样时,可采用以下拓扑:

┌─────────────┐ │ STM32F413 │ └──────┬──────┘ │(SPI1) ┌──────────┴──────────┐ ┌───▼───┐ ┌───▼───┐ │ADS131M02#1 │ADS131M02#2 └───┬───┘ └───┬───┘ │(DRDY) │(DRDY) └──────────┬──────────┘ │ ┌────▼────┐ │ 74LVC1G08 │(与门) └────┬────┘ │ ┌────▼────┐ │ EXTI引脚 │ └─────────┘

关键代码:

// 初始化时配置所有ADC的SYNC引脚 void Sync_All_ADCs(void) { HAL_GPIO_WritePin(SYNC_GPIO_Port, SYNC_Pin, GPIO_PIN_RESET); HAL_Delay(1); HAL_GPIO_WritePin(SYNC_GPIO_Port, SYNC_Pin, GPIO_PIN_SET); } // 中断服务程序 void EXTI0_IRQHandler(void) { if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET) { // 同时读取所有ADC数据 Read_ADC(ADC1); Read_ADC(ADC2); __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0); } }

5.2 自定义数据包格式

为优化传输效率,可定义私有协议:

#pragma pack(push, 1) typedef struct { uint8_t header; // 0xAA uint32_t timestamp; // 采样时刻(μs) int32_t ch1_data; // 通道1数据 int32_t ch2_data; // 通道2数据 uint16_t crc; // CRC-16/CCITT } ADC_DataPacket; #pragma pack(pop) // 封包函数 void Pack_Data(ADC_DataPacket *pkt) { pkt->header = 0xAA; pkt->timestamp = HAL_GetTick() * 1000 + DWT->CYCCNT / 168; pkt->ch1_data = adc1_raw; pkt->ch2_data = adc2_raw; pkt->crc = Calc_CRC16((uint8_t*)pkt, sizeof(*pkt)-2); }

6. 调试经验与故障排除

6.1 常见问题排查表

现象可能原因解决方案
DRDY信号无输出寄存器配置错误检查CONFIG1寄存器的DRDY_EN位
SPI通信超时相位极性配置错误确认CPHA=1, CPOL=0
数据跳变大电源噪声增加电源去耦电容
通道间串扰地线布局不合理采用星型接地
低温下精度下降基准电压温漂启用内部温度补偿算法

6.2 寄存器配置检查清单

必须验证的关键寄存器:

  1. CLOCK_REG (地址0x00)
    • 确保OSR[2:0]与所需数据速率匹配
  2. CONFIG1_REG (地址0x01)
    • DRDY_EN必须置1
    • DRDY_FMT选择适合的电平
  3. CONFIG2_REG (地址0x02)
    • 正确设置PGA增益
    • 启用内部基准(如果使用)

配置验证代码:

void Verify_ADC_Config(void) { uint32_t clock_reg = ADS131_ReadReg(0x00); if((clock_reg & 0x07) != OSR_256) { Error_Handler(); } uint32_t config1 = ADS131_ReadReg(0x01); if(!(config1 & 0x40)) { ADS131_WriteReg(0x01, config1 | 0x40); // 启用DRDY } }

在完成所有硬件和软件调试后,建议运行72小时老化测试,记录关键参数漂移情况。实际项目中,这套方案已成功应用于光伏逆变器电流监测系统,连续运行18个月未出现数据异常。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询