ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

STM32F103+AD7192高精度电子秤:从Sigma-Delta采样到标定实战

STM32F103+AD7192高精度电子秤:从Sigma-Delta采样到标定实战 简介面向STM32F103单片机学习者和电子秤方向开发者这份实验例程完整实现了基于AD7192高精度ADC芯片的电子秤方案采用标准库编写通过SPI接口连接传感器模拟前端并将称重结果经USART发送至串口调试助手显示。资源共80个文件以C源码和头文件为主35个.h、33个.c另含启动文件、Keil工程文件与链接脚本可直接打开编译烧录代码按ADC驱动、按键、SysTick、USART等模块划分便于理解高精度采样、数据滤波和串口交互的完整流程。包体仅293KB轻量易携带。目前已有315人学习下载。配套readme说明文档可帮助快速上手适合入门AD7192配置、电子秤标定与误差补偿的读者也可作为课程设计或毕业设计的基础工程在其上扩展液晶显示、蓝牙上传等功能。1. 电子秤精度瓶颈24 位 Sigma-Delta 才是关键把 STM32F103 的 12 位 ADC 直接接称重传感器分辨率远远不够。按 3.3V / 4096 计算LSB 约为 0.8mV而常见桥式称重传感器满量程输出只有 10mV 上下以 2mV/V、5V 激励计算12 位 ADC 的有效位数根本不足以分辨 0.1g 量级的重量变化。AD7192 走的是另一条路24 位 Sigma-Delta 架构内置可编程增益放大器PGA1~128 倍和数字滤波器把量化噪声整形到高频后由滤波器切掉再用 SPI 把结果送进 STM32F103。本实验例程的主题就是用标准外设库在 STM32F103 上驱动 AD7192完成称重采样、滤波、标定和串口显示。整个过程拆成硬件接线、SPI 寄存器配置、数据读取与标定、串口输出、精度调试五步每一段都有能直接抄进工程里的代码。2. AD7192 称重电路原理与 STM32F103 引脚分配2.1 桥式传感器输出特性与 AD7192 的 PGA电子秤最常用的传感器是电阻应变片组成的惠斯通电桥。电桥有 4 根线的E、E-、S、S-和 6 根线的多了两根反馈线原理都一样加载后桥臂电阻失衡S / S- 之间产生差模电压。这个电压的幅度和激励电压成正比典型规格是 2mV/V也就是如果激励电压是 5V满量程差模输出只有 10mV。要把 3000g 量程的分辨率做到 0.1gADC 需要分辨到 0.33uV这对逐次逼近型 ADC 来说非常吃力但 24 位 sigma-delta 芯片就容易得多。AD7192 内部带着一个增益可调的模拟前端增益范围 1、8、16、32、64、128。对 2mV/V 的传感器例程里直接设到 128 倍增益把 10mV 放大到 1.28V接近 2.5V 基准电压的一半有效位数利用最充分如果换成灵敏度更高的传感器比如 3mV/V就把 PGA 降到 64。要注意的是增益越大输入等效噪声越明显后面要配合 10SPS 左右的低输出速率来压噪声这也是电子秤程序里最常见的参数组合方式。2.2 最小系统的引脚规划SPI、PDWN、SYNC网上搜 STM32F103 最小系统的引脚分配最常见的是把 AD7192 接到 SPI1PA5 做 SCLKPA6 做 MISOPA7 做 MOSIPA4 做片选 CS。如果 PA4 被别的外设占了也可以换成 PA15 或 PB12只要把 GPIO 初始化改掉即可。除了四根 SPI 线还有两根控制线PDWN掉电/复位低电平有效和 SYNC滤波同步控制一般悬空或接高电平。PDWN 引脚在做硬件复位时要用软件初始化时也可以靠 SPI 连续写 0xFF 来完成串口接口复位这个后面再讲。一个 STM32F103 引脚规划的常见坑是PA11 / PA12 默认复用为 USB如果板子同时接了 USB 座和 SPI2 的 MISO/MOSI初始化顺序不对可能互相干扰排查时先看 GPIO 配置里是否把 PA11/PA12 点成了外设复用。以下接线表按最小系统最常用的配置列出来直接照连即可。信号STM32F103 引脚说明SPI1_SCKPA5SPI 时钟建议空载上拉到 VCCSPI1_MISOPA6AD7192 DOUT数据输出SPI1_MOSIPA7AD7192 DIN数据输入SPI1_CSPA4AD7192 CS软件手动控制AD7192_PDWNPB0上电后拉高复位时拉低 10usAD7192_SYNCPB1滤波同步悬空或接高电平VREF外部 2.5V 基准不用 MCU 的 3.3V 直接供电2.3 基准电压与激励电源的选择AD7192 的测量精度直接取决于基准电压的稳定性例程的做法是在 VREF 引脚接一个 2.5V 高精度基准芯片而不是直接把 STM32F103 的 3.3V 拿过来当 VREF。原因很简单3.3V 电源上有数字开关噪声而且随着负载变化会有毫伏级的波动折算到 24 位分辨率里就是几十个 LSB 的闪烁。激励电压 E 则根据传感器规格选择多数 3kg 传感器用 5V 激励可以用一个 LDO 单独供电避免和 MCU 电源共用后相互串扰。AD7192 还有一对输入缓冲选项。开启缓冲后输入阻抗大幅提高可以直接接高阻抗传感器输出不必担心影响电桥平衡但缓冲开启后输入信号范围会比电源轨略小。对于称重应用开启输入缓冲是默认选择用 5V 激励时 S / S- 的共模大约 2.5VAVDD 用 5V 供电余量完全够用。供电部分注意 AVDD 和 DVDD 要分别用磁珠或小电阻隔开数字地和模拟地在 PCB 上单点汇合这个细节对 AD7192 的噪声影响比很多参数调整都明显。3. 标准库下 SPI 通信与 AD7192 寄存器配置3.1 新建标准库工程时的 SPI 初始化要点用标准外设库新建工程时SPI 初始化要保证三件事RCC 时钟开启、GPIO 模式设为复用推挽或浮空输入、SPI 分频算准。AD7192 最高 SPI 时钟可以到几 MHz但为了布线和电源噪声的容错例程用 APB2 72MHz 除以 64得到约 1.125MHz这个速度对 10SPS 的称重采样完全够用。标准库的 SPI 初始化结构体写法如下SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_SPI1, ENABLE); // PA5 SCK, PA7 MOSI配置为复用推挽输出 GPIO_InitStructure.GPIO_Pin GPIO_Pin_5 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); // PA6 MISO配置为浮空输入方向由 AD7192 驱动 GPIO_InitStructure.GPIO_Pin GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, GPIO_InitStructure); // PA4 CS推挽输出手动控制片选 GPIO_InitStructure.GPIO_Pin GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_4); // CS 默认拉高 SPI_InitStructure.SPI_Direction SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode SPI_Mode_Master; SPI_InitStructure.SPI_DataSize SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL SPI_CPOL_High; // 空闲时钟为高 SPI_InitStructure.SPI_CPHA SPI_CPHA_2Edge; // 第二个边沿采样 SPI_InitStructure.SPI_NSS SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler SPI_BaudRatePrescaler_64; SPI_InitStructure.SPI_FirstBit SPI_FirstBit_MSB; SPI_Init(SPI1, SPI_InitStructure); SPI_Cmd(SPI1, ENABLE);这段代码的逻辑是先把 SCK 和 MOSI 配成复用推挽让 SPI 外设控制这两个引脚MISO 是 AD7192 的输出引脚STM32 侧应配成浮空输入CS 用普通 GPIO 手动控制方便在每次通信前拉低、结束后拉高。CPOLHigh 和 CPHA2Edge 是 AD7192 数据手册要求的 SPI 模式第一次调不通时优先检查这里很多例程用的是 STM32 默认的低电平空闲模式会导致 AD7192 完全无响应。标准库下 NSS 配置成软件模式后硬件 NSS 引脚不再参与控制片选逻辑交给 PA4 的手动拉高拉低。提示PA4 的 GPIO 初始化放在 SPI_Cmd 使能之前否则先开外设再拉低片选可能出现一帧多余的时钟脉冲。3.2 通信寄存器结构与底层读写函数AD7192 的所有操作都通过通信寄存器发起这是一个 8 位寄存器。写入通信寄存器时最高位位 7表示下一次操作方向1 表示读0 表示写位 5 到位 3 选择目标寄存器位 2 表示是否为连续写模式低两位保留。向配置寄存器写入数据时指令字节是 0x10要从数据寄存器读取 24 位数据指令字节是 0x40读 DATA 寄存器加最高位。这个分层设计让 8 位 SPI 总线可以访问多个 24 位寄存器。底层读写函数可以封装成下面这样后面的初始化、采样和校准都只用这两个函数static void AD7192_Write(uint8_t reg, const uint8_t *pData, uint8_t len) { CS_LOW(); SPI_SendByte(reg); // 写通信寄存器选目标寄存器 while (len--) { SPI_SendByte(*pData); } CS_HIGH(); } static void AD7192_Read(uint8_t reg, uint8_t *pData, uint8_t len) { CS_LOW(); SPI_SendByte(reg | 0x40); // 最高位置 1表示读操作 while (len--) { *pData SPI_ReadByte(); } CS_HIGH(); }这里的 SPI_SendByte 和 SPI_ReadByte 是标准库 SPI_I2S_SendData / SPI_I2S_ReceiveData 加等待标志位的封装。读操作时寄存器地址必须或上 0x40否则 AD7192 会把后续数据当成写操作接收。CS 的低电平必须覆盖整个读或写过程不能在两个字节之间拉高 CS否则通信中断寄存器指针会回到通信寄存器下次操作必须重新发送读/写指令。标准库例程里常犯的一个错误是每次发送完一字节就判断一次 SPI_I2S_GetFlagStatus导致 CS 超过 10us 拉高但数据传输还没完成调试现象就是读出来全是 0xFF 或 0x00。3.3 模式寄存器与配置寄存器的参数设计模式寄存器写入口 0x10和配置寄存器写入口 0x20是 AD7192 上电初始化时最先要写的地方。模式寄存器控制转换模式、时钟源和输出速率配置寄存器控制输入通道、PGA 增益、输入缓冲和双极性/单极性模式。电子秤例程的标准做法是连续转换模式时钟用内部 4.92MHz这样不需要额外接晶振。输出速率由滤波器字 FS 决定FS 越大输出速率越低噪声越低。void AD7192_Init(void) { uint8_t mode[3], conf[3]; uint32_t mode_reg, conf_reg; // 先做一次串行接口复位连续写入 6 个 0xFF CS_LOW(); for (uint8_t i 0; i 6; i) SPI_SendByte(0xFF); CS_HIGH(); // 模式寄存器连续转换模式10SPS 左右 // 位 23-21 MD000位 19-18 CLK10内部时钟 // 位 10-0 FS 240配合内部 4.92MHz 得到接近 10SPS mode_reg (0 21) | (2 18) | 240; // 配置寄存器AIN1-AIN2 差分PGA128开启输入缓冲双极性 // 增益编码 101 对应 32 倍111 对应 128 倍 conf_reg (1 19) | (7 1) | (0 0); mode[0] (mode_reg 16) 0xFF; mode[1] (mode_reg 8) 0xFF; mode[2] mode_reg 0xFF; AD7192_Write(0x10, mode, 3); conf[0] (conf_reg 16) 0xFF; conf[1] (conf_reg 8) 0xFF; conf[2] conf_reg 0xFF; AD7192_Write(0x20, conf, 3); }模式寄存器里 FS240 这个值按内部 4.92MHz 主频计算输出速率约 10SPS正好落在 50Hz 工频干扰衰减比较好的区间。如果你的环境是 60Hz 供电把 FS 调小到 200 左右。配置寄存器里 PGA 增益编码要查对应对照不同批次的 AD7192 对增益位定义一致但很多例程直接把整个配置字写成十六进制类似 0x1B08移植时只看注释不看公式结果换了传感器量程不知道怎么改。建议把所有配置分解成移位表达式这样每个位的作用一目了然换传感器时只改增益和通道两个字段即可。4. 数据读取、滤波与称重标定4.1 连续转换模式下读取 24 位数据配置完成后AD7192 会自动开始连续转换。每次转换完成后DOUT 引脚会拉低MCU 可以通过查询 DOUT 电平判断数据是否就绪。拉低 CS、发送 0x40 读取数据寄存器连续读 3 个字节得到一个 24 位补码值这就是当前采样点的原始码值。电子秤例程里不需要中断主循环轮询 DOUT 即可10SPS 的速率下 CPU 占用可以忽略。如果开启了 DAT_STA 位读到的 4 个字节里最后一个字节是状态寄存器里面有通道号、超范围标志和数据就绪标志调试时非常有用。uint32_t AD7192_ReadData(void) { uint8_t buf[3]; uint32_t raw; // 等待 DOUT 拉低表示数据已就绪 while (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_10) ! 0); AD7192_Read(0x00, buf, 3); // 0x00 对应数据寄存器 raw ((uint32_t)buf[0] 16) | ((uint32_t)buf[1] 8) | buf[2]; // 24 位补码转有符号数 if (raw 0x800000) { raw | 0xFF000000; } return (int32_t)raw; }这里参考接线里把 AD7192 的 DOUT 接到了 PC10用查询方式判断数据就绪。24 位补码转有符号数的逻辑是最高位为 1 表示负数扩展到 32 位后再转成 int32_t 才有正确的负数含义。电子秤正常情况下加到传感器上的力是压力原始码总是正值但空载时因失调电压可能是负值所以必须正确处理负数的扩展否则去皮后重量会出现跳变。4.2 滑动平均滤波与中位值滤波的组合AD7192 的数字滤波器本身已经做了 Sinc 低通但在 10SPS 下仍然能看到 1~2 个 LSB 的随机抖动。振动环境下这几个 LSB 折算到重量可能就有 0.2g~0.5g所以例程在软件里加一级滑动平均。滑动平均对周期性振动抑制效果好但对脉冲干扰比如短暂触碰秤体响应迟钝所以更好的做法是“中位值 滑动平均”两级滤波先取最近 5 次采样排中值再对中值序列做 10 点滑动平均。这段代码很直白但参数选择有讲究。#define FILTER_QUEUE_SIZE 10 static int32_t filter_queue[FILTER_QUEUE_SIZE]; static uint8_t filter_index 0; static int32_t Median5(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e) { int32_t t; // 简单插入排序数据量小没必要上快排 int32_t arr[5] {a, b, c, d, e}; for (int i 1; i 5; i) { for (int j i; j 0 arr[j] arr[j-1]; j--) { t arr[j]; arr[j] arr[j-1]; arr[j-1] t; } } return arr[2]; } int32_t AD7192_GetFilteredValue(void) { int32_t raw[5], median, sum 0; for (int i 0; i 5; i) { raw[i] AD7192_ReadData(); HAL_Delay(2); } median Median5(raw[0], raw[1], raw[2], raw[3], raw[4]); filter_queue[filter_index] median; filter_index (filter_index 1) % FILTER_QUEUE_SIZE; for (int i 0; i FILTER_QUEUE_SIZE; i) { sum filter_queue[i]; } return sum / FILTER_QUEUE_SIZE; }注意这段代码写成了标准库风格但用了一个比较少见的设计每个滤波周期内取 5 次原始采样做中位值再把中位值放入 10 点滑动队列。这样等效采样率其实被拉低了实际最终输出大概每 100ms 更新一次对应上一个 10SPS 配置是合理的。如果希望响应更快把 Median5 的循环次数改成 3滑动平均窗口改成 4更新速率可以翻倍但噪声会略增。这个参数组合要在“稳定显示”和“快速响应”之间做取舍电子秤一般以稳定优先。4.3 标定的两个环节去皮与增益系数电子秤标定分成两个环节空载时记录零点偏移加载已知砝码时计算增益系数。零点偏移会因为温度漂移和机械形变缓慢变化所以例程提供一个按键触发的去皮功能。增益系数的计算方法是先读空载滤波值作为 zero_code再放上标准砝码读 load_code用两者差值除以砝码重量得到每克的码值也就是 scale_factor。之后任意时刻的重量等于当前码值减去 zero_code再除以 scale_factor。typedef struct { int32_t zero_code; // 空载零点码值 float scale_factor; // 码值/克 float weight_gram; // 计算结果 } Scale_Handle; void Scale_Tare(Scale_Handle *h) { h-zero_code AD7192_GetFilteredValue(); // 空载采样 } void Scale_Calibrate(Scale_Handle *h, float known_weight_gram) { int32_t load_code AD7192_GetFilteredValue(); float delta (float)(load_code - h-zero_code); h-scale_factor delta / known_weight_gram; // 单位码值每克 } void Scale_Update(Scale_Handle *h) { int32_t cur AD7192_GetFilteredValue(); h-weight_gram (float)(cur - h-zero_code) / h-scale_factor; }这套定义里 scale_factor 的符号隐含了方向压力增加时码值增大所以是正值。如果传感器接反加载后码值变小计算出来的重量为负数这时只需交换 S 和 S- 两根线。这里没有引入任何浮点以外的重量换算电子秤分辨率 0.1g 时直接用 float 足够误差远小于传感器本身的非线性。要注意的是 Calibrate 函数里的 known_weight_gram 必须用标定砝码的实际重量不要用显示值回代否则会累积误差。4.4 量程保护与超限判断当负载超过传感器量程时AD7192 的输出码值会接近满幅值并可能翻转。数据手册里有一个超范围状态位开启 DAT_STA 模式后可以从状态寄存器读取。例程的做法比较简单把滤波后的码值和上次保存的满量程码值比较如果码值超过满量程对应值的 105%就认为超载显示区输出提示并停止重量更新。这个判断放在 Scale_Update 里做避免超载时显示一个错误的满量程数值。5. 串口输出与串口调试5.1 标准库下 USART1 初始化与 printf 重定向串口显示的两种常见做法是直接调 sprintf 生成字符串后循环发送或者用 fputc 重定向 printf 只维护一个库函数的指针。电子秤例程里用第二种因为格式化输出频繁printf 重定向后代码可读性好很多。USART1 在 PA9TX和 PA10RX初始化时注意使能 AFIO 时钟否则引脚复用不生效。以下初始化代码取 115200 波特率、8 位数据、1 位停止位、无校验这是串口调试助手的默认配置之一。void USART1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_9; // TX GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin GPIO_Pin_10; // RX GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, GPIO_InitStructure); USART_InitStructure.USART_BaudRate 115200; USART_InitStructure.USART_WordLength USART_WordLength_8b; USART_InitStructure.USART_StopBits USART_StopBits_1; USART_InitStructure.USART_Parity USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode USART_Mode_RX | USART_Mode_TX; USART_Init(USART1, USART_InitStructure); USART_Cmd(USART1, ENABLE); } int fputc(int ch, FILE *f) { while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) RESET); USART_SendData(USART1, (uint8_t)ch); return ch; }fputc 的重定向逻辑是每个字符发送前等待发送数据寄存器为空。115200 波特率下串一个字符约 87us一秒输出 10 次重量、每次 20 字节左右整个 printf 处理占用 CPU 的时间很短不会干扰 10SPS 的 AD7192 采样。如果调试时发现 printf 没有输出先在 while(1) 循环里每隔一段延时发送固定字符排除波特率问题后再检查 fputc 有没有正确链接到库的底层。5.2 串口 1 和串口 3 的使用差异例程默认用串口 1因为 PA9/PA10 是最常见的 TTL 引脚USB 转 TTL 模块和串口调试助手默认接这对引脚。但项目中有时需要把两个串口都打开串口 1 用来看调试日志串口 3 接上位机或者蓝牙模块。串口 3 在 PB10TX和 PB11RX初始化时时钟使能的是 RCC_APB1Periph_USART3注意这是 APB1 总线而不是 APB2。APB2 时钟是 72MHzAPB1 时钟默认是 36MHz如果用一个通用的 UART 初始化函数却不区分总线时钟波特率会翻倍出现乱码。STM32F103 标准库下串口 1 和串口 3 的差异主要体现在时钟源、中断通道号和重映射三个方面串口TX/RX 默认引脚挂载总线中断通道重映射说明USART1PA9 / PA10APB2USART1_IRQn可映射到 PB6/PB7USART2PA2 / PA3APB1USART2_IRQn可映射到 PD5/PD6USART3PB10 / PB11APB1USART3_IRQn可映射到 PC10/PC11 或 PD8/PD9串口 1 和串口 3 的 BaudRate 计算都用到总线时钟标准库里 USART_Init 会根据 RCC 配置自动取值但如果你手动改过 RCC_PCLK1Config必须确保初始化顺序是时钟配置在先、串口初始化在后。另一个容易踩的坑是串口 3 如果重映射到了 PC10/PC11恰好和前面 AD7192 的 DOUT 查询引脚冲突这时候只能另选 GPIO 来读取 DOUT或改用串口 1。5.3 串口调试助手与数据帧设计电子秤例程输出建议按固定帧格式发送方便上位机解析也方便串口调试助手直接按文本显示void Scale_Report(Scale_Handle *h) { char buffer[48]; // 例程输出WEIGHT,123.4,g sprintf(buffer, WEIGHT,%.1f,g\r\n, h-weight_gram); printf(%s, buffer); }如果只显示重量数值用printf(%.1f\r\n, h-weight_gram);即可。串口调试助手里要注意两项设置波特率和“发送新行”勾选。很多调试失败不是程序问题而是串口调试助手里的 DTR/RTS 默认电平把 STM32F103 复位了打开串口一瞬间芯片连续重启上位机看到的是一直重复的启动日志。CH340 这类 USB 转串口驱动在 Windows 下还有缓存缓冲如果数据量大要关闭“缓存”选项或改用 TTL 电平直接连接。6. 提高称重精度与常见故障排查6.1 使能 CHOP 斩波来抑制失调漂移AD7192 支持斩波稳定模式CHOP 置 1该模式下器件会周期性地交换输入把运放的失调和低频漂移调制到高频后再滤除。电子秤这种低速高精度应用CHOP 开启后零点漂移改善明显代价是最高的输出速率会降低但 10SPS 档位下几乎不受影响。例程里在配置寄存器中把 CHOP 位置 1 即可。如果输出速率被要求提升到 100SPS 以上CHOP 效果会减弱此时应回到关闭斩波的模式并依赖外部校准来消除失调。验证斩波是否生效的方法是上电后连续记录 30 秒空载码值统计最大最小值之差。未开斩波时如果差值为 15 个 LSB开后应该能压到 5~8 个 LSB。如果不能明显降低检查传感器供电是否稳定以及 S / S- 的屏蔽层是否单端接地。6.2 三类常见问题AD7192 无响应、重量跳变、串口乱码AD7192 无响应优先检查 SPI 模式。上电后从状态寄存器读回设备 ID0x00 读入口是 0x40ID 寄存器地址是 0x03读到 0xE 或 0x3 说明通信正常。如果读回全是 0xFF说明 DOUT 一直被拉高这时把 SCLK 空闲电平改为高、数据在第二个边沿采样再试。如果读回全是 0x00检查 MISO 引脚是否被配置成推挽输出标准库下浮空输入才是正确方向。重量跳变一是看传感器附近有没有振动源二是把采样速率降到 10SPS 以下再观察。如果跳变量级是正负几十个 LSB先用短路夹把 S / S- 短路看码值是否稳定稳定则问题在传感器机械部分不稳定则问题在模拟前端或电源。串口乱码则先统一波特率再确认串口 3 的时钟挂在 APB1 上最后用示波器看 TX 引脚的空闲电平和起始位的宽度是否符合 115200 协议。6.3 用原始码值代替重量调试排查结束时一个值得保留的习惯是把重量显示和原始码值分开调试。先在串口输出原始滤波码值确认系统稳定再切到重量显示做标定。每次改完滤波器参数或换传感器都先看原始码值是否稳定到预期的噪声范围内再谈重量精度。这样能把“模拟前端问题”和“标定问题”彻底分开调秤的效率会高很多。AD7192 这颗芯片本身噪声足够低真正限制精度的往往在这条链路之外传感器供电纹波、地平面布置、桌面振动以及你给串口调试助手选的换行符。本文还有配套的精品资源点击获取
返回列表