本次活动中使用Grove - 三轴数字加速度计 (LIS3DHTR)采集加速度信息,结合之前的工程在NUCLEO-C562RE开发板上实现串口打印,实现采集LIS3DHTR的加速度信息,
1、硬件配置Grove - 三轴数字加速度计 (LIS3DHTR)的主要特性如下
核心芯片:LIS3DHTR(ST 意法半导体),属于超低功耗“nano”系列。
测量量程:可通过软件动态选择 ±2g、±4g、±8g、±16g。
接口选项:模块原生支持 Grove I2C 接口
I2C 地址:默认为 0x19。如果模块上的 SDO 引脚接地,地址会变为 0x18,方便总线上挂载多个设备。
供电与温度:支持 3.3V / 5V 供电,工作温度范围 -40°C 至 +85°C,并内置温度传感器可用于补偿。
连接开发板的Arduino转接口到Arduino Grove 转接板,三轴数字加速度计 (LIS3DHTR)连接到Arduino Grove转接板的I2C接口,实现开发板与三轴数字加速度计的连接。硬件连接图如下。

查看NUCLEO-C562RE开发板的原理图,I2C接口的引脚为:SCL-PB6,SDA-PB7

CubeMX2配置以上引脚为I2C功能

选择I2C1外设的工作模式为I2C

设置I2C外设的通讯速率为100kHz,I2C1的首选外设地址为0x19

设置I2C外设的引脚为上拉

保存并生成工程代码。
3、LIS3DH 传感器驱动ST官方提供该传感器的驱动,
https://github.com/STMicroelectronics/lis3dh-pid/
下载代码仓库将其中的lis3dh_reg.c/h文件添加到工程中。STM32 VSCode工程是由CMake管理的,在顶层的CMakeList.txt文件中添加lis3dh_reg.c/h的信息
# Stubs to be able to add compiler flag overrides, e.g. -Os
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
# Add additional source files here
lis3dh_reg.c
)
# 添加浮点打印配置
target_link_options(${CMAKE_PROJECT_NAME} PUBLIC
# Add additional linker flags here
-u _printf_float
)
main.c中添加驱动相关的头文件
#include <math.h> #include "lis3dh_reg.h"
定义LIS3DH 三轴数字加速度计相关的宏定义、变量以及函数声明,用于读取传感器的数据
#define LIS3DH_I2C_ADDR (LIS3DH_I2C_ADD_H & 0xFEU) static stmdev_ctx_t lis3dh_ctx; uint8_t whoami = 0; int16_t acc_raw[3]; float_t acc_mg[3]; float_t acc_g[3]; float_t pitch_deg; float_t roll_deg; static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *buf, uint16_t len); static int32_t platform_read(void *handle, uint8_t reg, uint8_t *buf, uint16_t len); static void platform_delay(uint32_t millisec);
传感器读懂的写数据的的回调函数定义如下
/**
* @brief I2C 写回调(适配 STM32C5 的 HAL_I2C_MASTER_MemWrite)
*/
static int32_t platform_write(void *handle, uint8_t reg, const uint8_t *buf, uint16_t len)
{
hal_i2c_handle_t *hi2c = (hal_i2c_handle_t *)handle;
reg |= 0x80; /* LIS3DH auto-increment 标志,多字节写使能 */
if (HAL_I2C_MASTER_MemWrite(hi2c, LIS3DH_I2C_ADDR, reg,
HAL_I2C_MEM_ADDR_8BIT, (uint8_t *)buf, len, 1000) != HAL_OK)
{
return -1;
}
return 0;
}传感器驱动的读数据的回调函数实现如下
/**
* @brief I2C 读回调(适配 STM32C5 的 HAL_I2C_MASTER_MemRead)
*/
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *buf, uint16_t len)
{
hal_i2c_handle_t *hi2c = (hal_i2c_handle_t *)handle;
hal_status_t status;
reg |= 0x80; /* 多字节读使能自动递增(读 6 字节加速度必须) */
status = HAL_I2C_MASTER_MemRead(hi2c, LIS3DH_I2C_ADDR, reg,
HAL_I2C_MEM_ADDR_8BIT, buf, len, 1000);
if (status != HAL_OK)
{
printf("LIS3DH I2C read error: status=0x%08lX, error=0x%08lX, addr=0x%02X, reg=0x%02X\r\n",
(unsigned long)status, (unsigned long)hi2c->last_error_codes,
(unsigned int)LIS3DH_I2C_ADDR, (unsigned int)reg);
return -1;
}
return 0;
}传感器驱动的延时回调函数如下
/**
* @brief 延时回调
*/
static void platform_delay(uint32_t millisec)
{
HAL_Delay(millisec);
}main函数中注册上述回调函数到传感器的驱动接口中,通过获取传感器的ID验证通讯正常,配置传感器工作在±2g,100Hz的配置下。
/* 填充驱动上下文,handle 直接指向 I2C1 */
lis3dh_ctx.write_reg = platform_write;
lis3dh_ctx.read_reg = platform_read;
lis3dh_ctx.mdelay = platform_delay;
lis3dh_ctx.handle = mx_i2c1_i2c_gethandle(); /* 或 &hi2c1 */
/* 读取 WHO_AM_I,验证 I2C 通信 */
if (lis3dh_device_id_get(&lis3dh_ctx, &whoami) != 0)
{
printf("LIS3DH read WHO_AM_I failed!\r\n");
while (1);
}
printf("LIS3DH WHO_AM_I = 0x%02X\r\n", whoami);
if (whoami != LIS3DH_ID)
{
printf("LIS3DH ID mismatch!\r\n");
while (1);
}
/* 配置 LIS3DH */
lis3dh_block_data_update_set(&lis3dh_ctx, PROPERTY_ENABLE); /* BDU */
lis3dh_full_scale_set(&lis3dh_ctx, LIS3DH_2g); /* ±2g */
lis3dh_data_rate_set(&lis3dh_ctx, LIS3DH_ODR_100Hz); /* 100Hz */
if (lis3dh_operating_mode_set(&lis3dh_ctx, LIS3DH_HR_12bit) != 0)
{
printf("LIS3DH high-resolution mode configuration failed!\r\n");
while (1);
}
printf("LIS3DH initialized OK!\r\n");main函数的主循环中添加以下代码实现循环读取传感器数据的功能。
if (lis3dh_acceleration_raw_get(&lis3dh_ctx, acc_raw) == 0)
{
/* 配置为高分辨率(HR_12bit)模式,±2g 用 hr 换算 */
acc_mg[0] = lis3dh_from_fs2_hr_to_mg(acc_raw[0]);
acc_mg[1] = lis3dh_from_fs2_hr_to_mg(acc_raw[1]);
acc_mg[2] = lis3dh_from_fs2_hr_to_mg(acc_raw[2]);
acc_g[0] = acc_mg[0] / 1000.0f;
acc_g[1] = acc_mg[1] / 1000.0f;
acc_g[2] = acc_mg[2] / 1000.0f;
roll_deg = atan2f(acc_mg[1], acc_mg[2]) * 57.3f;
pitch_deg = atan2f(-acc_mg[0],
sqrtf(acc_mg[1] * acc_mg[1] + acc_mg[2] * acc_mg[2])) * 57.3f;
printf("x=%.3f y=%.3f z=%.3f | pitch=%.2f roll=%.2f\r\n",
(double)acc_g[0], (double)acc_g[1], (double)acc_g[2],
(double)pitch_deg, (double)roll_deg);
}
else
{
printf("Read LIS3DH data failed!\r\n");
}
HAL_Delay(100);编译并烧录程序到开发板,连接开发板到串口,获取到传感器数据如下

我要赚赏金
