【let's do|2026年第3期】加速度计
本文介绍了 Let's Do|2026年第3期 活动,使用 NUCLEO-C562RE 开发板驱动 LIS3DH 加速度传感器并 OLED 显示的项目设计,包括硬件连接、环境搭建、工程测试等流程。
项目介绍
NUCLEO-C562RE 开发板通过 IIC 通信协议读取 LIS3DH 传感器数据的项目设计。
传感器介绍、硬件连接;
传感器驱动:工程创建、参数配置、IDE 导入、代码、编译运行等;
OLED驱动:头文件、源文件、显示测试;
角度显示:关键代码、加速度数据的 OLED 显示;

LIS3DH
Grove - 三轴数字加速度计 (LIS3DHTR) 是一款低成本的三轴加速度计,属于 Grove 产品系列。
基于 LIS3DHTR 芯片,提供多种量程和接口选择。体积小巧,支持 I2C、SPI 和 ADC GPIO 接口。
这款加速度计可监测环境温度,以校正由温度引起的误差。


特性
测量范围:±2g、±4g、±8g、±16g,多种量程选择。
多种接口选项:Grove I2C 接口、SPI 接口、ADC 接口。
温度可调:能够调整和校正由温度引起的误差。
3/5V 电源供电。
规格
| 项目 | 参数 |
| 电源供电 | 3/5V |
| 接口 | I2C/SPI/GPIO ADC |
| I2C 地址 | 默认 0x19,当 SDO 引脚连接到 GND 时可更改为 0x18 |
| ADC GPIO 电源输入 | 0-3.3V |
| 中断 | 预留一个中断引脚 |
| SPI 模式设置 | 将 CS 引脚连接到 GND |
原理图


详见:LIS3DH | Seeed Studio Wiki .
传感器驱动
通过硬件 I2C 驱动 LIS3DH 模块,串口打印三轴加速度与俯仰角度数据。
硬件连接
由原理图可知,将模块的 IIC 引脚与 STM32C562RET6 的 PB6 (SCL)、PB7 (SDA) 相连;
为了使用杜邦线连接开发板引脚和 LIS3DH 模块,设计 Grove 扩展板


接线方式如下
| STM32C562RET6 | LIS3DHTR |
| Digital Pin 15 (PB6) SCL | SCL |
| Digital Pin 14 (PB7) SDA | SDA |
| GND | GND |
| 3V3 | VCC |
实物图


工程创建
打开 STM32CubeMX2 软件,从开发板新建工程;
点击左侧工具栏 Open Peripherals 按钮,展开 Connectivity ,使能 USART2 并配置为异步通信;
展开 System - GPIO ,将 USART2 对应引脚配置为 PA2 和 PA3,并使能全局中断;
进入 Peripherials 标签页,展开 Connectivity,使能 I2C1,标准速率 100kHz,7 位地址 0x19,


SCL 和 SDA 引脚分别配置为 PB6、PB7 均设置为上拉输出模式;


保存配置,生成 CMake工程;
详见:【let's_do|2026年第3期】介绍、环境搭建、工程测试 .
导入 IDE (VSCode)
打开 STM32CubeIDE 软件,依次选择 File - Import ,选择 STM32 CMake Project ,选择目标工程文件所在路径;
配置工具链,选择主控芯片型号 STM32C562RETx ;
待导入完成,点击工具栏 小锤子 按钮,编译工程,无报错。
在 IDE 项目中新建 LIS3DH 传感器驱动的头文件 lis3dh_reg.h 和源文件 lis3dh_reg.c 。
lis3dh_reg.h
#ifndef LIS3DH_REGS_H
#define LIS3DH_REGS_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stddef.h>
#include <math.h>
#ifndef DRV_BYTE_ORDER
#ifndef __BYTE_ORDER__
#define DRV_LITTLE_ENDIAN 1234
#define DRV_BIG_ENDIAN 4321
#define DRV_BYTE_ORDER DRV_LITTLE_ENDIAN
#else /* defined __BYTE_ORDER__ */
#define DRV_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
#define DRV_BIG_ENDIAN __ORDER_BIG_ENDIAN__
#define DRV_BYTE_ORDER __BYTE_ORDER__
#endif /* __BYTE_ORDER__*/
#endif /* DRV_BYTE_ORDER */
/** I2C Device Address 8 bit format if SA0=0 -> 31 if SA0=1 -> 33 **/
#define LIS3DH_I2C_ADD_L 0x31U
#define LIS3DH_I2C_ADD_H 0x33U
/** Device Identification (Who am I) **/
#define LIS3DH_ID 0x33U
typedef union
{
lis3dh_status_reg_aux_t status_reg_aux;
lis3dh_ctrl_reg0_t ctrl_reg0;
lis3dh_temp_cfg_reg_t temp_cfg_reg;
lis3dh_ctrl_reg1_t ctrl_reg1;
lis3dh_ctrl_reg2_t ctrl_reg2;
lis3dh_time_limit_t time_limit;
lis3dh_time_latency_t time_latency;
lis3dh_time_window_t time_window;
lis3dh_act_ths_t act_ths;
lis3dh_act_dur_t act_dur;
bitwise_t bitwise;
uint8_t byte;
} lis3dh_reg_t;
#ifdef __cplusplus
}
#endif
#endif /* LIS3DH_REGS_H */保存代码。
lis3dh_reg.c
#include "lis3dh_reg.h"
int32_t lis3dh_temp_status_reg_get(const stmdev_ctx_t *ctx, uint8_t *buff)
{
int32_t ret;
ret = lis3dh_read_reg(ctx, LIS3DH_STATUS_REG_AUX, buff, 1);
return ret;
}
int32_t lis3dh_temperature_raw_get(const stmdev_ctx_t *ctx, int16_t *val)
{
uint8_t buff[2];
int32_t ret;
ret = lis3dh_read_reg(ctx, LIS3DH_OUT_ADC3_L, buff, 2);
if (ret != 0) { return ret; }
*val = (int16_t)(buff[0] | ((uint16_t)buff[1] << 8));
return ret;
}
int32_t lis3dh_adc_raw_get(const stmdev_ctx_t *ctx, int16_t *val)
{
uint8_t buff[6];
int32_t ret;
ret = lis3dh_read_reg(ctx, LIS3DH_OUT_ADC1_L, buff, 6);
if (ret != 0) { return ret; }
val[0] = (int16_t)(buff[0] | ((uint16_t)buff[1] << 8));
val[1] = (int16_t)(buff[2] | ((uint16_t)buff[3] << 8));
val[2] = (int16_t)(buff[4] | ((uint16_t)buff[5] << 8));
return ret;
}保存代码。
详见:STMicroelectronics/lis3dh-pid .
CMake
打开项目的 CMakeLists.txt 文件,将新增的驱动文件 lis3dh_reg.c 添加至编译路径;
# 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
修改 main.c 文件,添加如下代码
#include "main.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "lis3dh_reg.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#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);
int _write(int file, char *ptr, int len)
{
hal_uart_handle_t *huart2 = mx_usart2_uart_gethandle();
if (huart2 != NULL)
{
HAL_UART_Transmit(huart2, ptr, len, 1000);
}
return len;
}
/**
* @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);
}
/**
* brief: The application entry point.
*/
int main(void)
{
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;
/**
System Init
*/
if (mx_system_init() != SYSTEM_OK)
{
return (-1);
}
else
{
/* 填充驱动上下文,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");
/* 主循环:读取并打印 */
while (1) {
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);
}
}
} /* end main */保存代码,编译并上传固件。
复位开发板,运行程序;
效果
重新编译工程、点击工具栏 Run 按钮,配置调试器为 ST-LINK ,运行程序;
运行串口调试软件,配置波特率等参数,打开串口;
连续接收开发板输出的字符串;


使用绘图软件显示 X、Y、Z 三轴加速度数值,以及翻滚角度的变化


OLED 驱动
使用 OLED 显示 LIS3DH 传感器数据,包括硬件连接、工程配置、驱动代码、显示测试。
硬件连接
根据原理图,选择 PA11 和 PA12 作为 I2C2 的通信引脚。


接线方式如下
| STM32C562RET6 | OLED |
| PA11 (SCL) | SCL |
| PA12 (SDA) | SDA |
| GND | GND |
| 3V3 | VCC |
实物图


工程配置
打开 STM32CubeMX2 软件,从开发板新建工程;
点击左侧工具栏 Open Peripherals 按钮,展开 Connectivity ,使能 I2C2,标准速率 100kHz,7 位地址 0x3c ;
SCL 和 SDA 引脚分别配置为 PA11、PA12 均设置为上拉输出模式;
保存配置,生成 CMake工程;
ssd1306.h
新建 OLED 驱动头文件,添加如下代码
#ifndef __SSD1306_H
#define __SSD1306_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
void WriteCmd(void);
void SSD1306_WR_CMD(uint8_t cmd);
void SSD1306_WR_DATA(uint8_t data);
void SSD1306_Init(void);
void SSD1306_Clear(void);
void SSD1306_Display_On(void);
void SSD1306_Display_Off(void);
void SSD1306_Set_Pos(uint8_t x, uint8_t y);
void SSD1306_On(void);
void SSD1306_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2, uint8_t Color_Turn);
void SSD1306_ShowDecimal(uint8_t x,uint8_t y,float num,uint8_t z_len,uint8_t f_len,uint8_t size2, uint8_t Color_Turn);
void SSD1306_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size, uint8_t Color_Turn);
void SSD1306_ShowString(uint8_t x,uint8_t y,const char *chr,uint8_t Char_Size, uint8_t Color_Turn);
void SSD1306_ShowCHinese(uint8_t x,uint8_t y,uint8_t no, uint8_t Color_Turn);
void SSD1306_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t * BMP,uint8_t Color_Turn);
void SSD1306_DrawGIF(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t k, int m, unsigned char GIF[][m]);
void SSD1306_HorizontalShift(uint8_t direction);
void SSD1306_Some_HorizontalShift(uint8_t direction,uint8_t start,uint8_t end);
void SSD1306_VerticalAndHorizontalShift(uint8_t direction);
void SSD1306_DisplayMode(uint8_t mode);
void SSD1306_IntensityControl(uint8_t intensity);
void SSD1306_ClearLinePart(uint8_t line, uint8_t start, uint8_t end);
#ifdef __cplusplus
}
#endif
#endif /* __SSD1306_H */保存代码。
ssd1306.c
新建 OLED 驱动源文件,添加如下代码
#include "ssd1306.h"
#include "main.h"
#include "mx_i2c2.h"
#include "oledfont.h"
void WriteCmd(void)
{
uint8_t i = 0;
for(i=0; i<27; i++)
{
HAL_I2C_MASTER_MemWrite(mx_i2c2_i2c_gethandle(), 0x78, 0x00,
HAL_I2C_MEM_ADDR_8BIT, CMD_Data + i, 1, 100);
}
}
/**
* @function: void SSD1306_WR_CMD(uint8_t cmd)
* @description: 向设备写控制命令
* @param {uint8_t} cmd 芯片手册规定的命令
* @return {*}
*/
void SSD1306_WR_CMD(uint8_t cmd)
{
HAL_I2C_MASTER_MemWrite(mx_i2c2_i2c_gethandle(), 0x78, 0x00,
HAL_I2C_MEM_ADDR_8BIT, &cmd, 1, 100);
}
/**
* @function: void SSD1306_WR_DATA(uint8_t data)
* @description: 向设备写控制数据
* @param {uint8_t} data 数据
* @return {*}
*/
void SSD1306_WR_DATA(uint8_t data)
{
HAL_I2C_MASTER_MemWrite(mx_i2c2_i2c_gethandle(), 0x78, 0x40,
HAL_I2C_MEM_ADDR_8BIT, &data, 1, 100);
}具体函数定义详见:【功率监测与控制系统DIY活动过程贴】OLED显示 .
oledfont.h
新建 OLED 驱动的字体头文件,添加如下代码
#ifndef __OLEDFONT_H
#define __OLEDFONT_H
#include <stdint.h>
//8*6 ASCII字符集点阵 static const uint8_t Font6x8[][6] = {};
const unsigned char F6x8[][6] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
// …… ……
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
};
//16*8 ASCII字符集点阵 static const uint8_t Font8x16[][16]={};
const unsigned char Font8x16[]=
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//sp /0
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! /1
// …… ……
0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+
0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x00,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x00 // ~ /94
};
const unsigned char Hzk[][32]=
{
// 加(0) 速(1) 度(2) 计(3) 俯(4) 仰(5) 翻(6) 横(7) 滚(8) 偏(9) 航(10) 向(11) 角(12)
{0x10,0x10,0x10,0xFF,0x10,0x10,0xF0,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x00},
{0x80,0x40,0x30,0x0F,0x40,0x80,0x7F,0x00,0x00,0x7F,0x20,0x20,0x20,0x7F,0x00,0x00},/*"加",0*/
{0x40,0x40,0x42,0xCC,0x00,0x04,0xF4,0x94,0x94,0xFF,0x94,0x94,0xF4,0x04,0x00,0x00},
{0x00,0x40,0x20,0x1F,0x20,0x48,0x44,0x42,0x41,0x5F,0x41,0x42,0x44,0x48,0x40,0x00},/*"速",1*/
/* (16 X 16 , 宋体 )*/
};
#endif取模方式详见:【功率监测与控制系统DIY活动过程贴】OLED显示 .
字符在线取模:在线文字取模工具 .
bmp.h
新建 OLED 驱动的图片头文件,添加如下代码
#ifndef BMP_H_
#define BMP_H_
const unsigned char BMP1[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
// …… ……
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
#endif /* BMP_H_ */保存代码。
main.c
修改主函数文件,关键代码如下
#include "main.h"
#include "ssd1306.h"
#include "bmp.h"
int main(void)
{
if (mx_system_init() != SYSTEM_OK)
{
return (-1);
}
else
{
/* 初始化 OLED */
SSD1306_Init();
/* 清屏并显示 */
SSD1306_Clear();
SSD1306_ShowString(25, 0, "OLED TEST", 16, 1);
SSD1306_ShowString(0, 2, "6x8 Font~", 12, 0);
SSD1306_ShowString(0, 3, "8x16 Font~", 16, 0);
SSD1306_ShowNum(0, 5, 1234567890, 10, 16, 0);
HAL_Delay(1000);
/* 图片显示 */
SSD1306_DrawBMP(0, 0, 128, 8, BMP1, 0);
HAL_Delay(1000);
/* 显示汉字 */
SSD1306_Clear();
/* 1st row */
SSD1306_ShowString(0,0,"DIY",16,1);
SSD1306_ShowCHinese(24,0,0,1); // 加
SSD1306_ShowCHinese(39,0,1,1); // 速
SSD1306_ShowCHinese(54,0,2,1); // 度
SSD1306_ShowCHinese(69,0,3,1); // 计
/* 2nd row */
SSD1306_ShowString(0,2,"X:",16,0);
SSD1306_ShowString(44,2,"Y:",16,0);
SSD1306_ShowString(88,2,"Z:",16,0);
/* 3rd row */
SSD1306_ShowCHinese(0,4,4,0); // 俯
SSD1306_ShowCHinese(15,4,5,0); // 仰
SSD1306_ShowChar(30,4,':',16,0); // :
/* 4th row */
SSD1306_ShowCHinese(0,6,6,0); // 翻
SSD1306_ShowCHinese(15,6,8,0); // 滚
SSD1306_ShowChar(30,6,':',16,0); // :
HAL_Delay(1000);
while (1) {}
}
} /* end main */保存代码。
效果
编译固件,运行工程;
OLED 显示文字、数字、图片等;


角度显示
进一步通过 OLED 实现倾斜角度和加速度的实时显示。
流程图

硬件连接
将 LIS3DH 传感器模块与开发板 I2C1 引脚对应连接;
将 OLED 模块与开发板的 I2C2 引脚对应连接。


代码
修改 main.c 代码如下
#include "main.h"
#include "ssd1306.h"
#include "bmp.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "lis3dh_reg.h"
int main(void){
if (mx_system_init() != SYSTEM_OK){
return (-1);
}
else{
/* 初始化 OLED */
SSD1306_Init();
/* 显示文本 */
SSD1306_Clear();
/* 1st row */
/* 2nd row */
/* 3rd row */
/* 4th row */
/* 初始化 LIS3DH */
printf("LIS3DH initialized OK!\r\n");
while (1) {
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);
}
SSD1306_ClearLinePart(2, 17, 43);
SSD1306_ClearLinePart(2, 61, 87);
SSD1306_ClearLinePart(2, 105, 127);
SSD1306_ShowDecimal(17,2,fabsf(acc_g[0]),1,1,16,0);
SSD1306_ShowDecimal(61,2,fabsf(acc_g[1]),1,1,16,0);
SSD1306_ShowDecimal(105,2,fabsf(acc_g[2]),1,1,16,0);
SSD1306_ClearLinePart(4, 47, 127);
SSD1306_ClearLinePart(5, 47, 127);
SSD1306_ShowDecimal(45,4,pitch_deg,2,2,16,0);
SSD1306_ClearLinePart(6, 47, 127);
SSD1306_ClearLinePart(7, 47, 127);
SSD1306_ShowDecimal(45,6,roll_deg,2,2,16,0);
HAL_Delay(100);
}
}
} /* end main */保存代码。
效果
重新编译固件、运行程序;
OLED 显示实时三轴加速度数值;


同时串口打印加速度及俯仰倾斜角度。
总结
本文介绍了 Let's Do|2026年第3期 活动,使用 NUCLEO-C562RE 开发板驱动 LIS3DH 加速度传感器并 OLED 显示的项目设计,包括硬件连接、环境搭建、工程测试等流程,为后续项目的研究探索提供了参考。
我要赚赏金
