1. 项目概述
这个车载振动曲线摆件是我最近完成的一个有趣的小项目,它能实时显示汽车行驶过程中的振动情况。核心思路很简单:用MPU6050传感器采集车辆振动数据,通过STM32F103C8T6单片机处理,最后在迪文串口屏上动态显示振动曲线。
提示:这个项目特别适合有一定STM32基础的开发者练手,涉及传感器数据采集、串口通信、GUI显示等多个嵌入式开发核心技能点。
我选择STM32F103C8T6作为主控,主要考虑三点:一是性价比高(某宝10元左右);二是资源足够(72MHz主频,20KB RAM);三是生态完善(各种库和资料齐全)。MPU6050则是目前最常用的6轴运动传感器,价格不到10元,精度完全够用。
2. 硬件设计与选型
2.1 核心器件选型解析
主控芯片:STM32F103C8T6(Cortex-M3内核)
- 工作电压:2.0-3.6V(需LDO降压)
- 外设资源:2个SPI、3个USART、2个I2C
- 开发环境:Keil MDK或STM32CubeIDE
运动传感器:MPU6050(国产替代型号)
- 测量范围:±2g/±4g/±8g/±16g可调
- 通信接口:I2C(400kHz快速模式)
- 特别注意:国产芯片ID为0x70(原装为0x68)
显示屏:迪文T5L系列串口屏
- 分辨率:480×272
- 通信协议:自定义串口协议
- 开发工具:DGUS_V7648配置软件
2.2 电路设计要点
电源部分采用车载USB 5V输入,通过AMS1117-3.3稳压到3.3V。关键设计细节:
- MPU6050的VCC需接3.3V(不能接5V!)
- I2C总线加上拉电阻(4.7kΩ)
- 串口屏TX接STM32的PA10(RX),RX接PA9(TX)
- 所有数字信号线建议加100Ω电阻做阻抗匹配
原理图中几个容易出错的地方:
- MPU6050的AD0引脚需接地(地址位)
- 串口屏的5V供电要单独走线(避免压降)
- STM32的NRST复位电路不能省略
3. 软件实现详解
3.1 MPU6050数据采集
使用HAL库开发时,关键初始化代码如下:
c复制// I2C初始化
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 400000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
HAL_I2C_Init(&hi2c1);
// MPU6050初始化
uint8_t check_id = 0;
HAL_I2C_Mem_Read(&hi2c1, 0x70<<1, 0x75, 1, &check_id, 1, 100);
if(check_id != 0x70) Error_Handler(); // 国产芯片校验
uint8_t init_data[2] = {0x6B, 0x00}; // 退出睡眠模式
HAL_I2C_Master_Transmit(&hi2c1, 0x70<<1, init_data, 2, 100);
数据读取流程:
- 先读取加速度计原始值(0x3B~0x40寄存器)
- 转换为实际加速度值(根据量程±2g计算)
- 低通滤波处理(简易移动平均滤波)
c复制#define FILTER_NUM 5
float filter_buf[FILTER_NUM] = {0};
float mpu_filter(float new_val) {
static uint8_t idx = 0;
filter_buf[idx++] = new_val;
if(idx >= FILTER_NUM) idx = 0;
float sum = 0;
for(uint8_t i=0; i<FILTER_NUM; i++) {
sum += filter_buf[i];
}
return sum/FILTER_NUM;
}
3.2 迪文屏曲线显示实现
迪文屏的曲线显示需要按照特定协议发送数据帧。核心指令格式:
| 指令头 | 曲线ID | 数据长度 | 数据内容 | 校验和 |
|---|---|---|---|---|
| 0x5A 0xA5 | 0x01 | 0x0002 | 加速度值 | 自动计算 |
实际代码实现:
c复制void DGUS_SendCurveData(uint8_t ch, int16_t val) {
uint8_t cmd[7] = {0x5A, 0xA5, 0x01, 0x00, 0x02};
val = (val + 2000) * 100 / 4000; // 归一化到0-100
cmd[5] = (uint8_t)(val >> 8);
cmd[6] = (uint8_t)val;
HAL_UART_Transmit(&huart1, cmd, 7, 100);
}
注意:迪文屏的Y轴坐标是向下增长的,需要做数值反转。建议发送前将加速度值映射到0-100范围。
4. 系统集成与调试
4.1 硬件组装要点
- 焊接顺序建议:电源电路→MCU最小系统→传感器→显示屏接口
- MPU6050安装方向:芯片正面朝上,Z轴垂直PCB板
- 结构固定:使用3M双面胶将PCB固定在摆件底座
- 线材选择:显示屏排线建议用FFC软排线(长度不超过15cm)
4.2 软件调试技巧
常见问题1:MPU6050读取数据全为0
- 检查I2C地址是否正确(国产0x70)
- 测量SCL/SDA波形(应有400kHz方波)
- 确认VCC电压(3.3V±0.1V)
常见问题2:曲线显示跳动剧烈
- 增加软件滤波(前文示例代码)
- 降低采样频率(建议50-100Hz)
- 检查电源纹波(示波器观察3.3V)
常见问题3:显示屏无反应
- 确认波特率(迪文屏默认115200)
- 检查接线(TX/RX交叉连接)
- 发送测试指令(如清屏命令)
5. 性能优化建议
5.1 采样率优化
默认配置下,MPU6050输出速率1kHz,但实际只需要50Hz左右。可通过配置寄存器降低采样率:
c复制uint8_t smplrt_div = 19; // 1kHz/(1+19)=50Hz
HAL_I2C_Mem_Write(&hi2c1, 0x70<<1, 0x19, 1, &smplrt_div, 1, 100);
5.2 显示效果增强
在迪文屏配置工具中,可以:
- 设置曲线颜色渐变
- 添加背景网格线
- 配置历史轨迹保留时间
- 增加峰值标记功能
5.3 功耗控制
虽然车载供电无需考虑功耗,但优化后可用充电宝供电:
- 降低MCU主频到48MHz
- 关闭不用的外设时钟
- 设置MPU6050为循环模式
- 显示屏亮度调至70%
6. 扩展应用方向
这个基础框架可以衍生出多种实用功能:
- 驾驶行为分析:通过振动频谱识别急加速/急刹车
- 路况监测:建立振动特征库判断路面状况
- 车辆健康诊断:长期记录振动数据发现悬架异常
- 互动艺术装置:将振动数据转化为灯光/音乐效果
我在实际测试中发现,不同车型的振动特征差异明显。SUV在颠簸路面的Z轴加速度可达±1.5g,而轿车通常不超过±0.8g。这个现象可以用来做车型识别的小实验。
