1. 项目概述
在无人机飞控开发领域,STM32F103作为经典Cortex-M3内核MCU,以其出色的实时性和丰富的外设资源成为入门级飞控的首选平台。这个项目将带您从零开始构建基于MPU6050六轴传感器的姿态解算系统,并实现PWM信号输出控制电机的基本飞控功能。
我曾用这套方案为学校航模队开发过训练用飞控板,实测在室内悬停场景下能达到±2°的姿态控制精度。相比市面上动辄上千元的商业飞控,自制方案不仅成本能控制在百元以内,更重要的是能透彻理解飞控底层原理。
2. 硬件架构设计
2.1 核心器件选型
STM32F103C8T6(俗称"蓝莓派"):
- 72MHz主频满足实时控制需求
- 3个USART接口便于调试和无线通信
- 多达15个PWM输出通道(TIM1/TIM2/TIM3/TIM4)
- 内置DMA可减轻CPU负载
MPU6050模块:
- 三轴加速度计(±16g) + 三轴陀螺仪(±2000°/s)
- 内置数字运动处理器(DMP)
- I2C接口最高支持400kHz通信速率
注意:市面上MPU6050模块有5V和3.3V两种供电版本,务必确认模块电平与STM32匹配,否则需加电平转换电路。
2.2 关键电路设计
电源部分:
- 建议采用3.7V锂电池供电
- AMS1117-3.3稳压芯片为MCU和传感器供电
- 大容量滤波电容(推荐100μF+0.1μF组合)靠近MPU6050放置
信号连接:
plaintext复制MPU6050 STM32
VCC → 3.3V
GND → GND
SCL → PB6(I2C1_SCL)
SDA → PB7(I2C1_SDA)
INT → PA0(外部中断)
3. 软件架构实现
3.1 开发环境搭建
-
工具链配置:
- Keil MDK-ARM V5 + STM32F1xx_DFP
- STM32CubeMX初始化外设
- PuTTY串口调试工具
-
关键库依赖:
- STM32 HAL库(硬件抽象层)
- MPU6050官方驱动库
- DMP姿态解算库
3.2 传感器数据采集
I2C初始化配置:
c复制hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 400000; // 400kHz高速模式
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
MPU6050初始化流程:
- 复位设备(写0x6B寄存器)
- 配置陀螺仪量程(0x1B寄存器)
- 配置加速度计量程(0x1C寄存器)
- 使能DMP功能(需加载官方固件)
3.3 姿态解算实现
互补滤波算法:
c复制void ComplementaryFilter(float *pitch, float *roll)
{
// 读取原始数据
MPU6050_Read_Accel(&ax, &ay, &az);
MPU6050_Read_Gyro(&gx, &gy, &gz);
// 加速度计角度计算
acc_pitch = atan2(ay, az) * 180/PI;
acc_roll = atan2(ax, az) * 180/PI;
// 互补滤波
*pitch = 0.98*(*pitch + gy*dt) + 0.02*acc_pitch;
*roll = 0.98*(*roll + gx*dt) + 0.02*acc_roll;
}
卡尔曼滤波进阶方案:
- 状态变量:角度、角速度偏差
- 过程噪声Q和测量噪声R需要实测调整
- 推荐使用ARM CMSIS-DSP库加速矩阵运算
4. PWM输出控制
4.1 电机驱动配置
TIM1四通道PWM配置:
c复制htim1.Instance = TIM1;
htim1.Init.Prescaler = 71; // 72MHz/(71+1)=1MHz
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 19999; // 1MHz/20000=50Hz
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.Pulse = 1000; // 初始1ms脉冲
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_DISABLE;
sConfig.OCIdleState = TIM_OCIDLESTATE_RESET;
警告:电调需要特定启动序列(先给最大油门再回最低),直接输出信号可能导致电机异常启动。
4.2 混控算法实现
X型四轴混控示例:
c复制void Mixer(float throttle, float pitch, float roll, float yaw)
{
motor[0] = throttle - 0.5*pitch + 0.5*roll - yaw;
motor[1] = throttle - 0.5*pitch - 0.5*roll + yaw;
motor[2] = throttle + 0.5*pitch - 0.5*roll - yaw;
motor[3] = throttle + 0.5*pitch + 0.5*roll + yaw;
// 限幅保护
for(int i=0; i<4; i++){
motor[i] = constrain(motor[i], 1000, 2000);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1+i, motor[i]);
}
}
5. 系统调试技巧
5.1 传感器校准
-
静态校准:
- 水平放置飞控板
- 采集1000组加速度计数据取平均
- 计算零偏值写入EEPROM
-
动态校准:
- 六面旋转法校准陀螺仪
- 使用椭圆拟合补偿加速度计非线性
5.2 参数整定经验
PID调参步骤:
- 先调P(比例项)直到出现小幅振荡
- 增加D(微分项)抑制超调
- 最后加I(积分项)消除静差
- 典型初始值范围:
- Roll/Pitch:P=3.0, I=0.05, D=1.5
- Yaw:P=1.5, I=0.01, D=0.7
5.3 常见故障排查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| MPU6050无响应 | I2C地址错误 | 尝试0x68/0x69地址 |
| 姿态数据漂移 | 未校准陀螺仪 | 执行六面校准程序 |
| 电机响应迟钝 | PWM频率不对 | 检查是否为50Hz |
| 剧烈振荡 | PID参数过大 | 逐步减小P值 |
6. 进阶优化方向
-
传感器融合升级:
- 增加磁力计实现9轴融合
- 移植Mahony或Madgwick算法
-
无线通信集成:
- 通过NRF24L01实现遥控
- 添加HC-05蓝牙调试接口
-
飞行日志记录:
- 使用SPI Flash存储飞行数据
- 上位机回放分析功能
我在实际项目中发现,当PWM信号线超过15cm时容易引入干扰,建议:
- 使用双绞线传输PWM信号
- 在电调端并联104电容
- 避免信号线与电源线平行走线