很荣幸能够有资格参加 Let's do 2026 年第 3 期活动。我通过主控 NUCLEO-C562RE 开发板实现 LIS3DHTR数据串口发送的项目设计。

效果预览
第一步:使用STM32CubeMX2来生成一个项目。
LIS3DHTR传感器使用I2C总线读取。所以要开启I2C支持。此外我初始化了USART2来发送采集到的数据到上位机VOFA+。
第二步:参考论坛里面老师的操作方法,使用VS code,结合STM32Cube相关插件来对项目进行开发
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stepmotor.h"
#include "lis3dh_reg.h"
#include <stdio.h>
#include <math.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* LIS3DH detected by the I2C1 bus scan at 0x32/0x33 (8-bit format),
i.e. 7-bit address 0x19 -> SA0 is tied HIGH on this module.
The HAL I2C API takes the 8-bit form (7-bit address << 1), so clear the
R/W bit of the ST driver constant (LIS3DH_I2C_ADD_H = 0x33 -> 0x32). */
#define LIS3DH_I2C_ADDR (LIS3DH_I2C_ADD_H & 0xFEU)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static stmdev_ctx_t lis3dh_ctx;
/* Private functions prototype -----------------------------------------------*/
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: Retarget printf to USART2 (called by newlib _write()).
*/
int __io_putchar(int ch)
{
hal_uart_handle_t *huart = mx_usart2_uart_gethandle();
uint8_t data = (uint8_t)ch;
(void)HAL_UART_Transmit(huart, &data, 1U, 100U);
return ch;
}
/**
* brief: I2C write callback for the LIS3DH driver.
*/
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 |= 0x80U; /* LIS3DH auto-increment flag (needed for multi-byte transfer) */
if (HAL_I2C_MASTER_MemWrite(hi2c, LIS3DH_I2C_ADDR, reg, HAL_I2C_MEM_ADDR_8BIT,
(const uint8_t *)buf, len, 1000U) != HAL_OK)
{
return -1;
}
return 0;
}
/**
* brief: I2C read callback for the LIS3DH driver.
*/
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 |= 0x80U; /* Multi-byte read with address auto-increment (needed for 6-byte accel read) */
status = HAL_I2C_MASTER_MemRead(hi2c, LIS3DH_I2C_ADDR, reg, HAL_I2C_MEM_ADDR_8BIT,
buf, len, 1000U);
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: Delay callback for the LIS3DH driver.
*/
static void platform_delay(uint32_t millisec)
{
HAL_Delay(millisec);
}
/**
* brief: The application entry point.
* retval: none but we specify int to comply with C99 standard
*/
int main(void)
{
uint8_t whoami = 0U;
uint8_t lis3dh_ready = 0U;
int16_t acc_raw[3];
float acc_mg[3];
float acc_g[3];
float pitch_deg;
float roll_deg;
/** System Init: this code placed in targets folder initializes your system.
* It calls the initialization (and sets the initial configuration) of the peripherals.
* You can use STM32CubeMX to generate and call this code or not in this project.
* It also contains the HAL initialization and the initial clock configuration.
*/
if (mx_system_init() != SYSTEM_OK)
{
return (-1);
}
else
{
/* 初始化步进电机 */
stepper_init();
/* 填充 LIS3DH 驱动上下文,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();
/* 读取 WHO_AM_I,验证 I2C 通信 */
if (lis3dh_device_id_get(&lis3dh_ctx, &whoami) != 0)
{
printf("LIS3DH read WHO_AM_I failed!\r\n");
}
else
{
printf("LIS3DH WHO_AM_I = 0x%02X\r\n", whoami);
if (whoami != LIS3DH_ID)
{
printf("LIS3DH ID mismatch!\r\n");
}
else
{
/* 配置 LIS3DH */
(void)lis3dh_block_data_update_set(&lis3dh_ctx, PROPERTY_ENABLE); /* BDU */
(void)lis3dh_full_scale_set(&lis3dh_ctx, LIS3DH_2g); /* ±2g */
(void)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");
}
else
{
printf("LIS3DH initialized OK!\r\n");
lis3dh_ready = 1U;
}
}
}
while (1)
{
if (lis3dh_ready != 0U)
{
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("%.3f,%.3f,%.3f,%.2f,%.2f\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(10); /* 10ms -> ~100Hz,与 LIS3DH ODR 匹配 */
}
}
} /* end main */可以让AI辅助编写驱动,自己修改主函数中的调用,然后就可以在上位机读取到三轴的加速度信息了。
我要赚赏金
