[应用相关] STM32与ADS1220高精度采集

[复制链接]
1155|25
晓伍 发表于 2025-11-11 21:19 | 显示全部楼层 |阅读模式
在工业自动化、环境监测和医疗设备中,微弱信号的精确采集始终是嵌入式系统设计的核心挑战。比如,一个称重传感器输出的差分电压可能仅有几毫伏甚至几百微伏,若使用普通MCU内置的12位ADC(如STM32F103自带的ADC),其理论最小分辨电压约为1.2mV(以3.3V参考电压计算),显然无法满足需求。更不用说,在实际应用中还存在噪声干扰、温漂、电源波动等问题,使得小信号测量更加困难。

正是在这种背景下,“外置高精度ADC + 通用MCU”的架构逐渐成为主流方案。TI推出的 ADS1220 作为一款集成了可编程增益放大器(PGA)、Σ-Δ调制器、数字滤波器和SPI接口的24位ADC芯片,恰好填补了这一空白。它不仅能将输入信号放大128倍,还能通过内部陷波滤波抑制工频干扰,非常适合用于RTD测温、称重模块、心电前置等对精度要求极高的场景。

而搭配 STM32F103 这类成本低、生态成熟、开发便捷的Cortex-M3控制器,则构成了一个兼顾性能与性价比的理想组合。这套系统不仅能在便携设备中实现亚微伏级分辨率的数据采集,还可通过UART上传数据、OLED显示结果或接入无线网络,具备良好的扩展性。

ADS1220本质上是一款面向精密模拟前端的Σ-Δ型ADC。它的核心优势不在于速度——最高仅支持1kSPS采样率,而在于“静”:极低的噪声、高度集成的信号调理功能以及出色的共模抑制能力。这使得它特别适合处理来自桥式电路、热电偶或应变片这类缓慢变化但极其敏感的信号源。

该芯片提供4个差分输入通道(或7个单端输入),用户可通过内部多路复用器灵活选择待测信号路径。更重要的是,其内置的PGA支持1~128倍增益调节。这意味着即使输入信号只有±16mV,也能被放大至接近满量程范围进行转换,从而大幅提升有效分辨率。例如,在使用2.5V外部参考电压且增益设为128时,每LSB对应的电压变化仅为约0.298μV,足以捕捉到细微的物理变化。

为了进一步提升抗干扰能力,ADS1220集成了同步50Hz/60Hz双陷波滤波器,能够有效抑制电力线耦合进来的交流噪声。这对于部署在工厂车间或电网附近的设备尤为重要。此外,它支持两种工作模式:连续转换和单次转换。后者允许系统在非采样期间关闭ADC以节省功耗,非常适合电池供电的应用。

通信方面,ADS1220采用标准四线SPI接口(SCLK、DIN、DOUT、CS),最高支持4MHz时钟频率,与STM32系列MCU天然兼容。所有配置均通过写入四个8位寄存器完成,包括通道选择、增益设置、输出速率、滤波模式等参数。整个过程无需额外驱动库,只需按照手册格式构造命令字即可完成控制。

下面是一段基于STM32 HAL库的SPI初始化代码:

void MX_SPI1_Init(void)
{
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi1.Init.CLSPhase = SPI_PHASE_1EDGE;
    hspi1.Init.NSS = SPI_NSS_SOFT;
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    HAL_SPI_Init(&hspi1);
}




这里配置为SPI Mode 0(CPOL=0, CPHA=0),波特率预分频64,对应APB2总线72MHz下的SCLK约为1.125MHz,完全满足ADS1220的通信要求。NSS采用软件控制,便于精确管理片选时序,避免误触发。

接下来是对ADS1220寄存器的配置函数。关键在于理解每个bit的功能分布。例如,寄存器0(REG0)决定了输入通道和PGA状态:

void ADS1220_WriteRegister(uint8_t reg, uint8_t value)
{
    uint8_t tx_data[2];
    tx_data[0] = (reg << 2) | 0x02;  // 写操作命令:[RegAddr<<2 | 0x02]
    tx_data[1] = value;

    HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
    HAL_SPI_Transmit(&hspi1, tx_data, 2, 100);
    HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
}

void ADS1220_Config(void)
{
    ADS1220_WriteRegister(0, 0x20);  // AIN0-AIN1差分输入,PGA=128,缓冲关闭
    ADS1220_WriteRegister(1, 0x43);  // 100SPS,单周期稳定,禁用斩波
    ADS1220_WriteRegister(2, 0x14);  // 启用50+60Hz滤波
    ADS1220_WriteRegister(3, 0x00);  // 默认设置
}


上述配置实现了最基本的高增益采集模式:选择AIN0与AIN1之间的差分电压作为输入,启用128倍放大,设定输出速率为100SPS,并开启工频抑制滤波。这种设置下,RMS噪声可低至700nV左右,信噪比显著优于大多数集成ADC。

读取转换结果的过程也需注意时序规范。ADS1220在每次转换完成后会拉低 DRDY 引脚,通知主控可以读数。虽然可以通过轮询方式处理,但更高效的做法是将其连接至STM32的外部中断引脚,实现事件驱动式采集。

以下是读取原始码值的实现:

int32_t ADS1220_ReadValue(void)
{
    uint8_t tx_data[4] = {0x10, 0x00, 0x00, 0x00};  // 读数据命令
    uint8_t rx_data[4] = {0};

    HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(&hspi1, tx_data, rx_data, 4, 100);
    HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);

    int32_t result = ((int32_t)rx_data[1] << 16) |
                     ((int32_t)rx_data[2] << 8)  | rx_data[3];

    if (result & 0x800000) {
        result |= 0xFF000000;  // 符号扩展
    }

    return result;
}


返回的是24位补码格式的有符号整数,正值表示AINP > AINN,负值则相反。要将其转换为实际电压,还需结合参考电压和增益系数:

float ADS1220_GetVoltage(float vref, uint8_t gain)
{
    int32_t raw = ADS1220_ReadValue();
    float voltage = (raw * vref) / (gain * 8388608.0f);  // 2^23
    return voltage;
}


假设使用REF3012提供的2.5V基准电压,增益为128,则每个LSB对应约0.298μV。也就是说,理论上系统可以检测到小于1μV的电压变化——这已经接近许多商用万用表的极限精度。

当然,理论分辨率并不等于实际可用精度。系统的稳定性受到多个因素影响,其中最关键是 参考电压的质量 。虽然ADS1220内置1.2V基准,但其负载能力和温漂表现不如专用外部基准源。因此在高精度场合,推荐使用REF3012、LM4040这类低温漂(<20ppm/℃)、低噪声的基准芯片,并通过独立LDO为其供电,避免受数字电源波动影响。

另一个常被忽视的问题是 PCB布局 。尽管原理图设计正确,但如果模拟走线靠近高频数字信号线(如SPI时钟、MCU晶振),很容易引入耦合噪声。建议采取以下措施:
- 模拟地与数字地分离,采用单点接地;
- 在AVDD引脚附近放置0.1μF陶瓷去耦电容,必要时再并联一个10μF钽电容;
- 输入端增加RC低通滤波(如10kΩ + 100nF),防止射频干扰进入前端;
- 使用磁珠隔离DVDD与AVDD电源路径。

软件层面也有优化空间。原始读数往往伴随随机跳动,尤其是当增益较高时。简单的滑动平均滤波就能大幅改善显示稳定性。例如,维护一个长度为16的环形缓冲区,每次更新后计算均值:

#define FILTER_SIZE 16
static float buffer[FILTER_SIZE];
static uint8_t index = 0;

float apply_moving_average(float new_value)
{
    buffer[index] = new_value;
    index = (index + 1) % FILTER_SIZE;

    float sum = 0;
    for (int i = 0; i < FILTER_SIZE; i++) {
        sum += buffer[i];
    }
    return sum / FILTER_SIZE;
}




对于突发性尖峰干扰(如静电放电引起的毛刺),中值滤波更为有效。两者结合使用效果更佳。

此外,零点漂移是长期运行中的常见问题。解决方法是在系统启动时执行一次“空载校准”:短接输入端,读取当前偏移量并保存为offset,在后续测量中予以扣除。类似地,也可以施加已知标准电压进行增益校准,修正比例因子误差。

从整体架构来看,这个系统呈现出典型的“感知—处理—输出”链条:

                    +------------------+
                    |    Sensor        |
                    | (e.g., Load Cell)|
                    +--------+---------+
                             |
                     +-------v--------+     +------------------+
                     |   ADS1220        |<--->|   REF3012        |
                     | 24-bit ADC       |     | 1.2V Precision Ref|
                     +-------+----------+     +------------------+
                             | DRDY (INT)
                             | SCLK, DIN, DOUT, CS
                             v
                    +--------+----------+
                    |   STM32F103       |
                    | ARM Cortex-M3     |
                    +--------+----------+
                             |
                    +--------v---------+
                    |  UART / LCD / SD |
                    | 或无线模块(WiFi) |
                    +------------------+






STM32在这里扮演中枢角色:负责初始化外设、配置ADC、读取数据、执行滤波算法,并最终将结果可视化或上传云端。得益于Cortex-M3内核的硬件乘除单元和高效的中断响应机制,即便在72MHz主频下运行轻量RTOS(如FreeRTOS),也能轻松应对周期性采集任务。

值得一提的是,该系统的低功耗潜力尚未被充分挖掘。如果目标设备是野外部署的无线传感器节点,完全可以利用ADS1220的单次转换模式配合STM32的Stop模式来大幅延长续航。具体策略如下:
- 配置定时器或RTC周期唤醒MCU;
- 唤醒后使能ADS1220,启动一次转换;
- 等待DRDY中断到来,读取数据;
- 处理完毕后再次进入深度睡眠。

在此模式下,整个系统的平均电流可降至几十微安级别。

回顾整个方案的设计逻辑,它并非追求极致性能的技术堆砌,而是围绕“实用、可靠、易实现”展开的工程权衡。没有选用更高分辨率的32位ADC(如ADS1256),是因为24位已足够覆盖绝大多数应用场景;没有采用更高端的MCU,是因为STM32F103的成本和生态优势无可替代;甚至连SPI通信都没有启用DMA,因为数据量小,直接CPU搬运反而更简洁可控。

正是这种务实的态度,让“STM32 + ADS1220”组合在电子秤、温度巡检仪、pH计、生物电信号采集器等领域获得了广泛应用。它既避免了FPGA+高速ADC的复杂性,又突破了传统单片机ADC的精度瓶颈,为开发者提供了一条通往高精度测量的平滑路径。

未来,随着更多国产高精度ADC的崛起(如芯海科技CS1258),这一架构有望进一步降低成本门槛。但从系统设计的角度看,无论换用何种芯片,其背后的核心思想不会改变: 精准源于细节,稳定来自综合考量 。无论是电源完整性、参考电压选择,还是滤波算法与校准机制,每一个环节都值得深思熟虑。而这,也正是嵌入式工程师真正的价值所在。


————————————————
版权声明:本文为CSDN博主「vim8coder」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/vim8coder/article/details/154453210

yzdel7 发表于 2025-11-13 14:41 来自手机 | 显示全部楼层
这篇文章中,里面有个错误,比如在2.5V基准电压的时候,因为ADS1220是24位ADC,在1倍增益时每个LSB可以达到0.149微伏,在128倍增益时,还要除以128才对。

还有,刚看了此ADC的数据手册,此ADC没有提供自校准功能,但通过内部的多路复用器可以实现偏移校准,你可以通过手动实现系统校准以消除系统误差,零点和偏移校准。每次切增益时都需要重新系统校准。
yzdel7 发表于 2025-11-13 14:43 来自手机 | 显示全部楼层
若要达到最佳的采样精度,应该降低到最低采样速率,100sps达不到最佳的采样精度。
zerorobert 发表于 2025-11-14 20:00 | 显示全部楼层
在模拟输入端添加RC滤波器,滤除高频噪声。
wwppd 发表于 2025-11-14 20:56 | 显示全部楼层
将模拟地和数字地通过单点接地或磁珠连接,减少数字噪声对模拟电路的干扰。
claretttt 发表于 2025-11-14 21:17 | 显示全部楼层
系统整体接地良好,模拟地与数字地单点连接,避免地线环路
sdCAD 发表于 2025-11-14 21:57 | 显示全部楼层
必须用开关电源,需在其后级叠加 LDO 二次滤波
uptown 发表于 2025-11-14 22:11 | 显示全部楼层
检查电源去耦、模拟输入滤波、接地是否良好。
averyleigh 发表于 2025-11-15 16:03 | 显示全部楼层
对连续多次采样结果排序后取中值,消除脉冲干扰。
macpherson 发表于 2025-11-15 17:12 | 显示全部楼层
抑制噪声,稳定参考电位              
tabmone 发表于 2025-11-16 21:10 | 显示全部楼层
若使用外部参考电压,需选择低噪声、低温漂的参考源,并在REF引脚附近添加去耦电容。
updownq 发表于 2025-11-17 07:43 | 显示全部楼层
不要直接使用 MCU 的 VREF 或未经稳压的电源作为参考
mollylawrence 发表于 2025-11-17 12:35 | 显示全部楼层
长导线或高阻抗信号源可能导致信号衰减。建议使用屏蔽双绞线传输信号,并在输入端添加RC低通滤波器
mattlincoln 发表于 2025-11-17 14:52 | 显示全部楼层
ADS1220的最大SPI时钟频率为5MHz
youtome 发表于 2025-11-17 15:17 | 显示全部楼层
采用独立模拟电源和数字电源,并通过磁珠单点连接至同一电源入口,避免数字噪声耦合至模拟电路
biechedan 发表于 2025-11-17 16:01 | 显示全部楼层
ADS1220 的硬件设计直接决定采集上限
kkzz 发表于 2025-11-17 22:27 | 显示全部楼层
ADS1220输入阻抗较高              
51xlf 发表于 2025-11-18 19:35 | 显示全部楼层
在ADS1220的VDD与GND之间并联10μF钽电容+0.1μF陶瓷电容,靠近芯片引脚放置以降低电源噪声
kkzz 发表于 2025-11-18 20:00 | 显示全部楼层
传感器线缆和模拟输入线使用屏蔽线,屏蔽层一端接地
wwppd 发表于 2025-11-18 20:32 | 显示全部楼层
ADS1220 的精度很大程度上依赖于 参考电压的稳定性和噪声水平
您需要登录后才可以回帖 登录 | 注册

本版积分规则

110

主题

4411

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部