news 2026/6/11 9:49:47

STM32HAL库驱动HX711压力传感器:从接线校准到OLED显示的完整避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32HAL库驱动HX711压力传感器:从接线校准到OLED显示的完整避坑指南

STM32HAL库驱动HX711压力传感器:从接线校准到OLED显示的完整避坑指南

当你第一次拿到HX711压力传感器模块时,可能会被它小巧的体积和简单的四线接口所迷惑。但真正开始动手连接STM32开发板时,各种问题就会接踵而至:数值跳动不稳定、校准公式理解错误、OLED显示异常...本文将带你一步步避开这些坑,完成从硬件连接到软件实现的完整流程。

1. 硬件连接:那些容易忽略的细节

1.1 接线顺序的玄机

HX711模块通常有四个引脚:VCC、GND、SCK和DT。看似简单的连接,却藏着几个关键点:

  • 电源隔离:建议为HX711单独供电,避免与STM32共用电源导致干扰。如果必须共用,确保电源线足够粗,并在VCC和GND之间添加100μF电容。
  • 信号线处理:SCK和DT线长度不宜超过15cm,过长会导致信号衰减。如果必须延长,建议使用双绞线。

注意:不同厂家的HX711模块引脚颜色可能不同,务必以模块上的丝印为准,不要盲目按照颜色接线。

1.2 GPIO初始电平设置

在CubeMX中配置SCK引脚时,初始电平设置直接影响测量稳定性:

// 错误的配置会导致数值跳动 GPIO_InitStruct.Pin = HX711_SCK_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 必须设置为HIGH GPIO_InitStruct.Level = GPIO_PIN_SET; HAL_GPIO_Init(HX711_SCK_GPIO_Port, &GPIO_InitStruct);

如果初始电平设置为LOW,取下重物后会出现数值大幅跳动的现象。这是因为HX711内部需要在高电平状态下完成数据转换。

2. CubeMX配置:关键参数解析

2.1 时钟配置

HX711对时序要求严格,系统时钟配置不当会导致通信失败。推荐配置:

参数推荐值说明
HCLK72MHz保证足够的处理速度
APB136MHz外设时钟
APB272MHzGPIO时钟

2.2 GPIO模式选择

DT引脚应配置为上拉输入模式:

GPIO_InitStruct.Pin = HX711_DT_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; // 必须启用上拉 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(HX711_DT_GPIO_Port, &GPIO_InitStruct);

3. 代码实现:避开数据处理的坑

3.1 数据读取时序

HX711的24位数据需要严格按照时序读取,以下是一个稳定的读取函数:

int32_t HX711_GetData(void) { int32_t count = 0; uint8_t i; HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_RESET); HAL_Delay(1); // 等待DT变低 while(HAL_GPIO_ReadPin(HX711_DT_GPIO_Port, HX711_DT_Pin) == GPIO_PIN_SET); // 读取24位数据 for(i=0; i<24; i++) { HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_SET); HAL_Delay(1); count = count << 1; HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_RESET); HAL_Delay(1); if(HAL_GPIO_ReadPin(HX711_DT_GPIO_Port, HX711_DT_Pin) == GPIO_PIN_SET) { count++; } } // 第25个脉冲选择通道和增益 HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_SET); HAL_Delay(1); HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_RESET); HAL_Delay(1); // 补码转原码 return count ^ 0x800000; }

3.2 数据处理与滤波

原始数据通常会有噪声,需要采用滑动平均滤波:

#define FILTER_SIZE 5 int32_t filter_buf[FILTER_SIZE] = {0}; uint8_t filter_index = 0; int32_t HX711_GetFilteredData(void) { filter_buf[filter_index] = HX711_GetData(); filter_index = (filter_index + 1) % FILTER_SIZE; int32_t sum = 0; for(uint8_t i=0; i<FILTER_SIZE; i++) { sum += filter_buf[i]; } return sum / FILTER_SIZE; }

4. 校准实战:从理论到实践

4.1 校准原理详解

HX711的校准需要两个已知点:空载值和已知重量值。校准公式为:

weight = (raw_value - offset) * scale

其中:

  • offset是空载时的原始值
  • scale是比例系数,通过已知重量计算得出

4.2 分步校准指南

  1. 获取空载值

    int32_t offset = HX711_GetFilteredData();
  2. 放置已知重量(如100g砝码)并获取新值:

    int32_t known_weight_value = HX711_GetFilteredData();
  3. 计算比例系数

    float scale = 100.0f / (known_weight_value - offset);
  4. 应用校准公式

    float weight = (current_value - offset) * scale;

提示:如果没有标准砝码,可以使用手机等已知重量的物品。例如,200g手机对应的100g计算值为:(phone_value - offset)/2 + offset

4.3 校准值存储

为避免每次上电重新校准,可以将offset和scale存入Flash:

typedef struct { int32_t offset; float scale; uint32_t crc; // 校验值 } HX711_Calib_t; void Save_Calibration(HX711_Calib_t *calib) { // 计算CRC32校验值 calib->crc = Calculate_CRC32((uint8_t*)calib, sizeof(HX711_Calib_t)-4); // 写入Flash HAL_FLASH_Unlock(); FLASH_Erase_Sector(FLASH_SECTOR_6, VOLTAGE_RANGE_3); HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, 0x08060000, *(uint32_t*)calib); HAL_FLASH_Lock(); } int Load_Calibration(HX711_Calib_t *calib) { // 从Flash读取 memcpy(calib, (void*)0x08060000, sizeof(HX711_Calib_t)); // 校验CRC uint32_t crc = Calculate_CRC32((uint8_t*)calib, sizeof(HX711_Calib_t)-4); return (crc == calib->crc) ? 0 : -1; }

5. OLED显示优化

5.1 显示刷新策略

频繁刷新OLED会导致闪烁,建议采用差异刷新:

char current_display[20] = {0}; char new_display[20] = {0}; void Update_Display(float weight) { sprintf(new_display, "%.1fg", weight); // 只有数值变化时才刷新 if(strcmp(current_display, new_display) != 0) { OLED_ClearLine(2); // 清除特定行 OLED_ShowString(2, 2, new_display); strcpy(current_display, new_display); } }

5.2 图形化显示

对于需要直观显示重量变化的场景,可以添加简单的条形图:

void Draw_Weight_Bar(float weight, float max_weight) { uint8_t max_width = 120; // OLED宽度 uint8_t bar_width = (uint8_t)((weight / max_weight) * max_width); OLED_DrawRectangle(10, 40, bar_width, 10, OLED_COLOR_NORMAL); OLED_Refresh(); }

6. 常见问题排查

遇到问题时,可以按照以下步骤排查:

  1. 数值始终为0

    • 检查DT引脚是否接触良好
    • 确认SCK引脚初始电平设置为HIGH
    • 测量VCC电压是否在2.6V-5.5V范围内
  2. 数值跳动严重

    • 检查电源是否稳定,建议增加滤波电容
    • 确保传感器机械结构稳固,无振动
    • 尝试增加滤波算法的窗口大小
  3. OLED无显示

    • 检查I2C/SPI线路连接
    • 确认OLED初始化代码正确执行
    • 测量OLED供电电压(通常为3.3V或5V)

7. 进阶技巧

7.1 自动去皮功能

实现按下按键自动去皮:

if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET) { HAL_Delay(50); // 消抖 if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET) { offset = HX711_GetFilteredData(); Save_Calibration(&calib); } }

7.2 低功耗模式

对于电池供电的应用,可以间歇性唤醒HX711:

void Enter_LowPower_Mode(void) { // 设置SCK为高电平超过60μs使HX711进入休眠 HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_SET); HAL_Delay(1); // 配置STM32进入STOP模式 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); } void WakeUp_HX711(void) { // 拉低SCK唤醒HX711 HAL_GPIO_WritePin(HX711_SCK_GPIO_Port, HX711_SCK_Pin, GPIO_PIN_RESET); HAL_Delay(1); }

7.3 多传感器切换

如果需要使用多个HX711模块,可以通过片选信号切换:

#define HX711_1_CS_H HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET) #define HX711_1_CS_L HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET) #define HX711_2_CS_H HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET) #define HX711_2_CS_L HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET) int32_t Read_HX711(uint8_t sensor_num) { if(sensor_num == 1) { HX711_1_CS_L; HX711_2_CS_H; } else { HX711_1_CS_H; HX711_2_CS_L; } return HX711_GetFilteredData(); }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 9:49:28

Nuxt 3项目从零到生产:一站式搭建与高效部署实战

1. Nuxt 3项目环境准备与初始化 最近在帮朋友搭建一个电商网站时&#xff0c;我选择了Nuxt 3作为前端框架。不得不说&#xff0c;相比Nuxt 2&#xff0c;Nuxt 3在开发体验和性能上都有显著提升。但刚开始配置环境时&#xff0c;我也踩了不少坑&#xff0c;这里分享下我的经验。…

作者头像 李华
网站建设 2026/6/11 9:42:20

WindowResizer终极指南:突破Windows窗口限制的完整解决方案

WindowResizer终极指南&#xff1a;突破Windows窗口限制的完整解决方案 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 你是否曾经遇到过无法调整大小的应用程序窗口&#xff1f;或…

作者头像 李华
网站建设 2026/6/11 9:48:03

如何快速掌握AKShare金融数据接口:新手必备的5个实战技巧

如何快速掌握AKShare金融数据接口&#xff1a;新手必备的5个实战技巧 【免费下载链接】akshare AKShare is an elegant and simple financial data interface library for Python, built for human beings! 开源财经数据接口库 项目地址: https://gitcode.com/gh_mirrors/aks…

作者头像 李华
网站建设 2026/4/14 13:25:27

如何永久保存微信聊天记录?WeChatMsg让你的珍贵记忆不再流失

如何永久保存微信聊天记录&#xff1f;WeChatMsg让你的珍贵记忆不再流失 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we…

作者头像 李华
网站建设 2026/4/14 13:24:23

AI头像生成器多场景落地:社交平台头像+角色形象+AI绘画工作流整合

AI头像生成器多场景落地&#xff1a;社交平台头像角色形象AI绘画工作流整合 1. 为什么你需要一个AI头像生成器 你有没有遇到过这样的情况&#xff1a;想要换一个好看的头像&#xff0c;但在网上找了半天也找不到满意的&#xff1b;或者想为你的游戏角色设计一个独特形象&…

作者头像 李华