日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于MPU6050学习的一些总结之三MPU6050程序解读

發布時間:2023/12/8 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于MPU6050学习的一些总结之三MPU6050程序解读 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

關于MPU6050學習的一些總結之三MPU6050程序解讀

  • 前言
  • MPU6050.h
  • 初始化函數
  • 獲取數據
  • 數據處理(計算零偏)
  • 結語

前言

經過兩天的整理終于可以嘗試解讀MPU6050程序了,話不多說直接看程序。

MPU6050.h

在讀頭文件之前還有個小知識點在第一節遺忘了,現在補上。那就是在MPU6050內部用來存儲自身地址的寄存器,它的名字也很形象叫WHO_AM_I。

可以看出這個寄存器是只讀寄存器,只有Bit1-Bit6存放六位只讀數據。分別是110 100,地址的第7位由引腳AD0的高低電平決定。下面直接看MPU6050的頭文件。

//**************************************** // 定義MPU6050內部地址 //****************************************#define SMPLRT_DIV 0x19 #define CONFIGL 0x1A #define GYRO_CONFIG 0x1B #define ACCEL_CONFIG 0x1C #define ACCEL_XOUT_H 0x3B #define ACCEL_XOUT_L 0x3C #define ACCEL_YOUT_H 0x3D #define ACCEL_YOUT_L 0x3E #define ACCEL_ZOUT_H 0x3F #define ACCEL_ZOUT_L 0x40 #define TEMP_OUT_H 0x41 #define TEMP_OUT_L 0x42 #define GYRO_XOUT_H 0x43 #define GYRO_XOUT_L 0x44 #define GYRO_YOUT_H 0x45 #define GYRO_YOUT_L 0x46 #define GYRO_ZOUT_H 0x47 #define GYRO_ZOUT_L 0x48 #define PWR_MGMT_1 0x6B //電源管理,典型值:0x00(正常啟用) #define WHO_AM_I 0x75 //IIC地址寄存器(默認數值0x68,只讀) #define MPU6050_ADDRESS 0xD0 //IIC寫入時的地址字節數據,+1為讀取 //此外,還定義了幾個結構體。 struct _float{float x;float y;float z;};struct _int16{int16_t x;int16_t y;int16_t z;}; struct _trans{struct _int16 origin; //原始值struct _int16 averag; //平均值struct _int16 histor; //歷史值struct _int16 quiet; //靜態值struct _float radian; //弧度值 };struct _sensor{ struct _trans acc;struct _trans gyro;};

初始化函數

u8 mpu6050_buffer[14]; //iic讀取后存放數據 struct _sensor sensor; u8 InitMPU6050(void) {u8 date;date = Single_Write(MPU6050_ADDRESS, PWR_MGMT_1, 0x00); //解除休眠狀態date += Single_Write(MPU6050_ADDRESS, SMPLRT_DIV, 0x07);date += Single_Write(MPU6050_ADDRESS, CONFIGL, 0x03);date += Single_Write(MPU6050_ADDRESS, GYRO_CONFIG, 0x10);date += Single_Write(MPU6050_ADDRESS, ACCEL_CONFIG, 0x09);//+-4Greturn date; }

Single_Write();函數在第二節已經介紹過,因此初始化函數主要對寄存器寫入字節數據。查閱相關寄存器可知:
1.對于電源管理寄存器1寫入0x00,即SLEEP=0:喚醒MPU6050;TEMP_DIS=0,使能溫度傳感器;CLKSEL=0,采用內部8MHz時鐘作為時鐘源。
2.對于采樣分頻寄存器寫入0x07,即SMPLRT_DIV=7;
3.對于配置寄存器寫入0x03,即低通濾波器參數DLPF_CFG=3,查表得陀螺儀輸出頻率Fs=1KHz。根據公式:采樣頻率=陀螺儀輸出頻率/(1+SMPLRT_DIV)
計算得到采樣頻率為1KHz/(1+7)=125Hz。
4.對于陀螺儀配置寄存器寫入0x10,查表可知不觸發自檢,滿量程為±1000°/s。
5.對于加速度計配置寄存器寫入0x09,查表可知不觸發自檢,滿量程為±4g,另外根據表可知,高通濾波器的截止頻率為5Hz.

獲取數據

//**************************實現函數******************************************** //將iic讀取到得數據分拆,放入相應寄存器,更新MPU6050_Last //****************************************************************************** void MPU6050_Read(void) {mpu6050_buffer[0]=Single_Read(MPU6050_ADDRESS, 0x3B);mpu6050_buffer[1]=Single_Read(MPU6050_ADDRESS, 0x3C);mpu6050_buffer[2]=Single_Read(MPU6050_ADDRESS, 0x3D);mpu6050_buffer[3]=Single_Read(MPU6050_ADDRESS, 0x3E);mpu6050_buffer[4]=Single_Read(MPU6050_ADDRESS, 0x3F);mpu6050_buffer[5]=Single_Read(MPU6050_ADDRESS, 0x40);mpu6050_buffer[8]=Single_Read(MPU6050_ADDRESS, 0x43);mpu6050_buffer[9]=Single_Read(MPU6050_ADDRESS, 0x44);mpu6050_buffer[10]=Single_Read(MPU6050_ADDRESS, 0x45);mpu6050_buffer[11]=Single_Read(MPU6050_ADDRESS, 0x46);mpu6050_buffer[12]=Single_Read(MPU6050_ADDRESS, 0x47);mpu6050_buffer[13]=Single_Read(MPU6050_ADDRESS, 0x48);}

由高到低依次讀取加速度計和陀螺儀三個軸的數據存放到數組內。在看下一段代碼之前,還需要看幾個宏定義以便更加容易地理解函數。

#define RtA 57.324841 //弧度到角度 #define AtR 0.0174533 //角度轉弧度 #define Acc_G 0.0011963 //±4g 8g/65536 #define Gyro_G 0.03051756 //±1000°/s 2000/65536 #define Gyro_Gr 0.0005426 // °每秒轉化為rad/s

在這里,RtA表示弧度轉角度的換算即180/pi180/pi180/pi;AtR表示角度轉弧度的換算即pi/180pi/180pi/180;Acc_G表示加速度計靈敏度的倒數即AccG=1/(65536/8)Acc_G=1/(65536/8)\quadAccG?=1/(65536/8);
同理GyroG=1/(65536/2000)Gyro_G=1/(65536/2000)GyroG?=1/(65536/2000);將單位°/s轉化為rad/s后對應的便是Gyro_Gr。
由于傳感器傳回的數據為16位數字量,對于加速度計將16位數字量num.acc轉化為模擬量的公式為:num.acc?ACCGnum.acc*ACC_Gnum.acc?ACCG?。對于陀螺儀將16位數字量num.Gyro轉化為模擬量的公式為:num.Gyro?GyroG,單位為°/s,num.Gyro?Gyro.Gr,單位為rad/snum.Gyro*Gyro_G,單位為°/s,num.Gyro*Gyro.Gr,單位為rad/snum.Gyro?GyroG?,°/snum.Gyro?Gyro.Gr,rad/s

數據處理(計算零偏)

void MPU6050_Dataanl(void) {MPU6050_Read();sensor.acc.origin.x = ((((int16_t)mpu6050_buffer[0]) << 8) | mpu6050_buffer[1]) - sensor.acc.quiet.x;//將加速度計x軸的高位和低位測量值整合到一起,并減去漂移量。sensor.acc.origin.y = ((((int16_t)mpu6050_buffer[2]) << 8) | mpu6050_buffer[3]) - sensor.acc.quiet.y;//將加速度計y軸的高位和低位測量值整合到一起,并減去漂移量。sensor.acc.origin.z = ((((int16_t)mpu6050_buffer[4]) << 8) | mpu6050_buffer[5]);//將加速度計z軸的高位和低位測量值整合到一起,并減去漂移量。sensor.gyro.origin.x = ((((int16_t)mpu6050_buffer[8]) << 8) | mpu6050_buffer[9]);//將陀螺儀x軸的高位和低位測量值整合到一起。sensor.gyro.origin.y = ((((int16_t)mpu6050_buffer[10]) << 8)| mpu6050_buffer[11]);//將陀螺儀y軸的高位和低位測量值整合到一起。sensor.gyro.origin.z = ((((int16_t)mpu6050_buffer[12]) << 8)| mpu6050_buffer[13]);//將陀螺儀z軸的高位和低位測量值整合到一起。sensor.gyro.radian.x = sensor.gyro.origin.x * Gyro_Gr - sensor.gyro.quiet.x * Gyro_Gr;//數字量轉換成模擬量,單位是rad/ssensor.gyro.radian.y = sensor.gyro.origin.y * Gyro_Gr - sensor.gyro.quiet.y * Gyro_Gr;//數字量轉換成模擬量,單位是rad/ssensor.gyro.radian.z = sensor.gyro.origin.z * Gyro_Gr - sensor.gyro.quiet.z * Gyro_Gr;//數字量轉換成模擬量,單位是rad/s // The calibration of acc // if(flag.calibratingA)//加速度計初始數據校準,記錄零偏{static int32_t tempax=0,tempay=0,tempaz=0;static uint8_t cnt_a=0;if(cnt_a==0){sensor.acc.quiet.x = 0;sensor.acc.quiet.y = 0;sensor.acc.quiet.z = 0;tempax = 0;tempay = 0;tempaz = 0;cnt_a = 1;}tempax+= sensor.acc.origin.x;tempay+= sensor.acc.origin.y;tempaz+= sensor.acc.origin.z;if(cnt_a==200){sensor.acc.quiet.x = tempax/cnt_a;sensor.acc.quiet.y = tempay/cnt_a;sensor.acc.quiet.z = tempaz/cnt_a;cnt_a = 0;flag.calibratingA = 0;EE_SAVE_ACC_OFFSET();//保存數據return;}cnt_a++; } }

這里面的flag.calibratingA通過翻看其他文件大概了解到是用來校準加速度計的,在遙控的程序中有用到(具體怎么實現的還沒有看懂),大致就是通過遙控命令來使flag.calibratingA=1,我猜想是在起飛前為了校準加速度計通過人為遙控來測量零偏。接下來就是讀取200次加速度計在靜止狀態下的測量值取平均數來定義零偏,通過EE_SAVE_ACC_OFFSET();函數保存到EEPROM中。

/*====================================================================================================*/ /*====================================================================================================* **函數 : Gyro_OFFSET **功能 : 陀螺儀靜態采集 **輸入 : None **輸出 : None **備注 : None **====================================================================================================*/ /*====================================================================================================*/ void Gyro_OFFSET(void) {uint16_t cnt_g = 0;int32_t tempgx = GYRO_GATHER;int32_t tempgy = GYRO_GATHER;int32_t tempgz = GYRO_GATHER;int16_t gx_last=0,gy_last=0,gz_last=0;sensor.gyro.quiet.x=0;sensor.gyro.quiet.y=0;sensor.gyro.quiet.z=0;while(tempgx>=GYRO_GATHER || tempgy>=GYRO_GATHER || tempgz>= GYRO_GATHER) //此循環是確保四軸處于完全靜止狀態{tempgx=0;tempgy=0;tempgz=0;cnt_g=30;while(cnt_g--){MPU6050_Read();sensor.gyro.origin.x = ((((int16_t)mpu6050_buffer[8]) << 8) | mpu6050_buffer[9]);sensor.gyro.origin.y = ((((int16_t)mpu6050_buffer[10]) << 8)| mpu6050_buffer[11]);sensor.gyro.origin.z = ((((int16_t)mpu6050_buffer[12]) << 8)| mpu6050_buffer[13]);tempgx += absu16(sensor.gyro.origin.x - gx_last);tempgy += absu16(sensor.gyro.origin.y - gy_last);tempgz += absu16(sensor.gyro.origin.z - gz_last);gx_last = sensor.gyro.origin.x;gy_last = sensor.gyro.origin.y;gz_last = sensor.gyro.origin.z;} }tempgx=0;tempgy=0;tempgz=0;cnt_g=2000;while(cnt_g--) //此循環進行陀螺儀標定,前提是四軸已經處于完全靜止狀態{MPU6050_Read();sensor.gyro.origin.x = ((((int16_t)mpu6050_buffer[8]) << 8) | mpu6050_buffer[9]);sensor.gyro.origin.y = ((((int16_t)mpu6050_buffer[10]) << 8)| mpu6050_buffer[11]);sensor.gyro.origin.z = ((((int16_t)mpu6050_buffer[12]) << 8)| mpu6050_buffer[13]);tempgx += sensor.gyro.origin.x;tempgy += sensor.gyro.origin.y;tempgz += sensor.gyro.origin.z;}sensor.gyro.quiet.x = tempgx/2000;sensor.gyro.quiet.y = tempgy/2000;sensor.gyro.quiet.z = tempgz/2000; }

這里GYRO_GATHER是宏定義設定好的值為100。具體怎么得到的不太清楚,就理解成設定的一個標準吧。第一個while循環是用來確保四軸處于完全靜止狀態,大致流程就是采集30次陀螺儀測量值數據,并且將每兩個相鄰的數據做差后進行累加,三個軸在采集30次數據后累加得到的數據都小于100(GYRO_GATHER)的話,說明陀螺儀處于靜止狀態。那么,就可以進行接下來零偏的計算了。本次程序是采集2000次數據求取平均值作為陀螺儀的零偏量。

結語

通過三篇文章已經全部完成了MPU6050模塊的學習,包括寄存器的使用,通過IIC協議來讀寫數據,對數據處理得到真實值和傳感器的零偏。接下來,我打算繼續去了解這些數據又是怎樣獲取四軸飛行器的姿態以及實現對四軸飛行器的控制呢?

總結

以上是生活随笔為你收集整理的关于MPU6050学习的一些总结之三MPU6050程序解读的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。