1. 前言
在物联网和嵌入式开发中,加速度计是实现姿态检测、抬腕亮屏、震动报警等功能的核心传感器。本文将分享如何在 STM32H533RE 开发板上,通过 I2C 总线驱动 LIS3DH 三轴加速度计,并解决开发过程中最常见的“通讯失败”问题。
2. 硬件连接
LIS3DH 模块通常通过 I2C 接口通讯,请确保接线正确:
VCC -> 3.3V
GND -> GND
SCL -> 连接至单片机 I2C_SCL 引脚
SDA -> 连接至单片机 I2C_SDA 引脚
注意:NUCLEO-H533RE 的引脚映射非常重要。如果使用 CubeMX 默认配置,I2C1 可能位于 PB6/PB7;若使用 Arduino 接口,请务必在 CubeMX 中将对应的 I2C1_SCL 和 I2C1_SDA 重新映射到目标引脚。
3. 核心驱动逻辑
驱动 LIS3DH 的本质是向其 I2C 地址发送寄存器指令,并获取 X, Y, Z 三轴的原始数据。
3.1 关键驱动文件
你需要准备两个核心文件:
lis3dh.h:定义寄存器地址(如 WHO_AM_I 地址为 0x0F,数据输出地址为 0x28-0x2D)。
lis3dh.c:实现 LIS3DH_Init() 和 LIS3DH_ReadRaw() 函数。
3.2 驱动代码片段
在 main.c 中调用初始化和读取逻辑:
/* 初始化传感器 */ret = LIS3DH_Init(&hi2c1, 0x18); // 尝试 0x18 地址,若无响应尝试 0x19if (ret == LIS3DH_OK) { printf("LIS3DH 初始化成功!\r\n");} else { printf("LIS3DH 通讯失败,请检查接线或地址!\r\n");}/* 循环读取数据 */if (LIS3DH_DataReady(&ready) && ready) { LIS3DH_ReadRaw(&raw); printf("X=%6d Y=%6d Z=%6d\r\n", raw.x, raw.y, raw.z);}4. 开发避坑指南(干货)
4.1 "I2C no ACK" 报错(最常见)
如果串口输出 LIS3DH init FAIL: I2C no ACK,说明单片机没找到传感器:
检查引脚配置:使用 CubeMX 检查 I2C1 的 GPIO 设置,确保引脚编号与硬件接线一致。
软件开启上拉:在 i2c.c 的 HAL_I2C_MspInit 中,将 GPIO_InitStruct.Pull 改为 GPIO_PULLUP。
尝试更换地址:LIS3DH 根据 SDO/SA0 引脚电平,地址可能是 0x18 或 0x19,建议在代码里写一个自动 fallback。
4.2 串口没输出/乱码
勾选 MicroLIB:在 Keil 的 Options for Target -> Target 选项卡中,必须勾选 Use MicroLIB,否则 printf 函数无法生效。
初始化顺序:确保 printf 之前已经执行了 BSP_COM_Init(或者你自己配置的 UART_Init)。
4.3 浮点数打印导致程序卡死
在 MDK 环境中,使用 %f 打印浮点数会消耗大量资源并需要特殊的库支持。建议在开发初期将原始数据 (int16_t) 直接转为 int32_t 打印,不仅速度快,还不容易导致堆栈溢出。
5. 总结
驱动传感器的关键在于底层总线(I2C)的调通。一旦 WHO_AM_I 寄存器返回了正确的值(0x33),后续的姿态解算和中断配置就只是顺水推舟了。
我要赚赏金
