基于STM32的电子秤PCB程序实现

一、硬件设计要点

  1. 核心器件选型

    • 主控芯片:STM32F103C8T6(72MHz Cortex-M3,64KB Flash)

    • 传感器模块:HX711(24位ADC,内置PGA,支持增益128/64/32)

    • 称重传感器:Zemic L6G(5kg量程,C3级精度)

    • 显示模块:SSD1306 OLED(I2C接口)

    • 电源管理:TP4056(锂电池充电)+ MT3608(升压至5V)

  2. PCB布局规范

    • 四层板结构:信号层(Top)→ 地平面(GND)→ 电源平面(VCC)→ 信号层(Bottom)

    • 关键布线

      • 传感器信号线(A+/A-)长度≤10cm,差分走线(间距≤0.2mm)

      • HX711的PD_SCK和DOUT线远离数字信号(如MCU时钟)

      • 电源输入端并联10μF电解电容+0.1μF陶瓷电容


二、软件架构设计

// 主程序流程图
int main() {
    硬件初始化();      // GPIO、时钟、外设
    HX711_Init();      // 传感器校准与参数配置
    OLED_Init();       // 显示模块初始化
    while(1) {
        读取重量数据(); // HX711数据采集与滤波
        更新显示();     // OLED刷新重量值
        处理按键();     // 去皮/单位切换
        低功耗管理();   // 闲置时进入休眠
    }
}

三、关键代码实现

1. HX711驱动模块
// hx711.h
#ifndef __HX711_H
#define __HX711_H
#include "stm32f1xx_hal.h"

#define HX711_SCK_PIN  PB0
#define HX711_DOUT_PIN PB1

void HX711_GPIO_Init();
int32_t HX711_Read_RawData();
float HX711_Get_Weight(float scale, float offset);

#endif

// hx711.c
#include "hx711.h"

void HX711_GPIO_Init() {
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOB_CLK_ENABLE();
    
    GPIO_InitStruct.Pin = HX711_SCK_PIN | HX711_DOUT_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

int32_t HX711_Read_RawData() {
    int32_t raw = 0;
    for (int i=0; i<24; i++) {
        HAL_GPIO_WritePin(GPIOB, HX711_SCK_PIN, GPIO_PIN_SET);
        HAL_Delay(0.1);  // 100ns延时
        raw <<= 1;
        HAL_GPIO_WritePin(GPIOB, HX711_SCK_PIN, GPIO_PIN_RESET);
        if (HAL_GPIO_ReadPin(GPIOB, HX711_DOUT_PIN)) raw |= 1;
        HAL_Delay(0.1);
    }
    HAL_GPIO_WritePin(GPIOB, HX711_SCK_PIN, GPIO_PIN_SET);  // 增益选择
    HAL_Delay(0.1);
    HAL_GPIO_WritePin(GPIOB, HX711_SCK_PIN, GPIO_PIN_RESET);
    return raw;
}

float HX711_Get_Weight(float scale, float offset) {
    int32_t raw = HX711_Read_RawData();
    return (raw - offset) * scale / 8388608.0f;  // 24位满量程转换
}
2. 滑动平均滤波算法
#define FILTER_SIZE 16
static float weight_buffer[FILTER_SIZE] = {0};
static uint8_t index = 0;

float MovingAverageFilter(float new_value) {
    weight_buffer[index++] = new_value;
    if (index >= FILTER_SIZE) index = 0;
    
    float sum = 0;
    for (int i=0; i<FILTER_SIZE; i++) sum += weight_buffer[i];
    return sum / FILTER_SIZE;
}
3. OLED显示驱动
// oled.c
#include "ssd1306.h"

void OLED_Display_Weight(float weight) {
    char buf[16];
    sprintf(buf, "Weight: %.2f g", weight);
    SSD1306_Clear();
    SSD1306_GotoXY(0, 0);
    SSD1306_Puts(buf, &Font_7x10, 1);
    SSD1306_UpdateScreen();
}
4. 按键中断处理
// key.c
volatile uint8_t key_flag = 0;

void EXTI0_IRQHandler() {
    if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
        key_flag = 1;
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

void Process_Key() {
    if (key_flag) {
        key_flag = 0;
        // 切换去皮/单位
        static uint8_t mode = 0;
        mode = (mode + 1) % 2;
        if (mode == 0) OLED_Display_String("Tare Mode");
        else OLED_Display_String("Unit: kg");
    }
}

四、校准流程

  1. 去皮操作

    float tare = HX711_Get_Weight(1.0, 0.0);  // 空载读取
    offset = tare;  // 存储至EEPROM
    
  2. 标定砝码

    // 使用1kg砝码
    float raw = HX711_Read_RawData();
    scale = 1000.0 / (raw - offset);  // 计算比例系数
    EEPROM_Write(0x10, scale);        // 存储至EEPROM
    

五、低功耗优化

// 进入睡眠模式
void Enter_LowPower() {
    HAL_PWR_DisablePVD();          // 关闭电压检测
    HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}

// 唤醒处理
void SysTick_Handler() {
    if (WakeUp_Flag) {
        HAL_PWR_EnablePVD();
        SystemClock_Config();      // 重新配置时钟
    }
}

参考代码 基于STM32设计的电子秤PCB,原理图加程序 www.youwenfan.com/contentcnr/101822.html

六、PCB设计文件示例

文件名 内容说明
STM32F103C8T6.lpf 低通滤波配置(抑制高频噪声)
HX711.SCH 传感器接口原理图
PCB_Layout 四层板堆叠结构(信号-地-电源-信号)

七、调试与验证

  1. 串口调试

    printf("Raw Data: %ld, Weight: %.2f g\n", raw, current_weight);
    
  2. 示波器观察

    • HX711的DOUT信号应呈现稳定的24位脉冲序列

    • PD_SCK时钟频率需严格控制在10MHz以内

  3. 实物测试

    测试项 合格标准
    零点漂移 空载波动≤±0.5g
    线性度 1kg~5kg误差≤±0.2% FS
    响应时间 100ms内稳定显示

通过上述方案,可实现精度达±0.2% FS的电子秤系统。实际开发中需根据传感器特性调整滤波算法,并通过多次校准提高稳定性。

posted @ 2026-03-01 16:35  yes_go  阅读(0)  评论(0)    收藏  举报