ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于STM32与24位Σ-Δ ADC的高精度称重系统设计与实现

基于STM32与24位Σ-Δ ADC的高精度称重系统设计与实现 简介本资源是一套基于STM32单片机驱动24位高精度ADC芯片AD7190的称重系统完整开发例程面向嵌入式初学者、电子设计竞赛学生及工业测控项目开发者解决高分辨率重量采集、零点校准、液晶实时显示等核心工程问题。压缩包共667个文件涵盖372个C源文件含AD7190底层驱动、滤波算法、LCD显示逻辑、147个头文件定义寄存器映射与接口函数、71个汇编启动文件及多种IDE工程配置IAR/Keil/STM32CubeIDE包体大小为7.46MB结构清晰支持快速移植与调试。已有1141人学习下载代码包含完整主循环逻辑自动检测AD7190、动态零点校准、双按键交互清零20g砝码标定、6次均值滤波、浮点重量换算及TFT液晶双字号分级显示原始码值克级结果并集成串口调试输出与背光控制可直接烧录运行是理解高精度Σ-Δ ADC应用与人机交互嵌入式系统设计的优质实践参考。1. 项目概述高精度称重系统的核心构建最近在做一个工业现场的小型称重终端核心需求是稳定、精准地读取重量数据并实时显示。客户对精度要求不低常规的16位ADC已经有点捉襟见肘噪声和温漂在长时间运行时会影响读数稳定性。于是我把目光投向了24位高精度Σ-Δ ADCAD7190这颗芯片就成了我的首选。它内置了PGA和缓冲器噪声性能优异特别适合像称重传感器这种输出微小差分信号的应用。主控方面STM32系列单片机是嵌入式开发的老朋友了资源丰富、生态完善驱动个液晶屏、处理一下数据通信都是手到擒来。这个“STM32单片机读写24位ADC-AD7190称重模块带液晶显示例程DEMO源码文件.zip”项目本质上就是一套完整的软硬件参考方案它解决了从模拟信号采集、数字滤波、重量换算到人机交互显示这一整套流程非常适合需要快速搭建高精度测量系统的工程师、学生以及电子爱好者参考。这个项目包的价值在于它提供了一个“开箱即用”的起点。你拿到的不只是几行驱动代码而是一个经过验证的、包含硬件接口设计、底层寄存器配置、数据处理算法和上层应用逻辑的完整工程。无论是想学习高精度ADC的应用还是要为一个真实的称重项目寻找技术方案它都能帮你绕过很多初期的坑直击核心——如何稳定可靠地获取并显示一个高精度的测量值。2. 核心硬件选型与电路设计解析2.1 为什么是AD7190Σ-Δ ADC的优势解析在称重或者任何精密测量场景里ADC的选择是决定系统精度的天花板。常见的SAR型ADC在速度和功耗上有优势但对于慢变化的直流或低频信号Σ-Δ型ADC在分辨率和噪声抑制方面是降维打击。AD7190是一颗典型的低噪声、24位Σ-Δ ADC。它的核心优势有几个第一是极高的有效位数在4.7Hz输出数据率下能提供高达23.5位的无噪声分辨率这意味着它能分辨出极其微小的电压变化对应到重量上可能就是几克甚至更小的变化。第二是内置可编程增益放大器增益从1到128可调这太关键了。称重传感器通常是应变片式电桥满量程输出往往只有几毫伏直接给ADC采样信号太小噪声就会淹没有用信号。PGA能把这个小信号放大到接近ADC的输入量程充分利用ADC的动态范围。第三它集成了完整的模拟前端包括缓冲器和激励电压检测简化了外部电路设计。在电路设计上有几个要点必须注意。模拟电源必须干净通常需要单独的LDO供电并且用磁珠或0欧电阻与数字电源隔离。基准电压源是ADC精度的心脏必须选择低温漂、低噪声的型号比如ADR441B。AD7190的基准输入阻抗很高但为了稳定建议在基准引脚就近放置一个1μF到10μF的钽电容或陶瓷电容并联一个0.1μF的退耦电容。模拟输入部分如果传感器距离较远需要考虑差分走线并在输入端加入RC低通滤波以抑制高频干扰。2.2 STM32主控与液晶显示接口设计主控我选择了STM32F103C8T6也就是常说的“蓝莓派”最小系统板核心型号。它资源足够有多个SPI接口用于驱动AD7190足够的GPIO驱动液晶屏定时器用于产生精确延时或触发采样UART用于调试和上传数据。更重要的是它的生态极其成熟HAL库和标准库资料丰富降低了开发门槛。与AD7190的通信采用SPI接口。这里要注意电平匹配AD7190是5V或3.3V兼容的但为了降低噪声整个系统建议统一用3.3V供电。如果STM32是3.3V而ADC模块是5V供电则需要电平转换或者直接选择支持3.3V供电的ADC模块。SPI的时钟速率不宜太高AD7190的SPI时钟最高可以到5MHz但在长线传输或干扰环境我通常会保守一点初始设置在1MHz以下稳定后再尝试提高。液晶显示部分根据项目名推测很可能使用的是常见的字符型LCD1602或点阵型LCD12864它们通常并行接口或I2C接口。为了节省IO口我强烈推荐使用带I2C转接板的液晶模块只需要两根线SCL SDA就能驱动大大简化了布线。在代码中需要实现对应的液晶驱动函数用于显示实时重量、单位、状态信息等。如果显示内容复杂比如要显示曲线、汉字那么选择一款SPI接口的OLED屏会是更好的选择它刷新快、对比度高但驱动代码稍复杂。3. 软件架构与驱动层实现详解3.1 AD7190的寄存器配置与初始化流程AD7190的功能都是通过读写一系列寄存器来配置的。上电后的初始化流程必须严谨这是稳定工作的基础。首先是通过SPI读取器件ID寄存器确认通信正常。然后进行复位操作可以通过SPI发送连续40个以上的1来实现软件复位或者拉低RESET引脚。复位后所有寄存器恢复默认值。接下来是核心配置主要涉及几个寄存器配置寄存器这是重中之重。你需要设置通道选择选择连接传感器的差分输入对AIN1 AIN2。增益设置根据传感器输出范围和参考电压计算。例如传感器满量程输出±2mV参考电压2.5V为了充分利用ADC量程增益可以设为128。计算(2.5V / 128) / 2 ≈ 9.8μV/LSB这样±2mV的信号大约对应±200个码值处在量程中部留有余量。缓冲器使能对于高阻抗源如电桥必须使能缓冲器以提供高输入阻抗但会引入少量噪声。如果信号源阻抗很低可以禁用缓冲器以获得更好的噪声性能。斩波使能必须开启。斩波技术能极大抵消ADC本身的偏移和1/f噪声对于直流测量是必选项。基准电压选择选择内部还是外部基准我们通常用外部高精度基准。模式寄存器设置工作模式。单次转换模式功耗低但需要手动触发连续转换模式数据源源不断。对于称重我更喜欢用连续转换模式然后由STM32定时读取数据。这里还要设置数据输出率输出率越低噪声越小但响应速度也慢。称重不需要快通常设为4.7Hz或更低。IO寄存器如果需要用AD7190内部的激励电压给传感器电桥供电可以在这里配置IO口输出。初始化完成后需要执行一次内部零电平校准和满量程校准。校准命令通过模式寄存器触发。校准时需要将输入端短路对零和接入一个精确的参考电压对满量程。对于称重系统我们更常用系统校准即用已知重量的砝码进行标定。注意配置寄存器的写入顺序有时有讲究特别是更改通道或增益后AD7190需要一段时间建立。安全的做法是每次重要配置更改后等待几个转换周期再读取数据或者检查状态寄存器的RDY位。3.2 SPI通信驱动与数据读取策略STM32的SPI驱动使用HAL库很方便但要注意配置。模式选择CPOL1 CPHA1即SPI Mode 3这是AD7190的数据手册要求的。数据大小设为8位。读取AD7190数据是一个固定的操作序列首先读取状态寄存器检查数据就绪位RDY。如果RDY为0表示新转换数据可用。然后连续读取3个字节的数据寄存器24位数据。这里有个细节AD7190的数据是24位补码格式。读取时是MSB先行。我通常封装一个函数AD7190_ReadData()其内部逻辑如下int32_t AD7190_ReadData(void) { uint8_t rxBuf[3] {0}; int32_t rawData 0; // 1. 检查RDY位可通过读状态寄存器或查询专用的DRDY引脚 while(AD7190_DataReady() ! 0); // 等待数据就绪 // 2. 发起读取数据寄存器的SPI传输 HAL_SPI_TransmitReceive(hspi1, (uint8_t*)CMD_READ_DATA, rxBuf, 3, HAL_MAX_DELAY); // 3. 组合24位数据 rawData (rxBuf[0] 16) | (rxBuf[1] 8) | rxBuf[2]; // 4. 将24位补码扩展为32位有符号整数 if (rawData 0x00800000) { // 检查第23位符号位 rawData | 0xFF000000; // 如果为负高8位补1 } else { rawData 0x00FFFFFF; // 如果为正高8位补0 } return rawData; }数据读取策略上不建议在中断里进行复杂的SPI读取和数据处理容易导致堆栈溢出或影响其他任务。更稳健的做法是将DRDY引脚连接到STM32的外部中断引脚设置为下降沿触发。在中断服务函数中仅仅设置一个标志位data_ready_flag。主循环中查询这个标志位一旦置位则执行上述AD7190_ReadData()函数读取数据并进行后续滤波、换算处理。这种“中断触发主循环处理”的方式既保证了实时性又避免了在中断中处理耗时操作的风险。4. 数据处理算法与重量换算实战4.1 数字滤波从原始码值到稳定读数直接从ADC读出来的原始数据是跳动的包含了高频噪声。虽然AD7190内部有Sinc滤波器但输出数据仍然可能存在工频干扰或随机噪声。因此在单片机侧进行软件滤波是必不可少的。对于称重这种慢变信号均值滤波和中值滤波是简单有效的选择。但更推荐的是一阶滞后滤波低通滤波它计算量小效果平滑。公式如下Filtered_Value (1 - α) * Filtered_Value α * Raw_Value其中α是滤波系数0α1α越小滤波越强响应越慢α越大滤波越弱响应越快。需要根据实际抖动情况和响应要求调整。在实际项目中我常用一个移动平均滤波结合限幅滤波的组合拳。首先创建一个数组缓存最近N次采样值比如N10。每次得到新数据先进行限幅判断如果新数据与当前平均值之差超过某个阈值比如满量程的1%则认为是干扰脉冲将其丢弃或用上次值代替。通过限幅的数据才加入移动平均数组并计算新的平均值。这种方法能有效抑制偶然的尖峰干扰。#define FILTER_LEN 10 static int32_t rawDataBuffer[FILTER_LEN] {0}; static uint8_t dataIndex 0; int32_t AdvancedFilter(int32_t newRawData) { static int32_t runningAvg 0; int32_t sum 0; uint8_t i; // 限幅滤波 if (abs(newRawData - runningAvg) LIMIT_THRESHOLD) { newRawData runningAvg; // 或用 buffer[dataIndex] 保持原值 } // 更新缓冲区 rawDataBuffer[dataIndex] newRawData; dataIndex (dataIndex 1) % FILTER_LEN; // 计算移动平均 for(i 0; i FILTER_LEN; i) { sum rawDataBuffer[i]; } runningAvg sum / FILTER_LEN; return runningAvg; }4.2 标定与换算将ADC码值转换为重量值这是将物理量电压转换为工程值重量的关键一步。我们需要建立一个线性模型Weight Scale * ADC_Code Offset。标定过程两点标定法零点标定在传感器空载秤台上无任何物品时读取稳定的滤波后ADC码值记为Code_Zero。此时对应的重量Weight_Zero 0。满量程标定在传感器上放置一个已知精确重量的标准砝码例如Weight_Cal 500.0g。待读数稳定后记录此时的ADC码值记为Code_Cal。计算标定参数刻度因子Scale Weight_Cal / (Code_Cal - Code_Zero)偏移量Offset -Scale * Code_Zero实际上在换算时用(Code - Code_Zero) * Scale更直观在代码中可以这样实现float CalibratedWeight(int32_t filteredCode) { // 这些参数通过标定得出并存储在EEPROM或Flash中 static float scaleFactor 0.00123f; // 示例值单位 g/LSB static int32_t codeZero -123456; // 零点码值 float weight; weight (filteredCode - codeZero) * scaleFactor; return weight; }实操心得标定是精度保证的生命线。标定时要确保传感器和秤台处于正常工作温度和环境。砝码的重量最好接近你常用量程的2/3处这样在整个量程内线性度最好。标定参数一定要存储在非易失性存储器中如STM32内部的Flash或外置EEPROM否则每次上电都需要重新标定。此外可以考虑多点标定如零点和两个不同重量的点并进行线性拟合以修正传感器微小的非线性误差。5. 人机交互与系统集成5.1 液晶显示驱动与界面布局驱动I2C液晶以LCD1602为例相对简单。首先初始化I2C外设然后按照液晶数据手册的时序通过I2C发送命令和数据。市面上常见的PCF8574T转接板其I2C地址通常是0x27或0x3F。显示界面设计要简洁明了。对于称重应用通常分为几个区域主显示区大字体显示当前重量如“** 500.23 g**”。这是视觉焦点。单位区显示当前重量单位g kg oz等。状态指示区用小图标或字符显示系统状态如稳定标志“STAB” 超载警告“OL” 零点标志“ZERO”等。辅助信息区可以显示电池电量、通讯状态等。刷新策略上重量值不需要以最高数据率刷新那样会导致屏幕闪烁。可以设置一个显示刷新定时器比如每200ms更新一次显示。只有重量变化超过一个最小显示分度值例如0.01g时才实际更新屏幕上的数字这样可以避免数字末尾无意义的跳动。5.2 按键功能设计与去皮、清零逻辑除了显示通常还需要几个按键进行交互比如“去皮/置零”、“单位切换”、“校准模式进入”等。按键检测使用扫描方式即可注意消抖。按键逻辑的核心是“去皮”功能。去皮操作的本质是在当前瞬间将此刻的ADC码值作为新的“软件零点”存储起来。此后显示的重量 (当前码值 - 新的零点码值) * 刻度因子。实现时需要两个零点变量hardwareZero硬件零点即空载标定值和tareZero去皮零点。上电时tareZero hardwareZero。置零当重量绝对值小于一个阈值如0.5%FS时按下置零键执行tareZero currentCode。这用于消除空载时的微小漂移。去皮在任何重量下按下去皮键执行tareZero currentCode。此时显示归零但hardwareZero不变。清除去皮通常再次按去皮键或者在去皮状态下重量小于阈值并按下置零键则恢复tareZero hardwareZero。去皮值也需要存入非易失性存储器否则断电后丢失。但要注意去皮是一种临时操作通常不需要像标定参数那样永久保存可以保存在具有备份电源的SRAM中如果STM32有VBAT引脚或者每次上电默认清除。6. 系统调试与常见问题排查实录6.1 上电无读数或数据异常问题排查这是调试阶段最常见的问题。可以按照以下流程逐步排查电源与基准检查首先用万用表测量AD7190的模拟电源AVDD和数字电源DVDD是否稳定在3.3V。然后测量基准电压REFIN引脚是否为预期的精确值如2.5V。这是所有工作的基础。SPI通信验证这是重点。先尝试读取AD7190的ID寄存器地址0x01。如果读不到正确的IDAD7190是0x0X说明通信链路有问题。检查接线SCK MOSI MISO CS四根线是否接反、虚焊。检查电平如果ADC模块是5V供电STM32是3.3VMISO信号从ADC到MCU需要电平转换或者确认ADC的IO口是否兼容3.3V输入。检查SPI配置模式必须是Mode 3CPOL1 CPHA1。时钟极性相位错误是导致通信失败的常见原因。降低时钟速度先将SPI波特率降到最低如100kHz排除因布线不良导致的高速信号完整性问题。ADC配置与状态检查如果通信正常但读数全为0或固定值检查配置寄存器是否写入成功。可以回读配置寄存器确认。同时检查状态寄存器的RDY位或DRDY引脚是否正常变化如果一直为高可能是转换未启动或模式设置错误。模拟输入检查给ADC的输入引脚施加一个已知的直流电压比如用分压电阻从基准电压分得看读数是否随电压线性变化。注意输入电压必须在(Vref / Gain)的范围内。6.2 读数不稳定、跳动大的优化措施即使能读到数据但数值跳动大精度达不到预期可以从以下几个方面优化电源噪声这是首要怀疑对象。在AVDD和AGND之间尽可能靠近芯片引脚并联一个10μF的钽电容和一个0.1μF的陶瓷电容。模拟地和数字地单点连接。基准噪声基准电压的噪声会直接叠加到测量结果上。确保基准芯片的负载电容足够且走线远离数字信号线。传感器激励如果使用AD7190内部的激励电压输出给电桥供电要确保该电压稳定。或者使用一个更精密的外部基准源来为电桥供电并将此电压同时作为ADC的基准这种“比率式”测量方法可以抵消激励电压波动带来的影响。滤波参数调整降低输出数据率在模式寄存器中选择更低的输出数据率如4.7Hz 9.8Hz。数据率越低内部数字滤波器的陷波效果越好噪声越低。优化软件滤波调整移动平均的窗口大小或一阶滤波的α系数。增加窗口大小或减小α滤波效果强但响应变慢。需要根据实际应用在稳定性和响应速度间权衡。环境干扰工频干扰50/60Hz是常见问题。Σ-Δ ADC的Sinc滤波器在特定数据率下对工频及其谐波有抑制。可以尝试将输出数据率设置为工频周期的整数倍例如50Hz的工频设置数据率为10Hz 5Hz等利用其陷波特性。代码层面的优化确保在读取ADC数据时关闭其他可能产生噪声的外设如PWM 高速时钟输出的GPIO等。如果使用DMA传输SPI数据要确保DMA缓冲区对齐避免访问冲突。6.3 标定后精度仍不达标的深度分析如果标定过程正确但测量误差仍然超过预期需要从系统层面分析传感器非线性与蠕变应变片传感器本身存在非线性尤其是在满量程两端。此外加载后读数会随时间缓慢变化蠕变。对于高精度要求需要进行多点标定和线性补偿。蠕变则需要软件算法进行补偿或者在读数稳定后再取值。温漂影响ADC的增益和偏移、基准电压、传感器灵敏度都会随温度变化。如果工作环境温度变化大需要考虑温度补偿。可以在系统中加入温度传感器如DS18B20建立温度与零点/增益漂移的补偿曲线。机械安装与受力称重传感器的安装必须规范确保力垂直、无侧向力。秤台的水平、刚度都会影响结果。这不是电路或代码能解决的却是影响精度的关键物理因素。代码计算溢出与精度检查标定参数scaleFactor的数据类型。如果使用整型计算在乘以一个很小的浮点数时可能导致精度丢失。全程使用float或double进行浮点运算。STM32F103有硬件FPU但需要编译器开启支持。如果没有FPU浮点运算由软件模拟速度慢但精度足够。调试是一个系统工程从电源、基准、信号链、PCB布局、到软件算法、机械结构任何一个环节的疏忽都可能导致最终性能下降。这个DEMO源码提供了一个正确的框架和流程但要将它变成一个真正稳定可靠的产品还需要开发者根据具体的硬件和环境进行细致的调试和优化。我的经验是耐心地逐项排查用示波器观察电源和信号用逻辑分析仪抓取SPI时序用串口打印内部中间变量大部分问题都能定位和解决。本文还有配套的精品资源点击获取
返回列表