1. 项目背景与核心需求在工业测量、医疗设备和环境监测等领域我们经常需要将模拟信号转换为数字信号进行处理。模拟信号是连续的物理量如温度、压力、光强等而数字信号则是离散的二进制数值。ADS122U04作为一款24位高精度Δ-Σ模数转换器(ADC)配合STM32F767ZG高性能微控制器能够实现高精度的模拟信号采集和数字转换。这个组合特别适合以下场景需要高精度测量的工业传感器如称重传感器、压力传感器医疗设备中的生物电信号采集如ECG、EEG环境监测系统温湿度、大气压力等2. 硬件选型与配置2.1 ADS122U04关键特性ADS122U04是TI公司推出的24位低功耗ADC具有以下突出特点24位无失码分辨率数据速率可达2kSPS内置可编程增益放大器(PGA)增益1~128低噪声150nV RMS增益12820SPS工作电压2.3V至5.5V集成温度传感器和电压基准实际应用中24位分辨率意味着可以检测到μV级别的电压变化。例如在称重系统中可以检测到0.1克以下的重量变化。2.2 STM32F767ZG接口配置STM32F767ZG通过SPI接口与ADS122U04通信典型硬件连接如下ADS122U04 STM32F767ZG ----------------------------- VDD → 3.3V GND → GND DRDY → PA0 (外部中断) CS → PA4 (SPI片选) SCLK → PA5 (SPI时钟) DIN → PA7 (SPI MOSI) DOUT → PA6 (SPI MISO)在CubeMX中的配置步骤启用SPI1模式为全双工主模式设置预分频器使SPI时钟≤10MHzADS122U04最大支持配置PA0为外部中断输入下降沿触发配置PA4为GPIO输出手动控制片选注意ADS122U04的DRDY信号是开漏输出建议在STM32端加上拉电阻4.7kΩ3. 软件实现与寄存器配置3.1 ADS122U04初始化ADS122U04通过SPI命令和寄存器进行配置。上电后需要配置以下关键寄存器// 寄存器配置示例 typedef struct { uint8_t CONFIG0; // 数据速率、模式等 uint8_t CONFIG1; // 增益、输入选择 uint8_t CONFIG2; // 基准电压、温度传感器 uint8_t CONFIG3; // 数据就绪、校准设置 } ADS122U04_Config; void ADS122U04_Init(void) { // 复位设备 HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_RESET); uint8_t reset_cmd 0x06; // 复位命令 HAL_SPI_Transmit(hspi1, reset_cmd, 1, 100); HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_SET); HAL_Delay(10); // 配置寄存器 ADS122U04_Config config { .CONFIG0 0x01, // 20SPS, 普通模式 .CONFIG1 0x04, // 增益8, 差分输入AIN0/AIN1 .CONFIG2 0x10, // 使用内部2.048V基准 .CONFIG3 0x00 // 默认设置 }; uint8_t write_cmd[5] {0x40, config.CONFIG0, config.CONFIG1, config.CONFIG2, config.CONFIG3}; HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(hspi1, write_cmd, 5, 100); HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_SET); // 启动连续转换 uint8_t start_cmd 0x08; HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(hspi1, start_cmd, 1, 100); HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_SET); }3.2 数据采集实现利用STM32的外部中断和DMA实现高效数据采集// 外部中断回调函数 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin ADS_DRDY_Pin) { static uint8_t rx_data[3]; HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Receive(hspi1, rx_data, 3, 100); HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_SET); int32_t adc_value (rx_data[0] 16) | (rx_data[1] 8) | rx_data[2]; if(adc_value 0x800000) { // 处理24位有符号数 adc_value | 0xFF000000; } // 转换为实际电压值 (增益8, 基准2.048V) float voltage (adc_value * 2.048f) / (8388608.0f * 8); process_measurement(voltage); } }4. 精度优化与噪声抑制4.1 PCB布局建议高精度ADC对PCB布局非常敏感将ADS122U04尽可能靠近传感器放置使用独立的模拟地和数字地单点连接电源引脚添加10μF钽电容0.1μF陶瓷电容去耦模拟信号走线远离数字信号和高频信号使用屏蔽电缆连接传感器4.2 软件滤波技术结合硬件特性可采用以下滤波方法移动平均滤波取多个采样值求平均#define FILTER_SIZE 16 float moving_avg_filter(float new_sample) { static float buffer[FILTER_SIZE]; static uint8_t index 0; static float sum 0; sum - buffer[index]; buffer[index] new_sample; sum new_sample; index (index 1) % FILTER_SIZE; return sum / FILTER_SIZE; }IIR低通滤波适合实时处理float iir_filter(float new_sample) { static float prev_output 0; float alpha 0.1; // 滤波系数 float output alpha * new_sample (1 - alpha) * prev_output; prev_output output; return output; }去除工频干扰采用50/60Hz陷波滤波5. 实际应用案例热电偶温度测量5.1 硬件连接使用K型热电偶测量高温0-1200°C热电偶 → AIN0 (ADS122U04) 热电偶- → AIN1 REF → 2.048V基准 REF- → GND5.2 冷端补偿热电偶需要冷端补偿CJCfloat read_temperature(void) { // 读取热电偶电压 float thermocouple_voltage read_ads122u04(); // 读取冷端温度使用ADS122U04内置温度传感器 float cjc_temp read_internal_temp(); // 使用多项式近似计算温度 float temp thermocouple_voltage * 25.5f; // 近似系数 temp 0.1f * thermocouple_voltage * thermocouple_voltage; temp cjc_temp; // 冷端补偿 return temp; }5.3 校准与线性化高精度测量需要分段校准typedef struct { float min_temp; float max_temp; float coeff[3]; // 多项式系数 } Calibration_Segment; float calibrated_temperature(float raw_temp) { static const Calibration_Segment segments[] { {0, 100, {0.98, 0.012, 0.0001}}, {100, 300, {1.02, 0.011, 0.00008}}, {300, 600, {1.05, 0.010, 0.00005}}, {600, 1200, {1.08, 0.009, 0.00003}} }; for(int i0; i4; i) { if(raw_temp segments[i].min_temp raw_temp segments[i].max_temp) { float temp segments[i].coeff[0] * raw_temp; temp segments[i].coeff[1] * raw_temp * raw_temp; temp segments[i].coeff[2] * raw_temp * raw_temp * raw_temp; return temp; } } return raw_temp; }6. 常见问题与调试技巧6.1 数据不稳定问题排查检查电源噪声用示波器观察ADC电源引脚确保纹波10mVpp必要时增加LC滤波验证基准电压测量REF引脚电压内部基准精度±0.1%温漂5ppm/°C检查SPI时序确保SCLK频率不超过10MHzCS信号在传输前后保持足够时间6.2 精度优化技巧系统校准方法零点校准短接输入端读取偏移量满量程校准输入已知参考电压存储校准系数到STM32 Flash温度补偿使用ADS122U04内置温度传感器建立温度-误差查找表接地技巧星型接地布局避免地环路敏感电路使用独立电源6.3 低功耗设计对于电池供电设备配置ADS122U04为单次转换模式关闭不用的模拟前端电路使用STM32低功耗模式STOP模式动态调整数据速率void enter_low_power_mode(void) { // 配置ADS122U04为单次模式 uint8_t cmd 0x02; // 单次转换命令 HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Transmit(hspi1, cmd, 1, 100); HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_SET); // 配置STM32进入STOP模式 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); }