标题:
STM32F103ZE+mpu6050+hmc5883L通过卡尔曼滤波串口输出姿态角,数据经过融合
[打印本页]
作者:
461534727
时间:
2019-7-10 10:44
标题:
STM32F103ZE+mpu6050+hmc5883L通过卡尔曼滤波串口输出姿态角,数据经过融合
基于STM32F103ZE+mpu6050+hmc5883L通过卡尔曼滤波串口输出姿态角,数据经过融合,Z无漂移,绝对指向
单片机源程序如下:
/* main.c file
功能:
1.初始化各个传感器,
2.运行姿态解算和高度测量
3.将解算的姿态和各个传感器的输出上传到 MiniIMU AHRS 测试软件
4.响应 PC发送的命令
------------------------------------
*/
#include "common.h" //包含所有的驱动 头文件
//上传数据的状态机
#define REIMU 0x01 //上传解算的姿态数据
#define REMOV 0x02 //上传传感器的输出
#define REHMC 0x03 //上传磁力计的标定值
#define Upload_Speed 15 //数据上传速度 单位 Hz
#define upload_time (1000000/Upload_Speed)/2 //计算上传的时间。单位为us
int16_t ax, ay, az;
int16_t gx, gy, gz;
int16_t hx, hy, hz;
int32_t Temperature = 0, Pressure = 0, Altitude = 0;
uint32_t system_micrsecond;
int16_t hmcvalue[3];
u8 state= REIMU; //发送特定帧 的状态机
/**************************实现函数********************************************
*函数原型: int main(void)
*功 能: 主程序
*******************************************************************************/
int main(void)
{
int16_t Math_hz=0;
unsigned char PC_comm; //PC 命令关键字节
float ypr[3]; // yaw pitch roll
/* 配置系统时钟为72M 使用外部8M晶体+PLL*/
SystemInit();
delay_init(72); //延时初始化
Initial_LED_GPIO(); //初始化STM32-SDK板子上的LED接口
Initial_PWMLED();
Initial_UART1(115200L);
Initial_UART2(115200L);
IIC_Init(); //初始化I2C接口
delay_ms(300); //等待器件上电
//UART1_Put_String("Initialize...\r\n");
AHRS_init(); //初始化IMU和传感器
system_micrsecond=micros();
while(1){ //主循环
//delay_ms(1); //延时,不要算那么快。
AHRS_getYawPitchRoll(ypr); //姿态更新
printf("%f %f %f\r\n",ypr[1],ypr[2],ypr[0]);
Math_hz++; //解算次数 ++
BMP180_Routing(); //处理BMP018 事务 开启转换和读取结果将在这个子程序中进行
//-------------上位机------------------------------
//是否到了更新 上位机的时间了?
if((micros()-system_micrsecond)>upload_time){
switch(state){
case REIMU:
BMP180_getTemperat(&Temperature); //读取最近的温度值
BMP180_getPress(&Pressure); //读取最近的气压测量值
BMP180_getAlt(&Altitude); //读取相对高度
//UART1_ReportIMU((int16_t)(ypr[0]*10.0),(int16_t)(ypr[1]*10.0),
//(int16_t)(ypr[2]*10.0),Altitude/10,Temperature,Pressure/10,Math_hz*16);
//UART2_ReportIMU((int16_t)(ypr[0]*10.0),(int16_t)(ypr[1]*10.0),
//(int16_t)(ypr[2]*10.0),Altitude/10,Temperature,Pressure/10,Math_hz*Upload_Speed);
Math_hz=0;
state = REMOV; //更改状态。
break;
case REMOV:
MPU6050_getlastMotion6(&ax, &ay, &az, &gx, &gy, &gz);
HMC58X3_getlastValues(&hx,&hy,&hz);
//UART1_ReportMotion(ax,ay,az,gx,gy,gz,hx,hy,hz);
//UART2_ReportMotion(ax,ay,az,gx,gy,gz,hx,hy,hz);
state = REIMU;
break;
default:
state = REIMU;
break;
}//switch(state)
system_micrsecond=micros(); //取系统时间 单位 us
LED_Change(); //LED1改变亮度
}
//--------------------------------------------------
//处理PC发送来的命令
if((PC_comm=UART2_CommandRoute())!=0xff)
{
switch(PC_comm){ //检查命令标识
case Gyro_init: MPU6050_InitGyro_Offset(); break; //读取陀螺仪零偏
case High_init: BMP180_ResetAlt(0); break; //气压高度 清零
}
}// 处理PC 发送的命令
}//主循环 while(1) 结束
} //main
//------------------End of File----------------------------
复制代码
所有资料51hei提供下载:
Kalman_AHRS.7z
(308.96 KB, 下载次数: 298)
2019-7-10 19:14 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
wuhuojian
时间:
2019-7-24 18:38
大神为什么我下载你的程序烧录进32单片机读取的YAW水平转动没变化的1,维持在135度左右,roll和pitch翻转的时候正常变化,而YAW角度在翻转的时候也才有变化
作者:
wuhuojian
时间:
2019-7-24 18:39
楼主,为什么YAW水平转动数据没变化的?
作者:
wuhuojian
时间:
2019-7-25 10:07
wuhuojian 发表于 2019-7-24 18:39
楼主,为什么YAW水平转动数据没变化的?
找到问题了,指南针的线短路了,但旋转时候发现水平方向的角度并不均匀,不知道是不是HMC5883没校准的问题
作者:
wuhuojian
时间:
2019-7-25 17:18
YAW的数据还是会很缓慢地漂移,大概半个小时差一度左右,怎么解决呢,楼主
作者:
wulingqing
时间:
2019-7-25 17:50
这个实用呀,好好学习。点赞点赞点赞
作者:
wenqian
时间:
2020-2-24 23:00
这个真的厉害 谢谢大神
作者:
43210
时间:
2020-5-13 12:21
请问这个程序中有原理图呢?
作者:
43210
时间:
2020-5-13 12:37
请问里面有原理图吗?
作者:
weskyfly
时间:
2020-5-14 16:20
可以姿态解算,但是不知道为什么,用起来完全不行。整个姿态角的误差特别大。不知是什么原因?
作者:
喵喵小公举
时间:
2020-7-12 16:47
这没有看到用Kalman滤波啊,用的是互补滤波求解四元素,然后反求欧拉角。。。。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1