標(biāo)題:
stm32f103rct6卡爾曼濾波源碼
[打印本頁(yè)]
作者:
xcj666
時(shí)間:
2018-5-5 23:00
標(biāo)題:
stm32f103rct6卡爾曼濾波源碼
卡爾曼濾波源碼
以stm32f103rct6為例
測(cè)試串口通信數(shù)據(jù)
MPU數(shù)據(jù)進(jìn)行處理
檢測(cè)X軸加速度,Y軸角速度
參考網(wǎng)上例程
單片機(jī)源程序如下:
#include "stm32f10x.h"
#include <stdio.h>
#include "delay.h"
#include "sys.h"
#include "Usart.h"
#include "MPU6050.h"
//******角度參數(shù)************
float Gyro_y; //Y軸陀螺儀數(shù)據(jù)暫存
float Angle_gy; //由角速度計(jì)算的傾斜角度
float Accel_x; //X軸加速度值暫存
float Angle_ax; //由加速度計(jì)算的傾斜角度
float Angle; //最終測(cè)量角度
void TIM2_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定義一個(gè)定時(shí)器結(jié)構(gòu)體變量
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能定時(shí)器2
TIM_TimeBaseStructure.TIM_Period = (10000 - 1); //計(jì)數(shù)100次,因?yàn)閺?開(kāi)始,所以減1
TIM_TimeBaseStructure.TIM_Prescaler = (72 - 1); //時(shí)鐘72分頻,因?yàn)?不分頻,所以減1
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 使用的采樣頻率之間的分頻比例
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計(jì)數(shù)
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定時(shí)器2
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除定時(shí)器2中斷標(biāo)志位
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //打開(kāi)定時(shí)器2中斷
TIM_Cmd(TIM2, ENABLE); //計(jì)數(shù)器使能,開(kāi)始計(jì)數(shù)
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/********************注冊(cè)定時(shí)器2中斷處理函數(shù)***********************/
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/******************注冊(cè)串口1中斷服務(wù)函數(shù)************************/
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//配置串口中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//占先式優(yōu)先級(jí)設(shè)置為0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //副優(yōu)先級(jí)設(shè)置為0
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;//中斷禁止
NVIC_Init(&NVIC_InitStructure);//中斷初始化
}
/*************卡爾曼濾波*********************************/
void Kalman_Filter(float Accel,float Gyro)
{
static const float Q_angle=0.001;
static const float Q_gyro=0.003;
static const float R_angle=0.5;
static const float dt=0.01; //dt為kalman濾波器采樣時(shí)間;
static const char C_0 = 1;
static float Q_bias, Angle_err;
static float PCt_0, PCt_1, E;
static float K_0, K_1, t_0, t_1;
static float Pdot[4] ={0,0,0,0};
static float PP[2][2] = { { 1, 0 },{ 0, 1 } };
Angle+=(Gyro - Q_bias) * dt; //先驗(yàn)估計(jì)
Pdot[0]=Q_angle - PP[0][1] - PP[1][0]; // Pk-先驗(yàn)估計(jì)誤差協(xié)方差的微分
Pdot[1]= -PP[1][1];
Pdot[2]= -PP[1][1];
Pdot[3]=Q_gyro;
PP[0][0] += Pdot[0] * dt; // Pk-先驗(yàn)估計(jì)誤差協(xié)方差微分的積分
PP[0][1] += Pdot[1] * dt; // =先驗(yàn)估計(jì)誤差協(xié)方差
PP[1][0] += Pdot[2] * dt;
PP[1][1] += Pdot[3] * dt;
Angle_err = Accel - Angle; //zk-先驗(yàn)估計(jì)
PCt_0 = C_0 * PP[0][0];
PCt_1 = C_0 * PP[1][0];
E = R_angle + C_0 * PCt_0;
K_0 = PCt_0 / E;
K_1 = PCt_1 / E;
t_0 = PCt_0;
t_1 = C_0 * PP[0][1];
PP[0][0] -= K_0 * t_0; //后驗(yàn)估計(jì)誤差協(xié)方差
PP[0][1] -= K_0 * t_1;
PP[1][0] -= K_1 * t_0;
PP[1][1] -= K_1 * t_1;
Angle += K_0 * Angle_err; //后驗(yàn)估計(jì)
Q_bias += K_1 * Angle_err; //后驗(yàn)估計(jì)
Gyro_y = Gyro - Q_bias; //輸出值(后驗(yàn)估計(jì))的微分=角速度
}
void Angle_Calculate(void)
{
static uint8_t DataBuffer[2]; //數(shù)據(jù)緩存
/****************************加速度****************************************/
I2C_ReadBuffer(DataBuffer, ACCEL_XOUT_H, 2);
Accel_x = (short)((DataBuffer[0]<<8)+DataBuffer[1]); //讀取X軸加速度
Angle_ax = (Accel_x +220) /16384; //去除零點(diǎn)偏移,計(jì)算得到角度(弧度)
Angle_ax = Angle_ax*1.2*180/3.14; //弧度轉(zhuǎn)換為度,
/****************************角速度****************************************/
I2C_ReadBuffer(DataBuffer, GYRO_YOUT_H, 2);
Gyro_y = (short)((DataBuffer[0]<<8)+DataBuffer[1]); //靜止時(shí)角速度Y軸輸出為-18左右
Gyro_y = (Gyro_y + 18)/16.4; //去除零點(diǎn)偏移,計(jì)算角速度值
// Angle_gy = Angle_gy + Gyro_y*0.01; //角速度積分得到傾斜角度.
/***************************卡爾曼濾波+角度融合*************************************/
Kalman_Filter(Angle_ax,Gyro_y); //卡爾曼濾波計(jì)算傾角
/*******************************互補(bǔ)濾波******************************************/
/*補(bǔ)償原理是取當(dāng)前傾角和加速度獲
得傾角差值進(jìn)行放大,然后與陀螺
儀角速度疊加后再積分,從而使傾
角最跟蹤為加速度獲得的角度0.5
為放大倍數(shù),可調(diào)節(jié)補(bǔ)償度;
0.01為系統(tǒng)周期10ms
*/
// Angle = Angle + (((Angle_ax-Angle)*0.5 + Gyro_y)*0.01);*/
}
int main(void)
{
Stm32_Clock_Init(6);//系統(tǒng)時(shí)鐘設(shè)置為外部晶振,9倍頻
delay_init(72);//系統(tǒng)SysTick初始化
Usart_Configuration();
TIM2_Configuration();
NVIC_Configuration();
I2C_Congiguration();
MPU6050_Init();
while (1)
{
printf("%f %f ",Angle,Gyro_y);
USART1_Send_Enter();
delay_ms(100);
}
}
/****************定時(shí)器2中斷服務(wù)函數(shù)***************************************/
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
Angle_Calculate();
}
}
復(fù)制代碼
所有資料51hei提供下載:
卡爾曼濾波.rar
(427.33 KB, 下載次數(shù): 68)
2018-5-6 01:19 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1