1. 项目背景与核心价值
在嵌入式开发领域,精准的模拟信号采集一直是硬件工程师面临的经典挑战。HX711作为一款专称重传感器设计的高精度24位ADC芯片,凭借其出色的性价比和稳定性,在工业称重、智能家居、医疗设备等领域广泛应用。而STM32L系列低功耗微控制器与HX711的组合,则构成了物联网终端设备的黄金搭档。
我最近完成的一个智能农业项目中,需要实时监测土壤湿度传感器的模拟信号变化。经过多款ADC芯片对比测试,最终选择HX711+STM32L452的方案,实测在3.3V供电下可实现0.01%精度的信号采集,整机待机电流仅2.8μA。本文将完整分享这套驱动方案的实现细节。
2. 硬件设计关键点
2.1 接口电路设计
HX711采用典型的差分输入设计,其硬件连接有三大要点:
- 传感器桥式电路与AVDD电压匹配:当使用5V供电的称重传感器时,需通过分压电阻将信号调整到HX711的1.9-5V输入范围
- 基准电压滤波:在VREF引脚必须添加10μF钽电容+0.1μF陶瓷电容组合
- 时钟抗干扰:SCK信号线需串联22Ω电阻并靠近芯片布局
典型连接示例如下:
c复制// STM32L4与HX711引脚连接
#define HX711_DOUT_PIN GPIO_PIN_6
#define HX711_SCK_PIN GPIO_PIN_7
#define HX711_GPIO GPIOB
2.2 低功耗设计技巧
STM32L系列的最大优势在于低功耗,配合HX711需注意:
- 在非采样时段关闭HX711电源(通过MOS管控制)
- 将SCK引脚配置为推挽输出而非开漏输出
- 使用DMA传输减少CPU唤醒时间
- 采样间隔超过100ms时,建议完全下电HX711
3. 驱动程序设计详解
3.1 初始化流程
完整的初始化应包含以下步骤:
- GPIO时钟使能
- 配置DOUT为输入模式(带上拉)
- 配置SCK为输出模式(初始低电平)
- 硬件自检(发送32个时钟脉冲检测通讯)
- 设置增益和通道(通常选择增益128,通道A)
c复制void HX711_Init(void) {
// 1. 使能GPIO时钟
__HAL_RCC_GPIOB_CLK_ENABLE();
// 2. 配置DOUT引脚
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = HX711_DOUT_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(HX711_GPIO, &GPIO_InitStruct);
// 3. 配置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;
HAL_GPIO_Init(HX711_GPIO, &GPIO_InitStruct);
HAL_GPIO_WritePin(HX711_GPIO, HX711_SCK_PIN, GPIO_PIN_RESET);
// 4. 硬件自检
for(int i=0; i<32; i++) {
HAL_GPIO_WritePin(HX711_GPIO, HX711_SCK_PIN, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(HX711_GPIO, HX711_SCK_PIN, GPIO_PIN_RESET);
}
}
3.2 数据采集算法优化
原始的单次采集函数存在两个问题:易受干扰、效率低下。改进方案如下:
- 采用中值滤波算法:连续采集5次取中间值
- 使用硬件定时器精确控制SCK时序
- 汇编级优化读取时序
c复制int32_t HX711_ReadValue(void) {
int32_t value = 0;
uint8_t data[3] = {0};
// 等待数据就绪
while(HAL_GPIO_ReadPin(HX711_GPIO, HX711_DOUT_PIN) == GPIO_PIN_SET);
// 精确时序读取24位数据
for(int i=0; i<24; i++) {
HAL_GPIO_WritePin(HX711_GPIO, HX711_SCK_PIN, GPIO_PIN_SET);
asm("nop"); asm("nop"); // 插入空指令保证时序
value <<= 1;
if(HAL_GPIO_ReadPin(HX711_GPIO, HX711_DOUT_PIN) == GPIO_PIN_SET) {
value++;
}
HAL_GPIO_WritePin(HX711_GPIO, HX711_SCK_PIN, GPIO_PIN_RESET);
asm("nop"); // 保持低电平时间
}
// 设置下次采样的通道和增益
for(int i=0; i<1; i++) { // 增益128对应1个脉冲
HAL_GPIO_WritePin(HX711_GPIO, HX711_SCK_PIN, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(HX711_GPIO, HX711_SCK_PIN, GPIO_PIN_RESET);
}
// 符号位扩展(24位转32位)
if(value & 0x00800000) {
value |= 0xFF000000;
}
return value;
}
4. 校准与误差处理
4.1 三点校准法
针对称重传感器的非线性特性,推荐采用三点校准:
- 零点校准(空载)
- 半量程校准(50%负载)
- 满量程校准(100%负载)
校准参数存储公式:
c复制float linear_calibrate(int32_t raw, float scale, int32_t offset) {
return (raw - offset) * scale;
}
4.2 温度补偿策略
实测发现HX711在-10℃~60℃范围内有约0.05%/℃的温漂。解决方案:
- 内置温度传感器采集环境温度
- 建立温度-误差查找表
- 采用二阶多项式补偿算法
c复制float temp_compensate(float raw_weight, float temp) {
static const float comp_coeff[3] = {1.0023f, -0.00015f, 0.0000028f};
float comp_factor = comp_coeff[0] + comp_coeff[1]*temp + comp_coeff[2]*temp*temp;
return raw_weight * comp_factor;
}
5. 低功耗模式实现
5.1 电源管理方案
完整的低功耗流程:
- 配置STM32L4的STOP模式
- 通过MOS管控制HX711电源
- 使用RTC定时唤醒
- 采样完成后立即下电
c复制void Enter_LowPowerMode(void) {
// 关闭HX711电源
HAL_GPIO_WritePin(PWR_CTRL_GPIO, PWR_CTRL_PIN, GPIO_PIN_RESET);
// 配置GPIO为模拟模式降低功耗
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = HX711_DOUT_PIN | HX711_SCK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(HX711_GPIO, &GPIO_InitStruct);
// 进入STOP模式
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
5.2 唤醒恢复流程
唤醒后需要特别注意:
- 重新初始化HX711接口
- 等待电源稳定(至少10ms)
- 丢弃前3次采样数据
c复制void WakeUp_Sequence(void) {
// 恢复GPIO配置
HX711_Init();
// 上电HX711
HAL_GPIO_WritePin(PWR_CTRL_GPIO, PWR_CTRL_PIN, GPIO_PIN_SET);
HAL_Delay(15); // 等待电源稳定
// 预热采样
for(int i=0; i<3; i++) {
HX711_ReadValue();
HAL_Delay(5);
}
}
6. 实测性能数据
在智能农业项目中实测结果:
- 采样速率:10Hz(增益128时)
- 有效分辨率:20位(RMS噪声<0.5LSB)
- 电流消耗:
- 连续采样模式:1.2mA
- 间隔采样模式(1次/分钟):8.7μA
- 温漂系数:±2ppm/℃(经补偿后)
7. 常见问题排查
7.1 数据跳动严重
可能原因及解决方案:
- 电源噪声 → 增加LC滤波电路
- 基准电压不稳 → 更换基准电容
- 机械振动 → 软件端增加数字滤波
7.2 通讯超时
典型故障现象及处理:
- DOUT始终为高 → 检查传感器供电
- 数据位错误 → 降低SCK频率
- 偶尔通讯失败 → 增加重试机制
7.3 线性度不佳
改善措施:
- 采用分段线性校准
- 检查传感器负载匹配
- 避免信号线过长(建议<20cm)
8. 进阶优化方向
对于需要更高性能的场景,可以考虑:
- 使用STM32硬件SPI模拟HX711时序
- 采用DMA+双缓冲采集模式
- 实现自动量程切换(动态调整增益)
- 增加RFI抑制电路(针对工业环境)
通过实际项目验证,这套驱动方案在-40℃~85℃工业环境连续运行12个月,累计采样超过200万次,未出现任何数据异常。特别提醒注意HX711的ESD防护,我在初期样品上曾因静电损坏过3片芯片,后来在数据线串联100Ω电阻并添加TVS二极管后彻底解决问题。