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

單片機(jī)開(kāi)發(fā)教程3——串口發(fā)送MPU6050姿態(tài)角

這篇具有很好參考價(jià)值的文章主要介紹了單片機(jī)開(kāi)發(fā)教程3——串口發(fā)送MPU6050姿態(tài)角。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1. 簡(jiǎn)介

MPU6050 是 InvenSense 公司推出的整合性 6 軸運(yùn)動(dòng)處理組件,其內(nèi)部整合了 3 軸陀螺儀和 3 軸加速度傳感器,并且含有一個(gè)IIC 接口, 可用于連接外部磁力傳感器,并利用自帶的數(shù)字運(yùn)動(dòng)處理器(DMP: Digital Motion Processor) 硬件加速引擎,通過(guò)主 IIC 接口,向應(yīng)用端輸出完整的 9 軸融合演算數(shù)據(jù)。

InvenSense 公司提供了一套基于DMP的運(yùn)動(dòng)處理驅(qū)動(dòng)庫(kù),可大大降低單片機(jī)對(duì)動(dòng)處理運(yùn)算的負(fù)荷,同時(shí)也大大降低了編程難度。該模塊廣泛運(yùn)用于飛控、計(jì)步等電子產(chǎn)品中。

1.1 模塊原理圖

開(kāi)源mpu6050串口通信,單片機(jī)

1.2 引腳說(shuō)明

序號(hào) 引腳 說(shuō)明
1 VCC 3.3V/5V
2 GND 地線
3 SCL 作為從機(jī)時(shí) IIC 時(shí)鐘線
4 SDA 作為從機(jī)時(shí) IIC 數(shù)據(jù)線
5 XDA 作為主機(jī)時(shí) IIC 數(shù)據(jù)線
6 XCL 作為主機(jī)時(shí) IIC 時(shí)鐘線
7 AD0 作為從機(jī)時(shí) IIC 地址
8 INT 中斷輸出引腳

XDA和XCL是在MPU6050作為主機(jī)時(shí)的信號(hào)線,在與單片機(jī)的IIC通信中,MPU6050作為從機(jī),所以用不到

AD0 是從 IIC 接口(接 MCU)的地址控制引腳,該引腳控制IIC 地址的最低位。由原理圖可知,AD0 接了 GND,所以 MPU6050 的 IIC 地址默認(rèn)為:0X68

INT也用不到,當(dāng)模塊需要輸出數(shù)據(jù)時(shí),可以通過(guò)該引腳給單片機(jī)中斷信號(hào),一般都不需要

1.3 接線方式

單片機(jī) —— MPU6050

5V <——> VCC
GND <——> GND
Px.x <——> SCL
Px.x <——> SDA

2. IIC通信

如果你學(xué)過(guò)一段時(shí)間單片機(jī),你或多或少會(huì)聽(tīng)說(shuō)過(guò)IIC通信(也寫(xiě)作I2C,通常讀作:I方C),這是硬件開(kāi)發(fā)里很常見(jiàn)、很常用的一種通信協(xié)議。

其實(shí)協(xié)議并不是聽(tīng)上去的那么高不可攀,它終究是人為定義的一個(gè)標(biāo)準(zhǔn)而已,我們只需遵循這個(gè)標(biāo)準(zhǔn)就可以了。

這里面的協(xié)議層會(huì)涉及到時(shí)序,如果你還不是“老司機(jī)”,暫且可以放下不去專研,因?yàn)檫@些都會(huì)被封裝為函數(shù),使用格式也非常固定,完全不必?fù)?dān)心。比如通信中最頻繁的 讀寫(xiě)操作 ,會(huì)被封裝成 IIC讀/寫(xiě)函數(shù) ,而讀寫(xiě)只能算是最基礎(chǔ)的操作,還可以利用它進(jìn)一步封裝成各種設(shè)置函數(shù)和數(shù)據(jù)采集函數(shù)。

2.1 IIC介紹

I2C(Inter-Integrated Circuit)總線是由 PHILIPS 公司開(kāi)發(fā)的兩線式串行總線,用于連接微控制器及其外圍設(shè)備。是微電子通信控制領(lǐng)域廣泛采用的一種總線標(biāo)準(zhǔn)。它是 同步通信的一種特殊形式,具有接口線少,控制方式簡(jiǎn)單, 器件封裝形式小,通信速率較高等優(yōu)點(diǎn)。 I2C 總線 只有 兩根雙向信號(hào)線 。一根是 數(shù)據(jù)線 SDA ,另一根是 時(shí)鐘線 SCL 。由于其管腳少,硬件實(shí)現(xiàn)簡(jiǎn)單,可擴(kuò)展性強(qiáng)等特點(diǎn),因此被廣泛的使用在各大集成芯片內(nèi)。

2.2 例程講解

開(kāi)發(fā)資料中的例程代碼雖然很多,但最后在main函數(shù)里對(duì)MPU6050操作的只有兩個(gè)函數(shù),其他函數(shù)大多作為這兩個(gè)函數(shù)的內(nèi)容。其實(shí),對(duì)于這種不小的工程項(xiàng)目,我們往往會(huì)寫(xiě)成多個(gè)文件,方便查看和使用,這就涉及到了工程項(xiàng)目的管理,后續(xù)可能還會(huì)出一篇教程 (>﹏<)

// 初始化MPU6050
void InitMPU6050()
{
	Single_WriteI2C(PWR_MGMT_1, 0x00);	// #define PWR_MGMT_1 0x6B
	Single_WriteI2C(SMPLRT_DIV, 0x07);	// #define SMPLRT_DIV 0x19
	Single_WriteI2C(CONFIG, 0x06);		// #define CONFIG	  0x1A
	Single_WriteI2C(GYRO_CONFIG, 0x18);	// #define GYRO_CONFIG 0x1B
	Single_WriteI2C(ACCEL_CONFIG, 0x01);// #define ACCEL_CONFIG 0x1C
}

// 合成數(shù)據(jù)
int GetData(uchar REG_Address)
{
	uchar H,L;
	H=Single_ReadI2C(REG_Address);	// 相應(yīng)寄存器地址
	L=Single_ReadI2C(REG_Address+1);
	return ((H<<8)+L);   
}

InitMPU6050 可以初始化模塊,函數(shù)里對(duì)MPU6050的各個(gè)寄存器寫(xiě)入?yún)?shù),從而實(shí)現(xiàn)初始化的功能,如果你想了解寄存器內(nèi)部的配置原理,可以根據(jù)寄存器地址找到它的數(shù)據(jù)手冊(cè)上對(duì)應(yīng)的說(shuō)明

GetData 可以返回采集的數(shù)據(jù),值得注意的是這里得到數(shù)據(jù)不是角度,還需要進(jìn)一步融合數(shù)據(jù)才能解算出姿態(tài)角

3. 姿態(tài)解算

3.1 歐拉角

歐拉角是最直觀的一種姿態(tài)描述方式,所以在談到姿態(tài)時(shí),我們往往會(huì)使用歐拉角表達(dá)

一個(gè)坐標(biāo)系到另一個(gè)坐標(biāo)系的變換,可以通過(guò)繞不同坐標(biāo)軸的3次連續(xù)轉(zhuǎn)動(dòng)來(lái)實(shí)現(xiàn)。這三次的轉(zhuǎn)動(dòng)角度統(tǒng)一稱之為歐拉角

  • 偏航角(Yaw)
    機(jī)體系x軸投影到水平面與參考系x軸的夾角,順時(shí)針旋轉(zhuǎn)為正。

  • 俯仰角(Pitch)
    機(jī)體系x軸與水平面的夾角,抬頭為正。

  • 橫滾角(Roll)
    機(jī)體坐標(biāo)系z(mì)軸與通過(guò)機(jī)體系x軸的鉛垂面間的夾角,機(jī)體右旋為正。

開(kāi)源mpu6050串口通信,單片機(jī)

3.2 解算方法

上面得到數(shù)據(jù)只是10位原始數(shù)據(jù),我們需要把原始數(shù)據(jù)融合成與姿態(tài)有關(guān)的
歐拉角

這里有兩種方法:

第一種是自己添加濾波算法,常用的有一階互補(bǔ)濾波、二階互補(bǔ)濾波和卡爾曼濾波等

第二種是直接使用MPU6050內(nèi)部的DMP

DMP 是什么意思? DMP 就是指 MPU6050 內(nèi)部集成的處理單元,可以直接運(yùn)算出四元數(shù)和姿態(tài),而不再需要另外進(jìn)行數(shù)學(xué)運(yùn)算。DMP 的使用大大簡(jiǎn)化了四軸的代碼設(shè)計(jì)。DMP 是數(shù)字運(yùn)動(dòng)處理器的縮寫(xiě),顧名思義 mpu6050 并不單單是一款傳感器,其內(nèi)部還包含了可以獨(dú)立完成姿態(tài)解算算法的處理單元。如在設(shè)計(jì)中使用 DMP 來(lái)實(shí)現(xiàn)傳感器融合算法優(yōu)勢(shì)很明顯。首先,invensense 官方提供的姿態(tài)解算算法應(yīng)該比像我們自己寫(xiě)的要可靠得多。其次,由 DMP 實(shí)現(xiàn)姿態(tài)解算算法將單片機(jī)從算法處理的壓力中解放出來(lái),單片機(jī)所要做的是等待DMP 解算完成后產(chǎn)生的外部中斷,在外部中斷里去讀取姿態(tài)解算的結(jié)果。這樣單片機(jī)有大量的時(shí)間來(lái)處理其他任務(wù),提高了系統(tǒng)的實(shí)時(shí)性

經(jīng)過(guò) DMP 你就可以得到四元數(shù),四元數(shù)就是 4 個(gè)數(shù),可以表征姿態(tài),經(jīng)過(guò)幾個(gè)數(shù)學(xué)公式之后就可以得出姿態(tài),姿態(tài)包括 pitch,roll,yaw

下面介紹的是第一種方法的一階互補(bǔ)濾波,因?yàn)?1單片機(jī)對(duì)DMP的幾個(gè)庫(kù)函數(shù)不太兼容,或許后面會(huì)嘗試解決并出教程 ╮(╯_╰)╭ ,而第一種算法網(wǎng)上有不少案例,實(shí)際使用上,兩種方法對(duì)于初學(xué)者的難度都差不多

3.3 一階互補(bǔ)濾波

需要注意的是,以下代碼只能得到俯仰和滾轉(zhuǎn)的數(shù)據(jù),偏航角(Yaw)由于偏差太大沒(méi)有輸出值

以下代碼不是完整的,還需要使用開(kāi)發(fā)資料中的例程

//*******************************************************************************************************
//主程序
//*******************************************************************************************************
void main()
{ 

	unsigned int time;	// 保存定時(shí)器計(jì)數(shù)值
	float halfT;	// 每次采樣的時(shí)間
	int Ax,Ay,Az,Gx,Gy,Gz;	// 加速度計(jì)和陀螺儀的原始數(shù)據(jù) 
  	unsigned long Gravity;
	float AngleX1,AngleY1,AngleZ1,AngleX2,AngleY2,AngleZ2=0,dx,dy,dz;
	float Filter;
	Filter=0.8; //互補(bǔ)濾波系數(shù)
	
	delay(500);		//上電延時(shí)
	init_uart();
	InitMPU6050();	初始化MPU6050
	delay(150);
	
	while(1)
	{
		
		Ax=GetData(ACCEL_XOUT_H);
		Ay=GetData(ACCEL_YOUT_H);
		Az=GetData(ACCEL_ZOUT_H);
		Gx=GetData(GYRO_XOUT_H);
		Gy=GetData(GYRO_YOUT_H);
		Gz=GetData(GYRO_ZOUT_H);
		
		TR0 = 0;
		time = (TH0<<8)|TL0;
		halfT = (time/1000000.)*(12/11.0592);
		// Display10BitData((int)(halfT*1000000));	//顯示采樣時(shí)間
		TH0 = 0;
		TL0 = 0;
		TR0 = 1;
		
		Gravity=sqrt((float)Ax*Ax+(float)Ay*Ay+(float)Az*Az);  //Ax*Ax+Ay*Ay+Az*Az
		AngleX1=acos((float)Ax/Gravity)*180.0/3.14-90;;
		AngleY1=acos((float)Ay/Gravity)*180.0/3.14-90;
		AngleZ1=acos((float)Az/Gravity)*180.0/3.14;
		dy=halfT*Gx/-16.4; //陀螺儀測(cè)的轉(zhuǎn)角y
		dx=halfT*Gy/16.4; //陀螺儀測(cè)的轉(zhuǎn)角x
		dz=halfT*Gz/16.4; //陀螺儀測(cè)的轉(zhuǎn)角z

		//x和y軸數(shù)據(jù)是融合加速度計(jì)和陀螺儀數(shù)據(jù), z軸只采用陀螺儀數(shù)據(jù)
		AngleX2=Filter*(AngleX2+dx)+(1-Filter)*AngleX1;        
		AngleY2=Filter*(AngleY2+dy)+(1-Filter)*AngleY1;    
		// z軸數(shù)據(jù)有兩種方式,一種是只使用陀螺儀的數(shù)據(jù),舍棄z軸加速度(z軸零飄嚴(yán)重):
		AngleZ2=AngleZ2+dz;        // 注意MPU6050必須芯片正面朝上
		
		
		SeriPushSend(0x20);SeriPushSend('X'); SeriPushSend(':');
		Display10BitData((int)AngleX2);		//顯示X軸角度
		SeriPushSend(0x20);SeriPushSend('Y'); SeriPushSend(':');
		Display10BitData((int)AngleY2);		//顯示Y軸角度
		SeriPushSend(0x20);SeriPushSend('Z'); SeriPushSend(':');
		Display10BitData((int)AngleZ2);		//顯示Z軸角度
		
		SeriPushSend(0x0d); 
    	SeriPushSend(0x0a);//換行,回車
			
		delay(500);	// 控制采樣頻率
	}
}

4. 串口通信

4.1 概念

串行通訊是指僅用一根接收線和一根發(fā)送線就能將數(shù)據(jù)以位進(jìn)行傳輸?shù)囊环N通訊方式。盡管串行通訊的比按字節(jié)傳輸?shù)牟⑿型ㄐ怕谴诳梢栽趦H僅使用兩根線的情況下就能實(shí)現(xiàn)數(shù)據(jù)的傳輸

典型的串口通信使用3根線完成,分別是地線、發(fā)送、接收。由于串口通信是異步的,所以端口能夠在一根線上發(fā)送數(shù)據(jù)同時(shí)在另一根線上接收數(shù)據(jù)。串口通信最重要的參數(shù)是波特率、數(shù)據(jù)位、停止位和奇偶的校驗(yàn)。對(duì)于兩個(gè)需要進(jìn)行串口通信的端口,這些參數(shù)必須匹配,這也是能夠?qū)崿F(xiàn)串口通訊的前提

我們使用的STC89C516RD+內(nèi)部集成有一個(gè)串行通信口,使用時(shí)只需配置波特率、工作方式和中斷開(kāi)關(guān),因?yàn)檫@塊內(nèi)容比較吃單片機(jī)前面的中斷和定時(shí)器的基礎(chǔ),所以沒(méi)掌握也無(wú)須擔(dān)心,這些都有比較固定的初始化模板,直接使用例程提供的函數(shù)即可

4.2 串口顯示姿態(tài)角

代碼下載到單片機(jī)內(nèi)之后,使用串口助手顯示數(shù)據(jù)

開(kāi)源mpu6050串口通信,單片機(jī)

4.3 接線圖

上電時(shí),MPU6050的綠色電源指示燈亮起,程序下載完成后,串口模塊會(huì)有LED一直閃爍,表示串口通信正在工作

開(kāi)源mpu6050串口通信,單片機(jī)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-633172.html

到了這里,關(guān)于單片機(jī)開(kāi)發(fā)教程3——串口發(fā)送MPU6050姿態(tài)角的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包