Skip to content

Repository files navigation

MS5837 Depth Sensor — STM32 Firmware

基于 STM32F103C8T6 的 MS5837-30BA 深度传感器驱动,I2C 采集 → 二阶补偿解算 → 二进制数据帧通过 USART1 输出。

硬件连接

STM32F103C8T6 MS5837 说明
PB6 SCL I2C1 时钟 (400kHz)
PB7 SDA I2C1 数据
PA9 USART1 TX (115200bps, 上位机 RX)
PA10 USART1 RX (保留)
3.3V VDD 电源
GND GND

串口数据帧协议

每帧 11 字节,小端序,约 28Hz 发送频率(OSR=8192)。

┌──────┬──────┬──────────┬───────────────┬───────────┬──────────┐
│  0   │  1   │  2   3   │   4   5   6  7 │   8   9   │    10    │
│ 0xA5 │ 0x5A │ depth_cm │ pressure_01   │ temp_01c  │ checksum │
│      │      │ uint16   │ uint32        │ int16     │ uint8    │
└──────┴──────┴──────────┴───────────────┴───────────┴──────────┘
字节 字段 类型 单位 说明
0 SOF0 uint8 帧头固定 0xA5
1 SOF1 uint8 帧头固定 0x5A
2-3 depth_cm uint16 LE cm 水深,范围 0-65535 cm
4-7 pressure_01mbar uint32 LE 0.1 mbar 绝对压力
8-9 temp_01c int16 LE 0.1 °C 温度,有符号
10 checksum uint8 字节 2-9 的 XOR

解析示例 (Python)

import struct

def parse_frame(data: bytes):
    """返回 (depth_m, pressure_mbar, temp_c) 或 None"""
    if len(data) != 11 or data[0] != 0xA5 or data[1] != 0x5A:
        return None
    cksum = 0
    for b in data[2:10]:
        cksum ^= b
    if cksum != data[10]:
        return None
    d, p, t = struct.unpack('<H I h', data[2:10])
    return (d / 100.0, p / 10.0, t / 10.0)

帧示例

# 水深 0.00m, 气压 1013.2mbar, 温度 25.3°C
A5 5A  00 00  F0 27 00 00  FD 00  2D

# 水深 1.23m, 压力 1134.5mbar, 温度 24.8°C
A5 5A  7B 00  D2 2C 00 00  F8 00  AE

上电流程

  1. 复位 MS5837 (0x1E),等待 10ms
  2. 读取 PROM 校准系数 C1-C6
  3. 大气压校准 — 自动采集 20 帧压力数据取均值作为 P_atm 基准(约 0.7 秒)
  4. 进入主循环 — 每周期约 36ms:
  D2 温度转换 (0x5A) → 等待 18ms → 读取 D2 ADC
→ D1 压力转换 (0x4A) → 等待 18ms → 读取 D1 ADC
→ 二阶温度补偿 (int64 运算)
→ 深度 = (P_abs - P_atm) / 98.1   (淡水, ρ=1000 kg/m³)
→ 打包二进制帧 → USART1 发送

编译

Keil MDK-ARM

打开 MDK-ARM/interpreter.uvprojx,编译下载。

EIDE (VSCode)

用 Embedded IDE 插件打开项目,目标选 interpreter,工具链 AC6 (ARM Compiler 6)。

优化说明

为了适配 32KB Flash 的芯片(国产克隆片常见),I2C 和 UART 均使用裸寄存器操作替代 HAL 库:

移除的 HAL 模块 替代方案
stm32f1xx_hal_i2c.c (~25KB) 直接操作 I2C1 寄存器
stm32f1xx_hal_uart.c (~9KB) USART1 SR/DR 轮询
stm32f1xx_hal_dma.c (~3KB) 不使用 DMA

编译选项:-Os + MicroLIB。最终二进制约 15-20 KB

参数调整

以下宏定义在 Core/Inc/ms5837.h 中可按需修改:

默认值 说明
WATER_DENSITY_FRESH 1000.0f 液体密度 kg/m³,海水改为 1025.0f
DEPTH_CALIB_SAMPLES 20 上电大气压校准采样帧数
MS5837_CONVERT_DELAY 18 ADC 转换等待时间 ms (OSR=8192)

文件结构

interpreter/
├── Core/
│   ├── Inc/
│   │   ├── main.h
│   │   ├── ms5837.h      ← 传感器驱动头文件
│   │   ├── i2c.h
│   │   └── usart.h
│   └── Src/
│       ├── main.c         ← 主循环 + 帧打包发送
│       ├── ms5837.c       ← I2C 裸寄存器 + PROM + ADC + 二阶补偿
│       ├── i2c.c          ← I2C1 裸寄存器初始化
│       ├── usart.c        ← USART1 裸寄存器初始化
│       ├── stm32f1xx_it.c ← 中断服务
│       └── ...
├── Drivers/               ← HAL 库 (仅保留核心模块)
├── MDK-ARM/               ← Keil 工程
├── .eide/                 ← EIDE (VSCode) 工程
└── README.md

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages