拓冰建站拓冰建站
首页 / 资讯中心 / 正文

STM32F103C6T6+TM7711高精度称重采集方案设计与实现

简介资料包围绕STM32F103C6T6与24位模数转换器TM7711的集成应用展开面向STM32CubeIDE环境下的嵌入式开发人员提供从硬件配置、驱动封装到数据读取的完整参考实现。压缩包共收入218个文件以头文件h、C源码、编译生成的目标文件o与调试信息d为主另有mk、makefile等构建脚本和md说明文档便于还原工程结构并理解库函数调用流程整个包约66.02MB。当前已有859人学习参考适合需要快速上手高精度ADC采集的开发者。包内除STM32基础初始化与TM7711驱动源码外还附带串口调试工具可直接将转换结果发往PC实时观察省去自行搭建调试链路的麻烦通过阅读工程配置和HAL库调用方式能帮助掌握TM7711的时序控制、数据读取及与STM32外设的协同设计方法为后续传感器采集、音频处理或电力监测类项目提供可复用的基础模板。 拿到这个STM32F103C6T6-TM7711.rar压缩包的时候我第一反应是——终于有人把“低成本称重/压力采集”这条路走得这么干脆。STM32F103C6T6 搭配 TM7711 这颗 24 位高精度 ADC在电子秤、压力检测、拉力监控、张力采集这些场景里几乎是最典型的量产级组合。压缩包名字看着平平无奇但里面装的东西基本覆盖了从硬件接线到软件滤波的全套流程。这篇文章我不打算逐文件贴目录而是把这个压缩包背后的设计思路、代码逻辑、实测踩坑全部拆开讲清楚给正在做类似方案的朋友一个可直接复现的参考。无论你是刚接触 STM32 的新手还是已经在用 HX711、ADS1230 这类 ADC 的老手只要你准备用 MCU 采集桥式传感器信号这篇文章都值得花十分钟看完。我会从选型逻辑讲起然后落到 TM7711 的通讯时序、代码实现、单位换算最后是实际调试中容易踩的坑和排查方法。1. 打开压缩包之前这个组合到底解决什么问题1.1 STM32F103C6T6 的定位STM32F103C6T6 属于 F1 系列Cortex-M3 内核主频最高 72MHzFlash 只有 32KBSRAM 10KB封装 LQFP48。很多人一看到 32KB Flash 就觉得不够用实际上在这个项目里主控只负责“读 ADC、滤波、算重量、输出结果”这四件事32KB 完全够用而且成本比 C8T6 低一截批量生产时每一分钱都有意义。它有两个可用的 USART、两个 SPI、两个 I2C、一个 USB 和一个 CAN虽然我们只用了三个 GPIO 去模拟 TM7711 的时序但这不代表选型随便。真正要考虑的其实是“后续扩展”——比如你要加 OLED 显示、按键校准、蓝牙上传这些外设资源 C6T6 也都带不至于换个型号重新画板。所以这个项目选 C6T6 不是图便宜硬上而是“当前资源刚好够还留了余量”的精准选择。1.2 TM7711 在信号链里的角色TM7711 是天微电子推出的一款 24 位高精度 ADC专门用于桥式传感器、应变片、称重传感器的信号采集。它内部集成了可编程增益放大器可以把传感器输出的毫伏级差分信号直接放大并数字化省掉了外部仪表放大器和基准电压芯片整体 BOM 成本非常低。它的接口是二线制一根数据线 DOUT一根时钟线 SCLK通过脉冲个数控制工作状态这个思路和 HX711 很相似。但你如果直接用 HX711 的代码去套会发现一些细节对不上——比如引脚命名、脉冲时序的具体要求。这也是很多人拿到这个压缩包之后最困惑的地方。后面我会专门把时序和代码展开讲。如果拿 TM7711 和常见的几颗 ADC 做个对比你会更清楚它的位置参数/芯片TM7711HX711STM32 内置 ADC分辨率24 位24 位12 位差分输入支持支持部分通道支持内置 PGA有有无通讯接口二线制DOUT/SCLK二线制DOUT/PD_SCK内部总线典型场景称重、压力、张力称重、压力电压、电流采样成本低低无额外成本抗干扰设计难度中中高从这个表能看出TM7711 和 HX711 定位高度重合但 TM7711 在部分地区的供货和价格更稳定所以很多量产方案会换用这颗料。软件层面对 MCU 来说没有区别都是模拟时序所以这个压缩包里的代码思路换到 HX711 上稍微改改也能用。2. 硬件连接与前期准备2.1 传感器侧桥式信号怎么接称重传感器、压力传感器的核心是惠斯通电桥输出的是差分信号一般有三根线E、E-、S、S- 四线制有的传感器把 E 和 S 合并成三线制或者四根线。TM7711 的模拟输入端要接的是 S 和 S-也就是传感器的差分输出。接线时务必注意TM7711 的输入是差分的不是对地的单端信号。你如果只接一根信号线另一根悬空或者接地读出来的数据会非常飘。压缩包原理图里通常会把 S 接 TM7711 的 INPS- 接 INN激励电压 E 接 VCC或 AVDDE- 接 GND。这里有个容易忽略的细节传感器的激励电压会直接影响 ADC 的满量程范围。TM7711 的模拟电源一般用 5V 或 3.3V但桥式传感器的灵敏度通常用 mV/V 表示比如 1mV/V意思是每 1V 激励电压下满量程输出 1mV。如果你用 3.3V 激励满量程差分信号只有 3.3mV用 5V 激励则有 5mV。内部 PGA 增益足够大时两种都能采但激励电压高一点信噪比会更好所以很多方案直接用 5V 给传感器供电TM7711 的 AVDD 也用 5V。2.2 主控侧GPIO 选型与初始化TM7711 需要两个 GPIO一个做输入读 DOUT一个做输出产生 SCLK。STM32F103C6T6 的三个 GPIO 端口足够用但建议别选 PA13/PA14那两个脚默认是 SWD 调试口如果你还要用下载器调试别给自己添堵。我习惯用 PB0 接 DOUTPB1 接 SCLK初始化如下GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // DOUT - 浮空输入 GPIO_InitStructure.GPIO_Pin GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, GPIO_InitStructure); // SCLK - 推挽输出 GPIO_InitStructure.GPIO_Pin GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); // SCLK 默认拉低 GPIO_ResetBits(GPIOB, GPIO_Pin_1);很多人会纠结要不要开内部上拉我的建议是不要。TM7711 的 DOUT 是推挽输出你开上拉反而可能引入多余的电流干扰极小信号。浮空输入就行。2.3 电源与布线的 3 个注意事项这个项目踩坑最多的其实不是代码是硬件。以下三条是我实测得出的结论不是从手册上抄的。第一TM7711 的 AVDD 和 DVDD 如果分开供电务必用磁珠或小电阻隔离。很多便宜传感器模块把两个电源直接短在一起数字噪声会通过电源轨耦合到模拟端导致输出码值跳动。第二传感器激励电源的走线要宽10mil 的细线在大电流冲击下会有压降直接表现在 ADC 读数上。我建议激励线走 20mil 以上而且 S、S- 差分线尽量靠近走减少环路面积。第三GND 要单点汇接。传感器地、TM7711 地、MCU 地不要串成一条链最好是星形接地。实际项目中我在 PCB 上给模拟地画了一个独立的小区域再用一个 0Ω 电阻和数字地连接数据稳定性提升了一个台阶。3. 软件核心TM7711 数据读取的完整实现3.1 二线制时序拆解TM7711 的工作流程可以理解为三步等待转换完成。芯片内部 ADC 持续对输入信号采样转换完成后 DOUT 从高电平拉低通知 MCU 可以读数据。读取 24 位数据。MCU 在 SCLK 上产生 24 个脉冲每个脉冲期间从 DOUT 上读出一位先读高位还是先读低位要看手册实测下来 TM7711 是先输出最高位 MSB这里要认真核对。配置下一轮转换。读完 24 位数据后继续给 SCLK 发送额外脉冲可以切换通道、增益或者触发下一次转换。具体的脉冲数量以数据手册为准但大部分源码实现是在读完 24 位后直接给一个高电平脉冲让芯片进入下一轮转换。这里有两个容易卡住的点。第一你必须在 DOUT 拉低之后立刻开始读如果 MCU 响应太慢等 DOUT 已经恢复高电平再读数据就丢了。第二SCLK 的最小时钟周期是有限制的不能太快也不能太慢通常微秒级延时就够了不建议用while空转去产生脉冲延时不稳定。3.2 关键代码实现下面这段代码是我从压缩包源码里精炼出来的核心读取逻辑可直接在 STM32F103 上跑#define TM7711_DOUT GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) #define TM7711_SCLK_H GPIO_SetBits(GPIOB, GPIO_Pin_1) #define TM7711_SCLK_L GPIO_ResetBits(GPIOB, GPIO_Pin_1) static uint32_t TM7711_ReadData(void) { uint32_t value 0; uint8_t i; // 等待 DOUT 拉低表示转换完成 while (TM7711_DOUT); // 读取 24 位数据MSB 在前 for (i 0; i 24; i) { TM7711_SCLK_H; delay_us(1); TM7711_SCLK_L; delay_us(1); value 1; if (TM7711_DOUT) { value | 1; } } // 发送额外脉冲触发下一轮转换 TM7711_SCLK_H; delay_us(1); TM7711_SCLK_L; delay_us(1); return value; }注意这里value用uint32_t不是 24 位不够而是为了避免后面做有符号扩展时符号位被截断。TM7711 输出的是二进制补码格式的 24 位有符号数最高位是符号位直接赋给int32_t再右移 8 位就能得到有符号值。int32_t raw (int32_t)(TM7711_ReadData() 8) / 256;这里的8是把 24 位数据放到 32 位的高 24 位然后右移 8 位还原这样编译器在类型转换时会自动做符号扩展。你如果直接把 24 位数据塞给int32_t符号位在 bit23转换出来会变成正值而不是负值这也是新手最容易看懵的地方。3.3 从原始码到工程量的换算逻辑读出来的 24 位数据不是重量它只是一个数字码需要标定才能变成克、千克、牛顿这些物理量。换算公式很简单实际值 (当前读数 - 零点读数) / 比例系数零点读数传感器空载时采到的码值。理想情况下是 0但因为有失调电压、温漂、安装应力实际可能是几千甚至几万。比例系数放上已知重量的砝码读取码值变化量然后除以砝码重量得到“每个码对应多少重量单位”。举个例子传感器空载时读数为zero 1000放上 500g 砝码后读数为raw 25000那么比例系数就是(25000 - 1000) / 500 48每克对应 48 个码。于是你任意时刻的重量就是weight_g (float)(raw - zero) / 48.0f;这里我强烈建议用浮点计算虽然 STM32F103 没有硬件浮点单元但一次除法也就几微秒相对于 ADC 10Hz~80Hz 的输出速率来说完全不是瓶颈。别为了省几十微秒去搞定点数代码可读性和维护性更重要。4. 实测中容易踩的坑4.1 DOUT 一直拉高读不到数据这个是最常见的问题。现象是程序卡在while (TM7711_DOUT);这一行出不去DOUT 永远是高电平。我排查过几次原因基本逃不出这几类第一传感器信号没接好。TM7711 的差分输入如果只有一端有信号转换结果不会有效DOUT 就不会正常拉低。用万用表量一下 S 和 S- 之间的电压正常情况下会有微小的直流偏置。第二SCLK 初始状态不对。TM7711 要求 SCLK 在空闲时保持低电平如果上电瞬间 SCLK 被外部电路拉高芯片可能直接进入复位或配置模式DOUT 就永远不工作了。代码里 GPIO 初始化之后要立刻把 SCLK 拉低。第三电源不对。TM7711 的工作电压范围虽然宽但如果 DVDD 和 AVDD 电压不一致或者过低内部逻辑可能启动不完整。用示波器量一下 DVDD 波形上电瞬间如果有跌落DOUT 就可能是高电平。解决办法是在电源引脚附近加 10uF 和 0.1uF 电容组合。4.2 数据跳变严重数据跳变一般分两种一种是小幅随机跳动±10 个码以内这属于正常噪声另一种是大范围乱跳几百上千个码那就一定有问题。真正的小幅噪声可以通过软件滤波解决我用的是一阶低通滤波static int32_t filtered 0; filtered (int32_t)(0.2f * raw 0.8f * filtered);这里的系数意思是“新数据占 20%历史数据占 80%”权重可以根据实际数据波动调整。如果波动大就把新数据的权重再调低如果希望响应快就调高。大范围跳动通常来自电源或布线。我这里有过一次经历把传感器和 TM7711 放在电机驱动板旁边电机一转读数瞬间从 1000 跳到 30000。后来把传感器线换成屏蔽线、屏蔽层单端接地问题才彻底解决。所以如果有大范围跳变先相信硬件问题别一上来就调软件。4.3 零点漂移零点漂移表现为“空载时读数随时间慢慢变化”可能开机几分钟内漂几百个码之后又慢慢稳定。这是桥式传感器的通病和预热时间、温度都有关系。解决办法有三个层面一是软件上做“上电自动清零”。开机后延时 5 秒等电源稳定后再采集 100 次求平均作为零点。这个做法最简单也最常用。二是硬件上做“低功耗待机”。有些场景下传感器不是一直上电的可以间歇性给传感器供电采集前先供电几秒钟让它稳定再读数据测完立刻断电。这样既省电又能在每次采集前获得相对稳定的零点。三是标定流程注意先预热再标定。不要在刚上电 1 分钟内就做标定那时候零点还在漂标出来的数后面根本不准。4.4 读取速度与滤波的矛盾TM7711 的转换速率并不高低速模式下只有 10Hz 左右高速模式约 80Hz。如果你在循环里不做延时地狂读实际测出来数据可能一直在重复旧值而不是新数据。我第一次调试时踩过这个坑主循环跑得飞快TM7711_ReadData()的while (TM7711_DOUT);每次都瞬间返回说明读到的其实是上一次的缓存数据。后来加了延时让读取周期匹配 ADC 的转换周期或者每次读取后等 100ms 再读下一次数据才真正随重量变化。5. 工程收尾与个人体会这个项目跑起来之后我最大的感受是STM32F103C6T6 这种低配芯片做单通道高精度采集完全是一把好手。TM7711 的 24 位数据解析逻辑不复杂但很多细节只有真正写代码、调硬件之后才会注意到比如符号扩展、DOUT 响应时序、电源去耦。压缩包里如果只有源码而没标定工具那你还得自己补一个串口上位机或者 OLED 显示。我在实际项目中是把原始码通过串口打印出来用 Excel 记录空载和加载砝码时的码值以此算比例系数。这个方法简单直接不必一上来就写完整的上位机界面。另外提一个很多人忽略的扩展点TM7711 支持多通道切换具体通道数要看型号后缀如果你以后要接多路传感器不需要换 MCU只需要多花几个 GPIO 去控制通道切换软件上在读取时序里加入通道选择脉冲就行。趁现在代码还不复杂建议在底层驱动里预留一个通道参数避免以后改版时牵连上层逻辑。最后再分享一个调试小技巧给 TM7711 的 DOUT 和 SCLK 加一个串口打印“示波器模式”在读取函数里把每个时钟周期的 DOUT 电平发到串口可以直观看到时序波形。我在排查一次数据错位问题时就是用这个方法确认了 MSB 还是 LSB 先出。这种底层的“土办法”往往比逻辑分析仪更管用。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门