当前位置: 首页 > news >正文

HX711数据不稳定问题

根本原因:PC14/PC15 是 STM32F1 的 OSC32 晶振引脚,即使不启用 LSE,这两个引脚也受备份域保护,有以下严重限制:

最大输出频率仅 3MHz(无法可靠驱动 SCK)
驱动能力极弱(最大灌电流仅 3mA)
GPIO 读取不稳定,导致位错位 → RAW 值大幅跳变

#include "hx711.h" /* 全局变量 */ static uint8_t g_gain = HX711_GAIN_128; // 增益设置 static int32_t g_offset = 0; // 零点偏移 static float g_scale = 1.0f; // 比例系数 /* 微秒级延时 */ static void HX711_Delay_us(uint32_t us) { uint32_t i; // 72MHz系统时钟,调整系数以获得更准确的延时 for(i = 0; i < us * 18; i++) { __NOP(); } } /** * @brief HX711初始化 * @note DT: PA3 (输入) * SCK: PA4 (输出) */ void HX711_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* 使能GPIOA时钟 */ __HAL_RCC_GPIOA_CLK_ENABLE(); /* 配置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_HIGH; HAL_GPIO_Init(HX711_SCK_PORT, &GPIO_InitStruct); /* 配置DT为上拉输入 */ GPIO_InitStruct.Pin = HX711_DT_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(HX711_DT_PORT, &GPIO_InitStruct); /* 初始化SCK为低电平 */ HX711_SCK_LOW(); /* 设置默认增益 */ HX711_SetGain(HX711_GAIN_128); /* 等待HX711稳定 */ HAL_Delay(100); /* 等待HX711稳定后再去皮 */ HAL_Delay(500); // 增加稳定时间 /* 自动去皮(清零) */ HX711_Tare(10); } /** * @brief 检查HX711是否准备好 * @return 1: 准备好, 0: 未准备好 */ uint8_t HX711_IsReady(void) { return (HX711_DT_READ() == GPIO_PIN_RESET) ? 1 : 0; } /** * @brief 读取HX711原始数据 * @return 24位AD值 */ uint32_t HX711_Read(void) { uint32_t data = 0; uint8_t i; /* 等待HX711准备好,超时保护 */ uint32_t timeout = 200000; while(!HX711_IsReady() && timeout--) { HX711_Delay_us(1); } if(timeout == 0) { HX711_SCK_LOW(); // 确保SCK低电平,避免进入掉电模式 return 0; } /* 关中断:防止时序被打断导致位错位 */ __disable_irq(); /* 读取24位数据 - HX711规格书时序:SCK上升沿后在高电平期间读DT */ data = 0; for(i = 0; i < 24; i++) { HX711_SCK_HIGH(); HX711_Delay_us(1); // 在SCK高电平期间读取DT数据 data = data << 1; if(HX711_DT_READ()) { data |= 0x01; } HX711_SCK_LOW(); HX711_Delay_us(1); } /* 设置增益(额外的时钟脉冲) */ for(i = 0; i < g_gain; i++) { HX711_SCK_HIGH(); HX711_Delay_us(1); HX711_SCK_LOW(); HX711_Delay_us(1); } /* 开中断 */ __enable_irq(); /* 将24位数据转换为有符号32位数据 */ if(data & 0x800000) { data |= 0xFF000000; } return data; } /** * @brief 读取HX711平均值 * @param times: 采样次数 * @return 平均AD值 */ uint32_t HX711_ReadAverage(uint8_t times) { int64_t sum = 0; // 使用int64_t防止溢出 uint8_t i; for(i = 0; i < times; i++) { sum += (int32_t)HX711_Read(); // 转换为有符号数 HAL_Delay(10); } return (uint32_t)(sum / times); } /** * @brief 设置HX711增益 * @param gain: 增益选择 * HX711_GAIN_128: 通道A,增益128 * HX711_GAIN_32: 通道B,增益32 * HX711_GAIN_64: 通道A,增益64 */ void HX711_SetGain(uint8_t gain) { g_gain = gain; HX711_Read(); // 读取一次以应用新的增益设置 } /** * @brief 去皮(设置零点) * @param times: 采样次数 */ void HX711_Tare(uint8_t times) { int64_t sum = 0; uint8_t i; /* 丢弃前2次预热读数,等待ADC内部稳定 */ for(i = 0; i < 2; i++) { HX711_Read(); HAL_Delay(10); } for(i = 0; i < times; i++) { sum += (int32_t)HX711_Read(); HAL_Delay(10); } g_offset = (int32_t)(sum / times); } /** * @brief 获取重量值 * @return 重量值(单位由比例系数决定) */ int32_t HX711_GetWeight(void) { #define HX711_SAMPLE_NUM 5 int32_t buf[HX711_SAMPLE_NUM]; int32_t tmp; uint8_t i, j; int64_t sum = 0; float weight; /* 采样5次 */ for(i = 0; i < HX711_SAMPLE_NUM; i++) { buf[i] = (int32_t)HX711_Read(); HAL_Delay(10); } /* 冒泡排序(升序) */ for(i = 0; i < HX711_SAMPLE_NUM - 1; i++) { for(j = 0; j < HX711_SAMPLE_NUM - 1 - i; j++) { if(buf[j] > buf[j + 1]) { tmp = buf[j]; buf[j] = buf[j + 1]; buf[j + 1] = tmp; } } } /* 去掉最大值和最小值,取中间3次均值 */ for(i = 1; i < HX711_SAMPLE_NUM - 1; i++) { sum += buf[i]; } /* 重量计算:(均值 - 零点值) / 比例系数 */ weight = (float)((int32_t)(sum / (HX711_SAMPLE_NUM - 2)) - g_offset) / g_scale; /* 小于0视为空载噪声,返回0 */ if(weight < 0.0f) { return 0; } return (int32_t)weight; #undef HX711_SAMPLE_NUM } /** * @brief 设置比例系数 * @param scale: 比例系数(AD值/重量单位) * @note 需要通过校准获得此值 * 例如: 放置100g砂码,读取AD差值为1000,则scale = 1000/100 = 10 * 注意:如果数值为负,说明传感器接线反了,可传入负值校正 */ void HX711_SetScale(float scale) { if(scale == 0.0f) scale = 1.0f; // 防止除零错误 g_scale = scale; } /** * @brief 设置零点偏移 * @param offset: 零点偏移值 */ void HX711_SetOffset(int32_t offset) { g_offset = offset; } /** * @brief HX711进入掉电模式 */ void HX711_PowerDown(void) { HX711_SCK_LOW(); HX711_SCK_HIGH(); HAL_Delay(1); } /** * @brief HX711退出掉电模式 */ void HX711_PowerUp(void) { HX711_SCK_LOW(); }
#ifndef __HX711_H #define __HX711_H #include "main.h" /* HX711引脚定义 */ #define HX711_DT_PORT GPIOA #define HX711_DT_PIN GPIO_PIN_3 #define HX711_SCK_PORT GPIOA #define HX711_SCK_PIN GPIO_PIN_4 /* HX711控制宏 */ #define HX711_SCK_HIGH() HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_SET) #define HX711_SCK_LOW() HAL_GPIO_WritePin(HX711_SCK_PORT, HX711_SCK_PIN, GPIO_PIN_RESET) #define HX711_DT_READ() HAL_GPIO_ReadPin(HX711_DT_PORT, HX711_DT_PIN) /* HX711增益选择 */ #define HX711_GAIN_128 1 // 通道A,增益128 #define HX711_GAIN_32 2 // 通道B,增益32 #define HX711_GAIN_64 3 // 通道A,增益64 /* 函数声明 */ void HX711_Init(void); uint8_t HX711_IsReady(void); uint32_t HX711_Read(void); uint32_t HX711_ReadAverage(uint8_t times); void HX711_SetGain(uint8_t gain); void HX711_Tare(uint8_t times); int32_t HX711_GetWeight(void); void HX711_SetScale(float scale); void HX711_SetOffset(int32_t offset); void HX711_PowerDown(void); void HX711_PowerUp(void); #endif /* __HX711_H */
http://www.jsqmd.com/news/699951/

相关文章:

  • RAGAs与G-Eval:AI智能体评估实战指南
  • 职场效率提升:OpenClaw 电脑自动化办公部署教程
  • OpenPLC Editor:开源工业自动化开发的终极指南
  • 如何永久备份微信聊天记录?免费工具WeChatMsg完整指南
  • Windows 一键自动加入企业 AD 域的批处理脚本
  • 算法总结:图论——拓扑序
  • 30岁Java程序员裸辞All in AI,一年后我成了年薪百万的AI应用开发工程师!
  • Windhawk完全指南:免费开源Windows系统个性化定制神器终极教程
  • 30天快速上手Python-02 Python原生数据结构-2 列表List[]
  • API 批量纯代付接口
  • Switch大气层整合包终极指南:从破解到精通,完整解锁你的游戏主机
  • 如何在5分钟内用kohya_ss轻松训练你的AI绘画模型
  • 04-08-10 结论与总结 (Conclusion)
  • DeepSeek V4正式发布,昇腾超节点系列产品全面支持
  • VSCode多Agent调试崩溃频发?资深架构师紧急披露6个隐藏配置陷阱(含vscode-insiders验证数据)
  • 如何用“五维成熟度”量化品牌资产?专知智库新模型给CTO们一个技术解法
  • 基于Spring框架的银行转账业务,通过XML配置方式实现事务管理
  • 五一出游户外徒步必备:开源生存工具Trail Sense完全指南
  • 告别R-CNN的龟速:用Fast R-CNN实现目标检测的‘一键加速’(附VGG16实战对比)
  • Bridging Human Evaluation to Infrared and Visible Image Fusion
  • OOM Killer 选中你的进程只用了 0.3 毫秒——追踪 oom_badness() 的打分公式和 5 个可调旋钮
  • 5分钟掌握B站视频下载:BilibiliDown终极免费工具使用指南
  • 光伏四可装置设备性能评估:光伏组件衰减率与逆变器效率监测
  • 真空型压力传感器品牌推荐 厂家排行榜 - WHSENSORS
  • 终极Qwerty Learner打字练习软件完整指南:3步快速提升英语输入速度
  • 代价敏感SVM解决数据不平衡分类问题实战
  • 2026年4月 全国GEO优化服务商榜单 AI搜索行业深度解析
  • 2026宁波展厅设计核心转化技巧一线实战解析
  • 如何快速搭建全平台直播弹幕监控系统:面向开发者的终极解决方案
  • 【仅开放72小时】CUDA 13.3.1生产环境适配清单(含PyTorch 2.4/DeepSpeed 0.14/Triton 3.0兼容性矩阵+17个已验证patch)