国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32 F103C8T6學(xué)習(xí)筆記6:IIC通信__驅(qū)動MPU6050 6軸運動處理組件—一階互補濾波

這篇具有很好參考價值的文章主要介紹了STM32 F103C8T6學(xué)習(xí)筆記6:IIC通信__驅(qū)動MPU6050 6軸運動處理組件—一階互補濾波。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

今日主要學(xué)習(xí)一款傾角傳感器——MPU6050,往后對單片機原理基礎(chǔ)講的會比較少,更傾向于簡單粗暴地貼代碼,因為經(jīng)過前些日子對MSP432的學(xué)習(xí),對原理方面也有些熟絡(luò)了,除了在新接觸它時會對其引腳、時鐘、總線等進行仔細一些的研究之外,其余驅(qū)動方面便是照搬經(jīng)驗了~~

本文嘗試使用STM32 F103C8T6通過IIC通信驅(qū)動MPU6050,文章提供源碼、原理講解、實踐操作與結(jié)果截圖,測試工程下載。

目錄

MPU6050

使用注意點:

?程序設(shè)計目標:

移植IIC通信:

編寫IIC與MPU6050的通信:

向MPU6050寄存器寫數(shù)據(jù):

讀取MPU6050寄存器數(shù)據(jù):

MPU6050地址:

MPU6050初始化:

MPU6050數(shù)據(jù)讀取處理:

MPU6050濾波一階互補:

主函數(shù)代碼:


MPU6050

下圖為MPU6050:

STM32 F103C8T6學(xué)習(xí)筆記6:IIC通信__驅(qū)動MPU6050 6軸運動處理組件—一階互補濾波,STM32 F103 C8T6筆記,硬件模塊與傳感器的驅(qū)動,stm32,學(xué)習(xí),筆記

?MPU6050是由三個陀螺儀和三個加速度傳感器組成的6軸運動處理組件,是一款六軸(三軸加速度+三軸角速度(陀螺儀))傳感器

1. VCC:構(gòu)成8位的IIC地址模塊自帶了 3.3V 超低壓差穩(wěn)壓芯片,給 MPU6050 供電,因此外部供電可以選擇:3.3V / 5V 都可以

2.GND:不多說

3.SCL、SDA:IIC通訊引腳

另外,IIC_SDA 和 IIC_SCL 帶了 4.7K上拉電阻,外部可以不用再加上拉電阻了

4.XDA、XCL:XDA 跟 XCl是用來外接電磁傳感器,即使模塊不動,數(shù)值也會有波動。而外加電磁傳感器就是更好的解決這一問題。

5.AD0:?AD0 是從 IIC 接口(接 MCU)的地址控制引腳,該引腳控制IIC 地址的最低位。如果接?GND,則 MPU6050 的 IIC 地址是:0X68,如果接 VDD,則是0X69。另外,MPU_AD0 自帶了 10K 下拉電阻,當 AD0懸空時,默認 IIC 地址為(0X68)。?

?6.INT:在MPU6050 中有個INT 引腳,每當MPU6050 有數(shù)據(jù)輸出時,引腳INT 有相應(yīng)的電平變化??梢詫⑵溆|發(fā)外部中斷作為控制周期。當MPU6050 的讀取一次數(shù)據(jù),就控制一次,可以很好地保持MPU6050 數(shù)據(jù)的實時性。

使用注意點:

1.不用觸碰MPU6050芯片的表面,實測會使其卡住,我遇到這問題是需要給單片機重新下載程序才能解決。

2.AD0腳可以懸空也可接VCC\GND,這三種接法情況會導(dǎo)致MPU6050的地址變化,我是懸空的。

3.本文用到include "math.h"的庫函數(shù):?double atan2? (double y???? , double x);編譯報錯警告時注意添加頭文件~

?程序設(shè)計目標:

有關(guān)于MPU6050地址,寄存器讀取,寄存器寫入方面的一些知識,我們就在程序設(shè)計實踐中一起講了~~

此次程序設(shè)計目標簡單,是IIC 讀取MPU6050的角度值,用串口1每隔1S向上位機反饋:

移植IIC通信:

首先是移植IIC軟件模擬時序、IIC引腳初始化的代碼,這里直接貼出:此處我初始化了PA2 和 PA3為通信端口:該IIC代碼是從他處移植的~? IIC基本原理不多加介紹:

#include "bsp_i2c.h"

/* 定義I2C總線連接的GPIO端口, 用戶只需要修改下面4行代碼即可任意改變SCL和SDA的引腳 */
#define GPIO_PORT_I2C	GPIOA			/* GPIO端口 */
#define RCC_I2C_PORT 	RCC_APB2Periph_GPIOA		/* GPIO端口時鐘 */
#define I2C_SCL_PIN		GPIO_Pin_2			/* 連接到SCL時鐘線的GPIO */
#define I2C_SDA_PIN		GPIO_Pin_3			/* 連接到SDA數(shù)據(jù)線的GPIO */




/* 定義讀寫SCL和SDA的宏,已增加代碼的可移植性和可閱讀性 */
#if 0	/* 條件編譯: 1 選擇GPIO的庫函數(shù)實現(xiàn)IO讀寫 */
	#define I2C_SCL_1()  GPIO_SetBits(GPIO_PORT_I2C, I2C_SCL_PIN)		/* SCL = 1 */
	#define I2C_SCL_0()  GPIO_ResetBits(GPIO_PORT_I2C, I2C_SCL_PIN)		/* SCL = 0 */
	
	#define I2C_SDA_1()  GPIO_SetBits(GPIO_PORT_I2C, I2C_SDA_PIN)		/* SDA = 1 */
	#define I2C_SDA_0()  GPIO_ResetBits(GPIO_PORT_I2C, I2C_SDA_PIN)		/* SDA = 0 */
	
	#define I2C_SDA_READ()  GPIO_ReadInputDataBit(GPIO_PORT_I2C, I2C_SDA_PIN)	/* 讀SDA口線狀態(tài) */
#else	/* 這個分支選擇直接寄存器操作實現(xiàn)IO讀寫 */
    /* 注意:如下寫法,在IAR最高級別優(yōu)化時,會被編譯器錯誤優(yōu)化 */
	#define I2C_SCL_1()  GPIO_PORT_I2C->BSRR = I2C_SCL_PIN				/* SCL = 1 */
	#define I2C_SCL_0()  GPIO_PORT_I2C->BRR = I2C_SCL_PIN				/* SCL = 0 */
	
	#define I2C_SDA_1()  GPIO_PORT_I2C->BSRR = I2C_SDA_PIN				/* SDA = 1 */
	#define I2C_SDA_0()  GPIO_PORT_I2C->BRR = I2C_SDA_PIN				/* SDA = 0 */
	
	#define I2C_SDA_READ()  ((GPIO_PORT_I2C->IDR & I2C_SDA_PIN) != 0)	/* 讀SDA口線狀態(tài) */
#endif

void i2c_GPIO_Config(void);

/*
*********************************************************************************************************
*	函 數(shù) 名: i2c_Delay
*	功能說明: I2C總線位延遲,最快400KHz
*	形    參:無
*	返 回 值: 無
*********************************************************************************************************
*/
static void i2c_Delay(void)
{
	uint8_t i;

	/* 
	 	下面的時間是通過安富萊AX-Pro邏輯分析儀測試得到的。
		CPU主頻72MHz時,在內(nèi)部Flash運行, MDK工程不優(yōu)化
		循環(huán)次數(shù)為10時,SCL頻率 = 205KHz 
		循環(huán)次數(shù)為7時,SCL頻率 = 347KHz, SCL高電平時間1.5us,SCL低電平時間2.87us 
	 	循環(huán)次數(shù)為5時,SCL頻率 = 421KHz, SCL高電平時間1.25us,SCL低電平時間2.375us 
        
    IAR工程編譯效率高,不能設(shè)置為7
	*/
	for (i = 0; i < 10; i++);
}

/*
*********************************************************************************************************
*	函 數(shù) 名: i2c_Start
*	功能說明: CPU發(fā)起I2C總線啟動信號
*	形    參:無
*	返 回 值: 無
*********************************************************************************************************
*/
void i2c_Start(void)
{
	/* 當SCL高電平時,SDA出現(xiàn)一個下跳沿表示I2C總線啟動信號 */
	I2C_SDA_1();
	I2C_SCL_1();
	i2c_Delay();
	I2C_SDA_0();
	i2c_Delay();
	I2C_SCL_0();
	i2c_Delay();
}

/*
*********************************************************************************************************
*	函 數(shù) 名: i2c_Start
*	功能說明: CPU發(fā)起I2C總線停止信號
*	形    參:無
*	返 回 值: 無
*********************************************************************************************************
*/
void i2c_Stop(void)
{
	/* 當SCL高電平時,SDA出現(xiàn)一個上跳沿表示I2C總線停止信號 */
	I2C_SDA_0();
	I2C_SCL_1();
	i2c_Delay();
	I2C_SDA_1();
}

/*
*********************************************************************************************************
*	函 數(shù) 名: i2c_SendByte
*	功能說明: CPU向I2C總線設(shè)備發(fā)送8bit數(shù)據(jù)
*	形    參:_ucByte : 等待發(fā)送的字節(jié)
*	返 回 值: 無
*********************************************************************************************************
*/
void i2c_SendByte(uint8_t _ucByte)
{
	uint8_t i;

	/* 先發(fā)送字節(jié)的高位bit7 */
	for (i = 0; i < 8; i++)
	{		
		if (_ucByte & 0x80)
		{
			I2C_SDA_1();
		}
		else
		{
			I2C_SDA_0();
		}
		i2c_Delay();
		I2C_SCL_1();
		i2c_Delay();	
		I2C_SCL_0();
		if (i == 7)
		{
			 I2C_SDA_1(); // 釋放總線
		}
		_ucByte <<= 1;	/* 左移一個bit */
		i2c_Delay();
	}
}

/*
*********************************************************************************************************
*	函 數(shù) 名: i2c_ReadByte
*	功能說明: CPU從I2C總線設(shè)備讀取8bit數(shù)據(jù)
*	形    參:無
*	返 回 值: 讀到的數(shù)據(jù)
*********************************************************************************************************
*/
uint8_t i2c_ReadByte(u8 ack)
{
	uint8_t i;
	uint8_t value;

	/* 讀到第1個bit為數(shù)據(jù)的bit7 */
	value = 0;
	for (i = 0; i < 8; i++)
	{
		value <<= 1;
		I2C_SCL_1();
		i2c_Delay();
		if (I2C_SDA_READ())
		{
			value++;
		}
		I2C_SCL_0();
		i2c_Delay();
	}
	if(ack==0)
		i2c_NAck();
	else
		i2c_Ack();
	return value;
}

/*
*********************************************************************************************************
*	函 數(shù) 名: i2c_WaitAck
*	功能說明: CPU產(chǎn)生一個時鐘,并讀取器件的ACK應(yīng)答信號
*	形    參:無
*	返 回 值: 返回0表示正確應(yīng)答,1表示無器件響應(yīng)
*********************************************************************************************************
*/
uint8_t i2c_WaitAck(void)
{
	uint8_t re;

	I2C_SDA_1();	/* CPU釋放SDA總線 */
	i2c_Delay();
	I2C_SCL_1();	/* CPU驅(qū)動SCL = 1, 此時器件會返回ACK應(yīng)答 */
	i2c_Delay();
	if (I2C_SDA_READ())	/* CPU讀取SDA口線狀態(tài) */
	{
		re = 1;
	}
	else
	{
		re = 0;
	}
	I2C_SCL_0();
	i2c_Delay();
	return re;
}

/*
*********************************************************************************************************
*	函 數(shù) 名: i2c_Ack
*	功能說明: CPU產(chǎn)生一個ACK信號
*	形    參:無
*	返 回 值: 無
*********************************************************************************************************
*/
void i2c_Ack(void)
{
	I2C_SDA_0();	/* CPU驅(qū)動SDA = 0 */
	i2c_Delay();
	I2C_SCL_1();	/* CPU產(chǎn)生1個時鐘 */
	i2c_Delay();
	I2C_SCL_0();
	i2c_Delay();
	I2C_SDA_1();	/* CPU釋放SDA總線 */
}

/*
*********************************************************************************************************
*	函 數(shù) 名: i2c_NAck
*	功能說明: CPU產(chǎn)生1個NACK信號
*	形    參:無
*	返 回 值: 無
*********************************************************************************************************
*/
void i2c_NAck(void)
{
	I2C_SDA_1();	/* CPU驅(qū)動SDA = 1 */
	i2c_Delay();
	I2C_SCL_1();	/* CPU產(chǎn)生1個時鐘 */
	i2c_Delay();
	I2C_SCL_0();
	i2c_Delay();	
}

/*
*********************************************************************************************************
*	函 數(shù) 名: i2c_GPIO_Config
*	功能說明: 配置I2C總線的GPIO,采用模擬IO的方式實現(xiàn)
*	形    參:無
*	返 回 值: 無
*********************************************************************************************************
*/
void i2c_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_I2C_PORT, ENABLE);	/* 打開GPIO時鐘 */

	GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  	/* 開漏輸出 */
	GPIO_Init(GPIO_PORT_I2C, &GPIO_InitStructure);

	/* 給一個停止信號, 復(fù)位I2C總線上的所有設(shè)備到待機模式 */
	i2c_Stop();
}

/*
*********************************************************************************************************
*	函 數(shù) 名: i2c_CheckDevice
*	功能說明: 檢測I2C總線設(shè)備,CPU向發(fā)送設(shè)備地址,然后讀取設(shè)備應(yīng)答來判斷該設(shè)備是否存在
*	形    參:_Address:設(shè)備的I2C總線地址
*	返 回 值: 返回值 0 表示正確, 返回1表示未探測到
*********************************************************************************************************
*/
uint8_t i2c_CheckDevice(uint8_t _Address)
{
	uint8_t ucAck;

	i2c_GPIO_Config();		/* 配置GPIO */
	
	i2c_Start();		/* 發(fā)送啟動信號 */

	/* 發(fā)送設(shè)備地址+讀寫控制bit(0 = w, 1 = r) bit7 先傳 */
	i2c_SendByte(_Address|I2C_WR);
	ucAck = i2c_WaitAck();	/* 檢測設(shè)備的ACK應(yīng)答 */

	i2c_Stop();			/* 發(fā)送停止信號 */

	return ucAck;
}
#ifndef _BSP_I2C_H
#define _BSP_I2C_H

#include <inttypes.h>
#include "stm32f10x.h"

#define I2C_WR	0		/* 寫控制bit */
#define I2C_RD	1		/* 讀控制bit */

void i2c_Start(void);
void i2c_Stop(void);
void i2c_SendByte(uint8_t _ucByte);
uint8_t i2c_ReadByte(uint8_t ack);
uint8_t i2c_WaitAck(void);
void i2c_Ack(void);
void i2c_NAck(void);
uint8_t i2c_CheckDevice(uint8_t _Address);
void i2c_GPIO_Config(void);

#endif

編寫IIC與MPU6050的通信:

向MPU6050寄存器寫數(shù)據(jù):

//模塊的A0引腳接GND,IIC的7位地址為0x68,若接到VCC,需要改為0x69
#define MPU6050_SLAVE_ADDRESS  (0x68<<1)      //MPU6050器件讀地址

//add 是地址
//dat 是數(shù)據(jù)
void MPU6050_WriteReg(u8 reg_add,u8 reg_dat)
{
	i2c_Start();
	i2c_SendByte(MPU6050_SLAVE_ADDRESS);
	i2c_WaitAck();
	i2c_SendByte(reg_add);
	i2c_WaitAck();
	i2c_SendByte(reg_dat);
	i2c_WaitAck();
	i2c_Stop();
}

讀取MPU6050寄存器數(shù)據(jù):

//reg_add是地址
//char*Read 表示傳入一個定義好的數(shù)組去接收
//num表示接收的位數(shù)

void MPU6050_ReadData(u8 reg_add,unsigned char*Read,u8 num)
{
	unsigned char i;
	
	i2c_Start();
	i2c_SendByte(MPU6050_SLAVE_ADDRESS);
	i2c_WaitAck();
	i2c_SendByte(reg_add);
	i2c_WaitAck();
	
	i2c_Start();
	i2c_SendByte(MPU6050_SLAVE_ADDRESS+1);
	i2c_WaitAck();
	
	for(i=0;i<(num-1);i++){
		*Read=i2c_ReadByte(1);
		Read++;
	}
	*Read=i2c_ReadByte(0);
	i2c_Stop();
}

MPU6050地址:

此處我翻譯了部分地址,進行宏定義

//模塊的A0引腳接GND,IIC的7位地址為0x68,若接到VCC,需要改為0x69
#define MPU6050_SLAVE_ADDRESS  (0x68<<1)      //MPU6050器件讀地址



#define MPU6050_WHO_AM_I        0x75     //用于驗證設(shè)備是否正常連接。
#define MPU6050_SMPLRT_DIV      0        //是采樣率分頻器的寄存器。對其進行配置可以設(shè)置采樣率,這里設(shè)置為8000Hz。
#define MPU6050_DLPF_CFG        0        //數(shù)字低通濾波器的寄存器。對其進行配置可以設(shè)置陀螺儀和加速度計的濾波參數(shù),這里設(shè)置為0表示不濾波。
#define MPU6050_GYRO_OUT        0x43     //MPU6050陀螺儀數(shù)據(jù)寄存器地址
#define MPU6050_ACC_OUT         0x3B     //MPU6050加速度數(shù)據(jù)寄存器地址


//MPU6050 的兩個可能的器件地址。AD0 引腳的狀態(tài)決定了使用哪個地址,低電平表示使用 `MPU6050_ADDRESS_AD0_LOW`。
#define MPU6050_ADDRESS_AD0_LOW     0x68 // address pin low (GND), default for InvenSense evaluation board
#define MPU6050_ADDRESS_AD0_HIGH    0x69 // address pin high (VCC)
#define MPU6050_DEFAULT_ADDRESS     MPU6050_ADDRESS_AD0_LOW

#define MPU6050_RA_XG_OFFS_TC       0x00 //[7] PWR_MODE, [6:1] XG_OFFS_TC, [0] OTP_BNK_VLD X軸陀螺儀偏移溫度補償寄存器
#define MPU6050_RA_YG_OFFS_TC       0x01 //[7] PWR_MODE, [6:1] YG_OFFS_TC, [0] OTP_BNK_VLD Y軸陀螺儀偏移溫度補償寄存器
#define MPU6050_RA_ZG_OFFS_TC       0x02 //[7] PWR_MODE, [6:1] ZG_OFFS_TC, [0] OTP_BNK_VLD Z軸陀螺儀偏移溫度補償寄存器

#define MPU6050_RA_X_FINE_GAIN      0x03 //[7:0] X_FINE_GAIN X軸加速度計校準增益寄存器
#define MPU6050_RA_Y_FINE_GAIN      0x04 //[7:0] Y_FINE_GAIN Y軸加速度計校準增益寄存器
#define MPU6050_RA_Z_FINE_GAIN      0x05 //[7:0] Z_FINE_GAIN Z軸加速度計校準增益寄存器

#define MPU6050_RA_XA_OFFS_H        0x06 //[15:0] XA_OFFS X軸加速度計偏移高位寄存器
#define MPU6050_RA_XA_OFFS_L_TC     0x07                //X軸加速度計偏移低位寄存器
#define MPU6050_RA_YA_OFFS_H        0x08 //[15:0] YA_OFFS Y軸加速度計偏移高位寄存器
#define MPU6050_RA_YA_OFFS_L_TC     0x09                //Y軸加速度計偏移低位寄存器
#define MPU6050_RA_ZA_OFFS_H        0x0A //[15:0] ZA_OFFS Z軸加速度計偏移高位寄存器
#define MPU6050_RA_ZA_OFFS_L_TC     0x0B                //Z軸加速度計偏移低位寄存器

#define MPU6050_RA_XG_OFFS_USRH     0x13 //[15:0] XG_OFFS_USR X軸陀螺儀用戶偏移高位寄存器
#define MPU6050_RA_XG_OFFS_USRL     0x14                //X軸陀螺儀用戶偏移低位寄存器
#define MPU6050_RA_YG_OFFS_USRH     0x15 //[15:0] YG_OFFS_USR Y軸陀螺儀用戶偏移高位寄存器
#define MPU6050_RA_YG_OFFS_USRL     0x16                //Y軸陀螺儀用戶偏移低位寄存器
#define MPU6050_RA_ZG_OFFS_USRH     0x17 //[15:0] ZG_OFFS_USR  Z軸陀螺儀用戶偏移高位寄存器
#define MPU6050_RA_ZG_OFFS_USRL     0x18                //Z軸陀螺儀用戶偏移低位寄存器。

#define MPU6050_RA_SMPLRT_DIV       0x19 //設(shè)置采樣率除數(shù),用于控制采樣率的頻率。
#define MPU6050_RA_CONFIG           0x1A //配置加速度計和陀螺儀的低通濾波器和同步采樣率
#define MPU6050_RA_GYRO_CONFIG      0x1B //配置陀螺儀的測量范圍和自檢
#define MPU6050_RA_ACCEL_CONFIG     0x1C //配置加速度計的測量范圍和自檢
#define MPU6050_RA_FF_THR           0x1D //雙向運動檢測的自由落體閾值
#define MPU6050_RA_FF_DUR           0x1E //雙向運動檢測的自由落體持續(xù)時間
#define MPU6050_RA_MOT_THR          0x1F //單向運動檢測的運動閾值
#define MPU6050_RA_MOT_DUR          0x20 //單向運動檢測的運動持續(xù)時間
#define MPU6050_RA_ZRMOT_THR        0x21 //零運動檢測的運動閾值
#define MPU6050_RA_ZRMOT_DUR        0x22 //零運動檢測的運動持續(xù)時間
#define MPU6050_RA_FIFO_EN          0x23 //FIFO緩沖區(qū)的數(shù)據(jù)輸出使能

#define MPU6050_RA_I2C_MST_CTRL     0x24 //I2C主控制器的配置
#define MPU6050_RA_I2C_SLV0_ADDR    0x25 //I2C從設(shè)備0的地址
#define MPU6050_RA_I2C_SLV0_REG     0x26 //I2C從設(shè)備0的寄存器地址
#define MPU6050_RA_I2C_SLV0_CTRL    0x27 //I2C從設(shè)備0的控制設(shè)置
#define MPU6050_RA_I2C_SLV1_ADDR    0x28 //I2C從設(shè)備1的地址
#define MPU6050_RA_I2C_SLV1_REG     0x29 //I2C從設(shè)備1的寄存器地址
#define MPU6050_RA_I2C_SLV1_CTRL    0x2A //I2C從設(shè)備1的控制設(shè)置
#define MPU6050_RA_I2C_SLV2_ADDR    0x2B //I2C從設(shè)備2的地址
#define MPU6050_RA_I2C_SLV2_REG     0x2C //I2C從設(shè)備2的寄存器地址
#define MPU6050_RA_I2C_SLV2_CTRL    0x2D //I2C從設(shè)備2的控制設(shè)置
#define MPU6050_RA_I2C_SLV3_ADDR    0x2E //I2C從設(shè)備3的地址
#define MPU6050_RA_I2C_SLV3_REG     0x2F //I2C從設(shè)備3的寄存器地址
#define MPU6050_RA_I2C_SLV3_CTRL    0x30 //I2C從設(shè)備3的控制設(shè)置
#define MPU6050_RA_I2C_SLV4_ADDR    0x31 //I2C從設(shè)備4的地址
#define MPU6050_RA_I2C_SLV4_REG     0x32 //I2C從設(shè)備4的寄存器地址
#define MPU6050_RA_I2C_SLV4_DO      0x33 //I2C從設(shè)備4的寫數(shù)據(jù)
#define MPU6050_RA_I2C_SLV4_CTRL    0x34 //I2C從設(shè)備4的控制設(shè)置
#define MPU6050_RA_I2C_SLV4_DI      0x35 //I2C從設(shè)備4的讀數(shù)據(jù)
#define MPU6050_RA_I2C_MST_STATUS   0x36 //I2C主機狀態(tài)寄存器

#define MPU6050_RA_INT_PIN_CFG      0x37 //中斷引腳配置寄存器
#define MPU6050_RA_INT_ENABLE       0x38 //中斷使能寄存器
#define MPU6050_RA_DMP_INT_STATUS   0x39 //DMP中斷狀態(tài)寄存器
#define MPU6050_RA_INT_STATUS       0x3A //中斷狀態(tài)寄存器

#define MPU6050_RA_ACCEL_XOUT_H     0x3B //X軸加速度輸出高位字節(jié)
#define MPU6050_RA_ACCEL_XOUT_L     0x3C //X軸加速度輸出低位字節(jié)
#define MPU6050_RA_ACCEL_YOUT_H     0x3D //Y軸加速度輸出高位字節(jié)
#define MPU6050_RA_ACCEL_YOUT_L     0x3E //Y軸加速度輸出低位字節(jié)
#define MPU6050_RA_ACCEL_ZOUT_H     0x3F //Z軸加速度輸出高位字節(jié)
#define MPU6050_RA_ACCEL_ZOUT_L     0x40 //Z軸加速度輸出低位字節(jié)
#define MPU6050_RA_TEMP_OUT_H       0x41 //溫度輸出高位字節(jié)
#define MPU6050_RA_TEMP_OUT_L       0x42 //溫度輸出低位字節(jié)
#define MPU6050_RA_GYRO_XOUT_H      0x43 //X軸陀螺儀輸出高位字節(jié)
#define MPU6050_RA_GYRO_XOUT_L      0x44 //X軸陀螺儀輸出低位字節(jié)
#define MPU6050_RA_GYRO_YOUT_H      0x45 //Y軸陀螺儀輸出高位字節(jié)
#define MPU6050_RA_GYRO_YOUT_L      0x46 //Y軸陀螺儀輸出低位字節(jié)
#define MPU6050_RA_GYRO_ZOUT_H      0x47 //Z軸陀螺儀輸出高位字節(jié)
#define MPU6050_RA_GYRO_ZOUT_L      0x48 //Z軸陀螺儀輸出低位字節(jié)

//外部傳感器數(shù)據(jù)寄存器
#define MPU6050_RA_EXT_SENS_DATA_00 0x49 //
#define MPU6050_RA_EXT_SENS_DATA_01 0x4A //
#define MPU6050_RA_EXT_SENS_DATA_02 0x4B //
#define MPU6050_RA_EXT_SENS_DATA_03 0x4C //
#define MPU6050_RA_EXT_SENS_DATA_04 0x4D //
#define MPU6050_RA_EXT_SENS_DATA_05 0x4E //
#define MPU6050_RA_EXT_SENS_DATA_06 0x4F //
#define MPU6050_RA_EXT_SENS_DATA_07 0x50 //
#define MPU6050_RA_EXT_SENS_DATA_08 0x51 //
#define MPU6050_RA_EXT_SENS_DATA_09 0x52 //
#define MPU6050_RA_EXT_SENS_DATA_10 0x53 //
#define MPU6050_RA_EXT_SENS_DATA_11 0x54 //
#define MPU6050_RA_EXT_SENS_DATA_12 0x55 //
#define MPU6050_RA_EXT_SENS_DATA_13 0x56 //
#define MPU6050_RA_EXT_SENS_DATA_14 0x57 //
#define MPU6050_RA_EXT_SENS_DATA_15 0x58 //
#define MPU6050_RA_EXT_SENS_DATA_16 0x59 //
#define MPU6050_RA_EXT_SENS_DATA_17 0x5A //
#define MPU6050_RA_EXT_SENS_DATA_18 0x5B //
#define MPU6050_RA_EXT_SENS_DATA_19 0x5C //
#define MPU6050_RA_EXT_SENS_DATA_20 0x5D //
#define MPU6050_RA_EXT_SENS_DATA_21 0x5E //
#define MPU6050_RA_EXT_SENS_DATA_22 0x5F //
#define MPU6050_RA_EXT_SENS_DATA_23 0x60 //


#define MPU6050_RA_MOT_DETECT_STATUS    0x61 //運動檢測狀態(tài)寄存器
#define MPU6050_RA_I2C_SLV0_DO      0x63 //I2C從機0數(shù)據(jù)輸出寄存器
#define MPU6050_RA_I2C_SLV1_DO      0x64 //I2C從機1數(shù)據(jù)輸出寄存器
#define MPU6050_RA_I2C_SLV2_DO      0x65 //I2C從機2數(shù)據(jù)輸出寄存器
#define MPU6050_RA_I2C_SLV3_DO      0x66 //I2C從設(shè)備3的數(shù)據(jù)寄存器地址
#define MPU6050_RA_I2C_MST_DELAY_CTRL   0x67 //信號路徑重置寄存器地址
#define MPU6050_RA_SIGNAL_PATH_RESET    0x68 //運動檢測控制寄存器地址
#define MPU6050_RA_MOT_DETECT_CTRL      0x69 //用戶控制寄存器地址
#define MPU6050_RA_USER_CTRL        0x6A //電源管理1寄存器地址
#define MPU6050_RA_PWR_MGMT_1       0x6B //電源管理2寄存器地址
#define MPU6050_RA_PWR_MGMT_2       0x6C //寄存器銀行選擇寄存器地址
#define MPU6050_RA_BANK_SEL         0x6D //內(nèi)存起始地址寄存器地址
#define MPU6050_RA_MEM_START_ADDR   0x6E //內(nèi)存讀/寫寄存器地址
#define MPU6050_RA_MEM_R_W          0x6F //DMP配置1寄存器地址
#define MPU6050_RA_DMP_CFG_1        0x70 //DMP配置2寄存器地址
#define MPU6050_RA_DMP_CFG_2        0x71 //FIFO計數(shù)高字節(jié)寄存器地址
#define MPU6050_RA_FIFO_COUNTH      0x72 //FIFO計數(shù)低字節(jié)寄存器地址
#define MPU6050_RA_FIFO_COUNTL      0x73 //FIFO讀/寫寄存器地址
#define MPU6050_RA_FIFO_R_W         0x74 //FIFO讀/寫寄存器地址
#define MPU6050_RA_WHO_AM_I         0x75 //器件ID寄存器地址

#define MPU6050_TC_PWR_MODE_BIT     7 //TC_PWR_MODE位,用于選擇電源模式
#define MPU6050_TC_OFFSET_BIT       6 //TC_OFFSET位,用于設(shè)置溫度傳感器的偏移
#define MPU6050_TC_OFFSET_LENGTH    6 //TC_OFFSET字段的長度
#define MPU6050_TC_OTP_BNK_VLD_BIT  0 //TC_OTP_BNK_VLD位,用于驗證OTP存儲的攝氏度系數(shù)是否有效

#define MPU6050_VDDIO_LEVEL_VLOGIC  0 //VDDIO電平模式,表示VLOGIC級別
#define MPU6050_VDDIO_LEVEL_VDD     1 //VDDIO電平模式,表示VDD級別

#define MPU6050_CFG_EXT_SYNC_SET_BIT    5 //EXT_SYNC_SET位,用于選擇外部同步信號
#define MPU6050_CFG_EXT_SYNC_SET_LENGTH 3 //EXT_SYNC_SET字段的長度
#define MPU6050_CFG_DLPF_CFG_BIT    2 //DLPF_CFG位,用于選擇數(shù)字低通濾波器配置
#define MPU6050_CFG_DLPF_CFG_LENGTH 3 //DLPF_CFG字段的長度

#define MPU6050_EXT_SYNC_DISABLED       0x0 //禁用外部同步信號
#define MPU6050_EXT_SYNC_TEMP_OUT_L     0x1 //外部同步信號為溫度輸出的低字節(jié)
#define MPU6050_EXT_SYNC_GYRO_XOUT_L    0x2 //外部同步信號為陀螺儀X軸輸出的低字節(jié)
#define MPU6050_EXT_SYNC_GYRO_YOUT_L    0x3 //外部同步信號為陀螺儀Y軸輸出的低字節(jié)
#define MPU6050_EXT_SYNC_GYRO_ZOUT_L    0x4 //外部同步信號為陀螺儀Z軸輸出的低字節(jié)
#define MPU6050_EXT_SYNC_ACCEL_XOUT_L   0x5 //外部同步信號為加速度計X軸輸出的低字節(jié)
#define MPU6050_EXT_SYNC_ACCEL_YOUT_L   0x6 //外部同步信號為加速度計Y軸輸出的低字節(jié)
#define MPU6050_EXT_SYNC_ACCEL_ZOUT_L   0x7 //外部同步信號為加速度計Z軸輸出的低字節(jié)

#define MPU6050_DLPF_BW_256         0x00 //
#define MPU6050_DLPF_BW_188         0x01 //
#define MPU6050_DLPF_BW_98          0x02 //
#define MPU6050_DLPF_BW_42          0x03 //
#define MPU6050_DLPF_BW_20          0x04 //
#define MPU6050_DLPF_BW_10          0x05 //
#define MPU6050_DLPF_BW_5           0x06 //

#define MPU6050_GCONFIG_FS_SEL_BIT      4
#define MPU6050_GCONFIG_FS_SEL_LENGTH   2

#define MPU6050_GYRO_FS_250         0x00
#define MPU6050_GYRO_FS_500         0x01
#define MPU6050_GYRO_FS_1000        0x02
#define MPU6050_GYRO_FS_2000        0x03

#define MPU6050_ACONFIG_XA_ST_BIT           7
#define MPU6050_ACONFIG_YA_ST_BIT           6
#define MPU6050_ACONFIG_ZA_ST_BIT           5
#define MPU6050_ACONFIG_AFS_SEL_BIT         4
#define MPU6050_ACONFIG_AFS_SEL_LENGTH      2
#define MPU6050_ACONFIG_ACCEL_HPF_BIT       2
#define MPU6050_ACONFIG_ACCEL_HPF_LENGTH    3

#define MPU6050_ACCEL_FS_2          0x00
#define MPU6050_ACCEL_FS_4          0x01
#define MPU6050_ACCEL_FS_8          0x02
#define MPU6050_ACCEL_FS_16         0x03

#define MPU6050_DHPF_RESET          0x00
#define MPU6050_DHPF_5              0x01
#define MPU6050_DHPF_2P5            0x02
#define MPU6050_DHPF_1P25           0x03
#define MPU6050_DHPF_0P63           0x04
#define MPU6050_DHPF_HOLD           0x07

#define MPU6050_TEMP_FIFO_EN_BIT    7
#define MPU6050_XG_FIFO_EN_BIT      6
#define MPU6050_YG_FIFO_EN_BIT      5
#define MPU6050_ZG_FIFO_EN_BIT      4
#define MPU6050_ACCEL_FIFO_EN_BIT   3
#define MPU6050_SLV2_FIFO_EN_BIT    2
#define MPU6050_SLV1_FIFO_EN_BIT    1
#define MPU6050_SLV0_FIFO_EN_BIT    0

#define MPU6050_MULT_MST_EN_BIT     7
#define MPU6050_WAIT_FOR_ES_BIT     6
#define MPU6050_SLV_3_FIFO_EN_BIT   5
#define MPU6050_I2C_MST_P_NSR_BIT   4
#define MPU6050_I2C_MST_CLK_BIT     3
#define MPU6050_I2C_MST_CLK_LENGTH  4

#define MPU6050_CLOCK_DIV_348       0x0
#define MPU6050_CLOCK_DIV_333       0x1
#define MPU6050_CLOCK_DIV_320       0x2
#define MPU6050_CLOCK_DIV_308       0x3
#define MPU6050_CLOCK_DIV_296       0x4
#define MPU6050_CLOCK_DIV_286       0x5
#define MPU6050_CLOCK_DIV_276       0x6
#define MPU6050_CLOCK_DIV_267       0x7
#define MPU6050_CLOCK_DIV_258       0x8
#define MPU6050_CLOCK_DIV_500       0x9
#define MPU6050_CLOCK_DIV_471       0xA
#define MPU6050_CLOCK_DIV_444       0xB
#define MPU6050_CLOCK_DIV_421       0xC
#define MPU6050_CLOCK_DIV_400       0xD
#define MPU6050_CLOCK_DIV_381       0xE
#define MPU6050_CLOCK_DIV_364       0xF

#define MPU6050_I2C_SLV_RW_BIT      7
#define MPU6050_I2C_SLV_ADDR_BIT    6
#define MPU6050_I2C_SLV_ADDR_LENGTH 7
#define MPU6050_I2C_SLV_EN_BIT      7
#define MPU6050_I2C_SLV_BYTE_SW_BIT 6
#define MPU6050_I2C_SLV_REG_DIS_BIT 5
#define MPU6050_I2C_SLV_GRP_BIT     4
#define MPU6050_I2C_SLV_LEN_BIT     3
#define MPU6050_I2C_SLV_LEN_LENGTH  4

#define MPU6050_I2C_SLV4_RW_BIT         7
#define MPU6050_I2C_SLV4_ADDR_BIT       6
#define MPU6050_I2C_SLV4_ADDR_LENGTH    7
#define MPU6050_I2C_SLV4_EN_BIT         7
#define MPU6050_I2C_SLV4_INT_EN_BIT     6
#define MPU6050_I2C_SLV4_REG_DIS_BIT    5
#define MPU6050_I2C_SLV4_MST_DLY_BIT    4
#define MPU6050_I2C_SLV4_MST_DLY_LENGTH 5

#define MPU6050_MST_PASS_THROUGH_BIT    7
#define MPU6050_MST_I2C_SLV4_DONE_BIT   6
#define MPU6050_MST_I2C_LOST_ARB_BIT    5
#define MPU6050_MST_I2C_SLV4_NACK_BIT   4
#define MPU6050_MST_I2C_SLV3_NACK_BIT   3
#define MPU6050_MST_I2C_SLV2_NACK_BIT   2
#define MPU6050_MST_I2C_SLV1_NACK_BIT   1
#define MPU6050_MST_I2C_SLV0_NACK_BIT   0

#define MPU6050_INTCFG_INT_LEVEL_BIT        7
#define MPU6050_INTCFG_INT_OPEN_BIT         6
#define MPU6050_INTCFG_LATCH_INT_EN_BIT     5
#define MPU6050_INTCFG_INT_RD_CLEAR_BIT     4
#define MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT  3
#define MPU6050_INTCFG_FSYNC_INT_EN_BIT     2
#define MPU6050_INTCFG_I2C_BYPASS_EN_BIT    1
#define MPU6050_INTCFG_CLKOUT_EN_BIT        0

#define MPU6050_INTMODE_ACTIVEHIGH  0x00
#define MPU6050_INTMODE_ACTIVELOW   0x01

#define MPU6050_INTDRV_PUSHPULL     0x00
#define MPU6050_INTDRV_OPENDRAIN    0x01

#define MPU6050_INTLATCH_50USPULSE  0x00
#define MPU6050_INTLATCH_WAITCLEAR  0x01

#define MPU6050_INTCLEAR_STATUSREAD 0x00
#define MPU6050_INTCLEAR_ANYREAD    0x01

#define MPU6050_INTERRUPT_FF_BIT            7
#define MPU6050_INTERRUPT_MOT_BIT           6
#define MPU6050_INTERRUPT_ZMOT_BIT          5
#define MPU6050_INTERRUPT_FIFO_OFLOW_BIT    4
#define MPU6050_INTERRUPT_I2C_MST_INT_BIT   3
#define MPU6050_INTERRUPT_PLL_RDY_INT_BIT   2
#define MPU6050_INTERRUPT_DMP_INT_BIT       1
#define MPU6050_INTERRUPT_DATA_RDY_BIT      0

// TODO: figure out what these actually do
// UMPL source code is not very obivous
#define MPU6050_DMPINT_5_BIT            5
#define MPU6050_DMPINT_4_BIT            4
#define MPU6050_DMPINT_3_BIT            3
#define MPU6050_DMPINT_2_BIT            2
#define MPU6050_DMPINT_1_BIT            1
#define MPU6050_DMPINT_0_BIT            0

#define MPU6050_MOTION_MOT_XNEG_BIT     7
#define MPU6050_MOTION_MOT_XPOS_BIT     6
#define MPU6050_MOTION_MOT_YNEG_BIT     5
#define MPU6050_MOTION_MOT_YPOS_BIT     4
#define MPU6050_MOTION_MOT_ZNEG_BIT     3
#define MPU6050_MOTION_MOT_ZPOS_BIT     2
#define MPU6050_MOTION_MOT_ZRMOT_BIT    0

#define MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT   7
#define MPU6050_DELAYCTRL_I2C_SLV4_DLY_EN_BIT   4
#define MPU6050_DELAYCTRL_I2C_SLV3_DLY_EN_BIT   3
#define MPU6050_DELAYCTRL_I2C_SLV2_DLY_EN_BIT   2
#define MPU6050_DELAYCTRL_I2C_SLV1_DLY_EN_BIT   1
#define MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT   0

#define MPU6050_PATHRESET_GYRO_RESET_BIT    2
#define MPU6050_PATHRESET_ACCEL_RESET_BIT   1
#define MPU6050_PATHRESET_TEMP_RESET_BIT    0

#define MPU6050_DETECT_ACCEL_ON_DELAY_BIT       5
#define MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH    2
#define MPU6050_DETECT_FF_COUNT_BIT             3
#define MPU6050_DETECT_FF_COUNT_LENGTH          2
#define MPU6050_DETECT_MOT_COUNT_BIT            1
#define MPU6050_DETECT_MOT_COUNT_LENGTH         2

#define MPU6050_DETECT_DECREMENT_RESET  0x0
#define MPU6050_DETECT_DECREMENT_1      0x1
#define MPU6050_DETECT_DECREMENT_2      0x2
#define MPU6050_DETECT_DECREMENT_4      0x3

#define MPU6050_USERCTRL_DMP_EN_BIT             7
#define MPU6050_USERCTRL_FIFO_EN_BIT            6
#define MPU6050_USERCTRL_I2C_MST_EN_BIT         5
#define MPU6050_USERCTRL_I2C_IF_DIS_BIT         4
#define MPU6050_USERCTRL_DMP_RESET_BIT          3
#define MPU6050_USERCTRL_FIFO_RESET_BIT         2
#define MPU6050_USERCTRL_I2C_MST_RESET_BIT      1
#define MPU6050_USERCTRL_SIG_COND_RESET_BIT     0

#define MPU6050_PWR1_DEVICE_RESET_BIT   7
#define MPU6050_PWR1_SLEEP_BIT          6
#define MPU6050_PWR1_CYCLE_BIT          5
#define MPU6050_PWR1_TEMP_DIS_BIT       3
#define MPU6050_PWR1_CLKSEL_BIT         2
#define MPU6050_PWR1_CLKSEL_LENGTH      3

#define MPU6050_CLOCK_INTERNAL          0x00 // 內(nèi)部振蕩器作為時鐘源
#define MPU6050_CLOCK_PLL_XGYRO         0x01 //X軸陀螺儀的相位鎖定環(huán)(PLL)作為時鐘源
#define MPU6050_CLOCK_PLL_YGYRO         0x02 //Y軸陀螺儀的相位鎖定環(huán)(PLL)作為時鐘源
#define MPU6050_CLOCK_PLL_ZGYRO         0x03 //Z軸陀螺儀的相位鎖定環(huán)(PLL)作為時鐘源
#define MPU6050_CLOCK_PLL_EXT32K        0x04 //外部32.768kHz晶振作為時鐘源
#define MPU6050_CLOCK_PLL_EXT19M        0x05 //外部19.2MHz晶振作為時鐘源
#define MPU6050_CLOCK_KEEP_RESET        0x07 //保持復(fù)位狀態(tài)

#define MPU6050_PWR2_LP_WAKE_CTRL_BIT       7
#define MPU6050_PWR2_LP_WAKE_CTRL_LENGTH    2
#define MPU6050_PWR2_STBY_XA_BIT            5
#define MPU6050_PWR2_STBY_YA_BIT            4
#define MPU6050_PWR2_STBY_ZA_BIT            3
#define MPU6050_PWR2_STBY_XG_BIT            2
#define MPU6050_PWR2_STBY_YG_BIT            1
#define MPU6050_PWR2_STBY_ZG_BIT            0

#define MPU6050_WAKE_FREQ_1P25      0x0
#define MPU6050_WAKE_FREQ_2P5       0x1
#define MPU6050_WAKE_FREQ_5         0x2
#define MPU6050_WAKE_FREQ_10        0x3

#define MPU6050_BANKSEL_PRFTCH_EN_BIT       6
#define MPU6050_BANKSEL_CFG_USER_BANK_BIT   5
#define MPU6050_BANKSEL_MEM_SEL_BIT         4
#define MPU6050_BANKSEL_MEM_SEL_LENGTH      5

#define MPU6050_WHO_AM_I_BIT        6
#define MPU6050_WHO_AM_I_LENGTH     6

#define MPU6050_DMP_MEMORY_BANKS        8
#define MPU6050_DMP_MEMORY_BANK_SIZE    256
#define MPU6050_DMP_MEMORY_CHUNK_SIZE   16

MPU6050初始化:


//初始化MPU6050
void MPU6050_Init(void)
{
  delay_ms(100);
	MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x00);	    //解除休眠狀態(tài)
	MPU6050_WriteReg(MPU6050_RA_SMPLRT_DIV , 0x07);	    //陀螺儀采樣率,1KHz
	MPU6050_WriteReg(MPU6050_RA_CONFIG , 0x06);	        //低通濾波器的設(shè)置,截止頻率是1K,帶寬是5K
	MPU6050_WriteReg(MPU6050_RA_ACCEL_CONFIG , 0x00);	  //配置加速度傳感器工作在2G模式,不自檢
	MPU6050_WriteReg(MPU6050_RA_GYRO_CONFIG, 0x18);     //陀螺儀自檢及測量范圍,典型值:0x18(不自檢,2000deg/s)
}


//讀取MPU6050的ID
uint8_t MPU6050ReadID(void)
{
	unsigned char Re = 0;
    MPU6050_ReadData(MPU6050_RA_WHO_AM_I,&Re,1);    //讀器件地址
	if(Re != 0x68)
	{
		printf("MPU6050 dectected error!\r\n");
		return 0;
	}
	else
	{
		printf("MPU6050 ID = %d\r\n",Re);
		return 1;
	}
		
}

MPU6050數(shù)據(jù)讀取處理:


// 讀取MPU6050的加速度數(shù)據(jù)
void MPU6050ReadAcc(short *accData)
{
    u8 buf[6];
    MPU6050_ReadData(MPU6050_ACC_OUT, buf, 6);
    accData[0] = ((buf[0] << 8) | buf[1]);
    accData[1] = ((buf[2] << 8) | buf[3]);
    accData[2] = ((buf[4] << 8) | buf[5]);
}

//讀取MPU6050的角加速度數(shù)據(jù)
void MPU6050ReadGyro(short *gyroData)
{
    u8 buf[6];
    MPU6050_ReadData(MPU6050_GYRO_OUT,buf,6);
    gyroData[0] = ((buf[0] << 8) | buf[1]);
    gyroData[1] = ((buf[2] << 8) | buf[3]);
    gyroData[2] = ((buf[4] << 8) | buf[5]);
}

//讀取MPU6050的原始溫度數(shù)據(jù)
void MPU6050ReadTemp(short *tempData)
{
	u8 buf[2];
    MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //讀取溫度值
    *tempData = (buf[0] << 8) | buf[1];
}

//讀取MPU6050的溫度數(shù)據(jù),轉(zhuǎn)化成攝氏度
void MPU6050_ReturnTemp(float *Temperature)
{
	short temp3;
	u8 buf[2];
	
	MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //讀取溫度值
  temp3= (buf[0] << 8) | buf[1];	
	*Temperature=((double) temp3/340.0)+36.53;
}

MPU6050濾波一階互補:

float yijiehubu_R(float angle_m, float gyro_m)//?????????????
{
     angle_R = K1 * angle_m+ (1-K1) * (angle_R + gyro_m * dt);
         return angle_R;
}
float yijiehubu_P(float angle_m, float gyro_m)//?????????????
{
     angle_P = K1 * angle_m+ (1-K1) * (angle_P + gyro_m * dt);
         return angle_P;
}

方位角計算? atan2(X,Y)

坐標方位角是指一個點相對于另一個參考點的方向角度。下面是計算坐標方位角的公式:

假設(shè)要計算從點 A 到點 B 的坐標方位角,點 A 的坐標為 (x1, y1),點 B 的坐標為 (x2, y2)。

1. 計算點 B 相對于點 A 的水平距離 dx = x2 - x1。

2. 計算點 B 相對于點 A 的豎直距離 dy = y2 - y1。

3. 計算坐標方位角 angle = atan2(dy, dx)。

4. 將 angle 的弧度值轉(zhuǎn)化為角度值。

其中, atan2(dy, dx) 是求取反正切值的函數(shù),返回值區(qū)間是(-π, π]。需要注意,因為 atan2函數(shù)的取值范圍不包括負半軸,所以需要做特殊處理,即:

如果 atan2(dy, dx) < 0,則 angle = 360 + atan2(dy, dx)。



作者:知乎用戶
鏈接:https://www.zhihu.com/question/601596103/answer/3032838089
來源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

主函數(shù)代碼:

#include "main.h"

//211

uint16_t t1,t2,t3;
	short Accel[3];
	short Gyro[3];
	float Temp;

	float Angle_Y,Angle_X,Angle_Z;
	int pitch,roll,yaw;

int main(void)
{	
	init_ALL();     //初始化所有函數(shù)
  while(1)
	{	
			MPU6050ReadAcc(Accel);//獲取加速度原始值
			MPU6050ReadGyro(Gyro);//獲取角速度原始值
			MPU6050_ReturnTemp(&Temp);//獲取溫度值	
		
					Angle_X=atan2(Accel[0],Accel[2])*57.3-Gyro[0]/16.4*0.005;//換算
					Angle_Y=atan2(Accel[1],Accel[2])*57.3-Gyro[1]/16.4*0.005;
					
					pitch=(int)yijiehubu_P(Angle_X,Gyro[0]/16.4); //一階互補濾波
					roll=-(int)yijiehubu_R(Angle_Y,Gyro[1]/16.4);	
	}
}


//初始化所有函數(shù):
void init_ALL(void)
{
	Usart1_Init(115200);      //初始化串口1
	printf("HELLO \r\n");   	//串口1 測試重定向Printf
	SysTick_Init(72);
	Timer2_Init();
//  Timer3_PWM_init(2000,719);
	i2c_GPIO_Config();	      //IIC初始化
	MPU6050_Init();           //mpu6050初始化
	MPU6050ReadID();  //讀取器件ID
}

void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{		
//		printf("Angle_X=%lf",Angle_X);
//		printf("\r\n");
//		printf("Angle_Y=%lf",Angle_Y);		
//		printf("\r\n");
		
//		printf("\r\n");
//		printf("Temp=%lf",Temp);
		
		printf("pitch=%d",pitch);
		printf("\r\n");
		printf("roll=%d",roll);		
		printf("\r\n");
		printf("yaw=%d",yaw);
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清出中斷寄存器標志位,用于退出中斷
	}
}

測試結(jié)果:

STM32 F103C8T6學(xué)習(xí)筆記6:IIC通信__驅(qū)動MPU6050 6軸運動處理組件—一階互補濾波,STM32 F103 C8T6筆記,硬件模塊與傳感器的驅(qū)動,stm32,學(xué)習(xí),筆記

工程下載:

https://download.csdn.net/download/qq_64257614/88212554?spm=1001.2014.3001.5503文章來源地址http://www.zghlxwxcb.cn/news/detail-645476.html

到了這里,關(guān)于STM32 F103C8T6學(xué)習(xí)筆記6:IIC通信__驅(qū)動MPU6050 6軸運動處理組件—一階互補濾波的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • STM32 F103C8T6學(xué)習(xí)筆記4:時鐘樹、滴答計時器、定時器定時中斷

    STM32 F103C8T6學(xué)習(xí)筆記4:時鐘樹、滴答計時器、定時器定時中斷

    今日理解一下STM32F103 C8T6的時鐘與時鐘系統(tǒng)、滴答計時器、定時器計時中斷的配置,文章提供原理,代碼,測試工程下載。 目錄 時鐘樹與時鐘系統(tǒng): 滴答計時器: 定時器計時中斷: 測試結(jié)果: 測試工程下載: 該系統(tǒng)介紹在 STM32F10x-中文參考手冊 P56頁開始 微控制器的時鐘系

    2024年02月13日
    瀏覽(32)
  • STM32 F103C8T6學(xué)習(xí)筆記8:0.96寸單色OLED顯示屏顯示字符

    STM32 F103C8T6學(xué)習(xí)筆記8:0.96寸單色OLED顯示屏顯示字符

    使用STM32F103 C8T6 驅(qū)動0.96寸單色OLED顯示屏: OLED顯示屏的驅(qū)動,在設(shè)計開發(fā)中OLED顯示屏十分常見,因此今日學(xué)習(xí)一下。一篇文章從程序到顯示都講通。 文章提供源碼、原理解釋、測試工程下載,測試效果圖展示。 ? 目錄 OLED驅(qū)動原理—IIC通信: SSD1306 單色 0.96 OLED 顯示屏特性

    2024年02月12日
    瀏覽(23)
  • STM32 F103C8T6學(xué)習(xí)筆記13:IIC通信—AHT10溫濕度傳感器模塊

    STM32 F103C8T6學(xué)習(xí)筆記13:IIC通信—AHT10溫濕度傳感器模塊

    今日學(xué)習(xí)一下這款A(yù)HT10 溫濕度傳感器模塊,給我的OLED手環(huán)添加上測溫濕度的功能。 文章提供源碼、測試工程下載、測試效果圖。 目錄 AHT10溫濕度傳感器: 特性: 連接方式: 適用場所范圍: 程序設(shè)計: 設(shè)計目標: ?程序設(shè)計注意點: AHT10代碼: ?主函數(shù)代碼: 測試效果:

    2024年02月11日
    瀏覽(26)
  • STM32 F103C8T6學(xué)習(xí)筆記2:GPIO的認識—GPIO的基本輸入輸出—點亮一個LED

    STM32 F103C8T6學(xué)習(xí)筆記2:GPIO的認識—GPIO的基本輸入輸出—點亮一個LED

    今日繼續(xù)學(xué)習(xí)使用? STM32 F103C8T6開發(fā)板 點亮一個LED燈,文章提供源碼,測試工程,實驗效果圖,希望我的歸納總結(jié)會對大家有幫助~ 目錄 GPIO的認識與分類 : 引腳安排整理: 定時器的引腳例舉: 串口的引腳例舉: ?CAN串口通信: SPI通信: IIC通信: ?其余引腳: 燒錄引腳:

    2024年02月11日
    瀏覽(19)
  • STM32 F103C8T6學(xué)習(xí)筆記5:定時器輸出不同占空比PWM驅(qū)動舵機旋轉(zhuǎn)角度

    現(xiàn)在學(xué)習(xí)使用STM32 F103C8T6的定時器PWM模式,使用PWM驅(qū)動舵機轉(zhuǎn)動不同角度,文章提供源碼,測試工程,測試動態(tài)效果圖。 目錄 基礎(chǔ)原理: ?實驗?zāi)繕耍?測試視頻結(jié)果: 測試工程下載: 這次依舊拿出之前學(xué)習(xí)過的舵機DS3115,它的基礎(chǔ)原理不多加介紹,在往期講MSP432的文章有所

    2024年02月13日
    瀏覽(25)
  • STM32 HAL庫 CubeMX配置 定時器學(xué)習(xí) F103C8T6

    STM32 HAL庫 CubeMX配置 定時器學(xué)習(xí) F103C8T6

    開發(fā)板: STM32F103C8T6最小系統(tǒng)板 編譯環(huán)境: Keil5 MDK 輔助軟件: STM32 CubeMX 課程教學(xué): 基于正點原子HAL庫學(xué)習(xí)教程 其余配件: 江科大STM32配件包?和 示波器一臺 備注: ?因為這塊開發(fā)板沒有基本定時器,所以本文也 沒有基本定時器的內(nèi)容 ????????????本文1.3和2.1部分的

    2024年04月26日
    瀏覽(21)
  • STM32 F103C8T6學(xué)習(xí)筆記10:OLED顯示屏GIF動圖取?!喴讜r鐘—動圖手表的制作~

    STM32 F103C8T6學(xué)習(xí)筆記10:OLED顯示屏GIF動圖取?!喴讜r鐘—動圖手表的制作~

    今日嘗試做一款有動圖的OLED實時時鐘,本文需要現(xiàn)學(xué)一個OLED的GIF動圖取模 其余需要的知識點有不會的可以去我? STM32 F103C8T6學(xué)習(xí)筆記? 系列專欄自己查閱把,閑話不多,直接開肝~~~ 文章提供源碼,測試工程下載,測試效果圖。 做個簡易的時鐘,就不把RTC實時時鐘放進來學(xué)了

    2024年02月12日
    瀏覽(41)
  • STM32 F103C8T6學(xué)習(xí)筆記6:IIC通信__驅(qū)動MPU6050 6軸運動處理組件—一階互補濾波

    STM32 F103C8T6學(xué)習(xí)筆記6:IIC通信__驅(qū)動MPU6050 6軸運動處理組件—一階互補濾波

    今日主要學(xué)習(xí)一款傾角傳感器——MPU6050,往后對單片機原理基礎(chǔ)講的會比較少,更傾向于簡單粗暴地貼代碼,因為經(jīng)過前些日子對MSP432的學(xué)習(xí),對原理方面也有些熟絡(luò)了,除了在新接觸它時會對其引腳、時鐘、總線等進行仔細一些的研究之外,其余驅(qū)動方面便是照搬經(jīng)驗了~

    2024年02月13日
    瀏覽(23)
  • STM32 F103C8T6學(xué)習(xí)筆記9:0.96寸單色OLED顯示屏—自由取模顯示—顯示漢字與圖片

    STM32 F103C8T6學(xué)習(xí)筆記9:0.96寸單色OLED顯示屏—自由取模顯示—顯示漢字與圖片

    今日學(xué)習(xí)0.96寸單色OLED顯示屏的自由取模顯示: 宋體漢字比較復(fù)雜,常用字符可以直接復(fù)制存下來,畢竟只有那么幾十個字母字符,但漢字實在太多了,基本不會全部放在單片機里存著,一般用到多少個字就取幾個字的模,因此漢字放在這里與自由取模一起講。 文章提供源碼

    2024年02月11日
    瀏覽(25)
  • STM32系列(HAL庫)——F103C8T6獲取DHT11溫濕度串口打印

    STM32系列(HAL庫)——F103C8T6獲取DHT11溫濕度串口打印

    在此特別鳴謝原文博主! (1)編程平臺:Keil5 (2)CubeMX (3)XCOM(串口調(diào)試助手) (1)F1的板子,本例使用經(jīng)典F103C8T6 ?(2)DHT11——溫濕度傳感器 (3)ST-link?下載器 (4)USB-TTL模塊 (5)杜邦線若干 (1)芯片選擇 STM32F103C8T6 ?(2)配置RCC、SYS、時鐘樹 配置RCC 配置SYS 配置時鐘樹 (3) 配置GPIO ?(4)配置

    2023年04月08日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包