加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入

第17章-用6050走直線和轉(zhuǎn)90度功能 平衡車入門-超詳細陀螺儀MPU6050模塊輸出姿態(tài)角

06/24 09:53
3675
服務(wù)支持:
技術(shù)交流群

完成交易后在“購買成功”頁面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗、收獲成長和認同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當前內(nèi)容為數(shù)字版權(quán)作品,購買后不支持退換且無法轉(zhuǎn)移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論
放大
實物圖
  • 方案介紹
    • 第17章-用6050走直線和轉(zhuǎn)90度功能
  • 相關(guān)文件
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜
第17章-用6050走直線和轉(zhuǎn)90度功能 平衡車入門-MPU6050陀螺儀的使用 超詳細陀螺儀MPU6050模塊輸出姿態(tài)角(有完整版源碼)
這個是全網(wǎng)最詳細的STM32項目教學(xué)視頻。
第一篇在這里:
視頻在這里:

STM32智能小車V3-STM32入門教程-openmv與STM32循跡小車-stm32f103c8t6-電賽 嵌入式學(xué)習 PID控制算法 編碼器電機 跟隨

第17章-用6050走直線和轉(zhuǎn)90度功能

17.1-6050姿態(tài)數(shù)據(jù)讀取

STM32讀取6050數(shù)據(jù)

先把我們的參考歷程里面的6050文件復(fù)制過去
在這里插入圖片描述
添加文件
在這里插入圖片描述
在這里插入圖片描述
然后在魔術(shù)棒添加上面兩個的路徑,不再截圖了。
簡單閱讀代碼,知道 我們需要設(shè)置兩個引腳,這兩個引腳使用模擬IIC讀取6050數(shù)據(jù)
1.在mpuiic.c延時使用自己寫的、引腳需要使用兩個先設(shè)置推挽輸出、高電平
在這里插入圖片描述

void mpuiic_Delayus(uint32_t usdelay)
{
  __IO uint32_t Delay = usdelay * (SystemCoreClock /8U/1000U/1000);//SystemCoreClock:系統(tǒng)頻率
  do
  {
    __NOP();//使用空指令延時、移植不同單片機注意__NOP(); 執(zhí)行時間
  }
  while (Delay --);
}
  //MPU IIC 延時函數(shù)
void MPU_IIC_Delay(void)
{
	mpuiic_Delayus(2);
}

//初始化IIC
void MPU_IIC_Init(void)
{					     
//  GPIO_InitTypeDef  GPIO_InitStructure;
//	
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//先使能外設(shè)IO PORTB時鐘 
//		
//  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;	 // 端口配置
//  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽輸出
//  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度為50MHz
//  GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根據(jù)設(shè)定參數(shù)初始化GPIO 
//	
//  GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);						 //PB10,PB11 輸出高	
 
}

使用軟件初始化兩個引腳

6050_SDA–PB9

6050_SCL–PB8
在這里插入圖片描述
PB8-輸出模式-起始輸出高電平
在這里插入圖片描述
PB9 輸出模式 起始狀態(tài)高電平
在這里插入圖片描述
生成代碼

打開我們的代碼,是通過模擬IIC 讀取6050數(shù)據(jù)的,我們知道SDA是模擬IIC的數(shù)據(jù)線 所以通信過程中是再輸入和輸出模式中切換的,但是我們的STM32CubeMX是設(shè)置的輸出,是在哪里更改的模式那?

是通過寄存器設(shè)置的,在mpuiic.h可以看到

刪除掉#include “sys.h”

把這個修改了
在這里插入圖片描述
2.在mpuiic.h更改相內(nèi)容

改成下面這樣的
在這里插入圖片描述

//IO方向設(shè)置 設(shè)置SDA-PB9為輸入或者輸出
#define MPU_SDA_IN()  {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=8<<4;}
#define MPU_SDA_OUT() {GPIOB->CRH&=0XFFFFFF0F;GPIOB->CRH|=3<<4;}
  1. 這是通過按位與后賦值 &=按位或后賦值 |=
  2. 設(shè)置端口配置高寄存器指定位。

先看一個例子
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
更改設(shè)置SDA與SCL電平的宏
在這里插入圖片描述

//IO操作函數(shù)	 
#define MPU_IIC_SCL_Hige    	HAL_GPIO_WritePin(SCL_6050_GPIO_Port,SCL_6050_Pin,GPIO_PIN_SET)//設(shè)置SCL高電平
#define MPU_IIC_SCL_Low      	HAL_GPIO_WritePin(SCL_6050_GPIO_Port,SCL_6050_Pin,GPIO_PIN_RESET)//設(shè)置SCL低電平
#define MPU_IIC_SDA_Hige        HAL_GPIO_WritePin(SDA_6050_GPIO_Port,SDA_6050_Pin,GPIO_PIN_SET)   //設(shè)置SDA高電平
#define MPU_IIC_SDA_Low         HAL_GPIO_WritePin(SDA_6050_GPIO_Port,SDA_6050_Pin,GPIO_PIN_RESET) //設(shè)置SDA低電平
  	 
#define MPU_READ_SDA            HAL_GPIO_ReadPin(SDA_6050_GPIO_Port,SDA_6050_Pin)    //讀SDA電平

更改一下 mupiic.c文件

//把之前的MPU_IIC_SDA=1;	 換成 MPU_IIC_SDA_Hige;
//MPU_IIC_SDA=0;	 換成 MPU_IIC_SDA_Low;
//MPU_IIC_SCL=1;  換成 MPU_IIC_SCL_Hige;
//MPU_IIC_SCL=0;  換成 MPU_IIC_SCL_Low;
//

編譯一下、刪掉沒有用的文件

把u8 替換為uint8_t
在這里插入圖片描述
t替換一下,u8 替換為uint8_t u32替換為uint32_t

可以一個文件一個文件的替換掉,如果整個工程替換其他HAL庫文件內(nèi)容也可能改變了
在這里插入圖片描述
刪除多余的庫文件

注釋掉
在這里插入圖片描述
如果有其他的delay_ms 都替換為HAL_Delay

還有一個錯誤

		if((txd&0x80)>>7) MPU_IIC_SDA_Hige;
		else MPU_IIC_SDA_Low;

在這里插入圖片描述
編譯一下 、沒有錯誤和警告

然后在main.c中定義變量和添加同文件

float pitch,roll,yaw; // 俯仰角 橫滾角 航向角

#include "mpu6050.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h" 

在這里插入圖片描述
替換inv_mpu.h的

#include "stm32f1xx_it.h"

在這里插入圖片描述
初始化6050

  HAL_Delay(500);//延時0.5秒 6050上電穩(wěn)定后初始化
  MPU_Init(); //初始化MPU6050
  while(MPU_Init()!=0);
  while(mpu_dmp_init()!=0);

在這里插入圖片描述
我們通過下面的代碼獲得數(shù)據(jù)

   	sprintf((char *)Usart3String,"pitch:%.2f roll:%.2f yaw:%.2frn",pitch,roll,yaw);//顯示6050數(shù)據(jù)
	HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const  char  *)Usart3String),0xFFFF);//通過串口三輸出字符 strlen:計算字符串大小	
   
   //mpu_dmp_get_data(&pitch,&roll,&yaw);//返回值:0,DMP成功解出歐拉角
    while(mpu_dmp_get_data(&pitch,&roll,&yaw)!=0){}  //這個可以解決經(jīng)常讀不出數(shù)據(jù)的問題

在這里插入圖片描述
然后我看一下 這個Usart3String 現(xiàn)在發(fā)送的大概多大的?
在這里插入圖片描述

uint8_t OledString[50];
uint8_t Usart3String[50];

編譯、燒錄、然后就可以連接手機藍牙,在藍牙軟件查看數(shù)據(jù)了
在這里插入圖片描述

17.2-利用6050直線和90度(有代碼)

為什么小車還是不能走直線

為什么兩個電機轉(zhuǎn)速一樣不能走非常正直線,如何控制小車轉(zhuǎn)彎90度。

當然,我們可以開環(huán)控制,但是控制效果可能不好,受外界影響比較大。

如果我們使用閉環(huán)控制,就要使用一個傳感器來獲得現(xiàn)在小車角度。
在這里插入圖片描述
https://www.bilibili.com/video/BV1UV4y1p7Hd/?spm_id_from=333.337.search-card.all.click

走直線(控制朝一個方向運動)

在pid.c中定義一個姿態(tài)控制使用的PID
在這里插入圖片描述

tPid pidMPU6050YawMovement;  //利用6050偏航角 進行姿態(tài)控制的PID

在這里插入圖片描述

	pidMPU6050YawMovement.actual_val=0.0;
	pidMPU6050YawMovement.target_val=0.00;//設(shè)定姿態(tài)目標值
	pidMPU6050YawMovement.err=0.0;
	pidMPU6050YawMovement.err_last=0.0;
	pidMPU6050YawMovement.err_sum=0.0;
	pidMPU6050YawMovement.Kp=2;//定距離跟隨的Kp大小通過估算PID輸入輸出數(shù)據(jù),確定大概大小,然后在調(diào)試
	pidMPU6050YawMovement.Ki=0;
	pidMPU6050YawMovement.Kd=0;

仿照之前紅外循跡代碼編寫姿態(tài)控制函數(shù)
在這里插入圖片描述

float  g_fMPU6050YawMovePidOut = 0.00f; //姿態(tài)PID運算輸出
float  g_fMPU6050YawMovePidOut1 = 0.00f; //第一個電機控制輸出
float  g_fMPU6050YawMovePidOut2 = 0.00f; //第一個電機控制輸出

走直線程序如下(因為上電初始化時候航向角是0、而且pidMPU6050YawMovementPID結(jié)構(gòu)體的目標值target_val 也是0)
在這里插入圖片描述


//*************MPU6050航向角 PID轉(zhuǎn)向控制*****************//

   	sprintf((char *)Usart3String,"pitch:%.2f roll:%.2f yaw:%.2frn",pitch,roll,yaw);//顯示6050數(shù)據(jù) 俯仰角 橫滾角 航向角
	HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const  char  *)Usart3String),0xFFFF);//通過串口三輸出字符 strlen:計算字符串大小	
   
   //mpu_dmp_get_data(&pitch,&roll,&yaw);//返回值:0,DMP成功解出歐拉角
    while(mpu_dmp_get_data(&pitch,&roll,&yaw)!=0){}  //這個可以解決經(jīng)常讀不出數(shù)據(jù)的問題
	
	
	g_fMPU6050YawMovePidOut = PID_realize(&pidMPU6050YawMovement,yaw);//PID計算輸出目標速度 這個速度,會和基礎(chǔ)速度加減

	g_fMPU6050YawMovePidOut1 = 1.5 + g_fMPU6050YawMovePidOut;//基礎(chǔ)速度加減PID輸出速度
	g_fMPU6050YawMovePidOut2 = 1.5 - g_fMPU6050YawMovePidOut;
	if(g_fMPU6050YawMovePidOut1 >3.5) g_fMPU6050YawMovePidOut1 =3.5;//進行限幅
	if(g_fMPU6050YawMovePidOut1 <0) g_fMPU6050YawMovePidOut1 =0;
	if(g_fMPU6050YawMovePidOut2 >3.5) g_fMPU6050YawMovePidOut2 =3.5;
	if(g_fMPU6050YawMovePidOut2 <0) g_fMPU6050YawMovePidOut2 =0;
	motorPidSetSpeed(g_fMPU6050YawMovePidOut1,g_fMPU6050YawMovePidOut2);

然后調(diào)節(jié)PID參數(shù)

順序 先確定P 正負 然后P大小

然后D正負 然后D大小

最后調(diào)節(jié)的參數(shù)如下
在這里插入圖片描述

	pidMPU6050YawMovement.Kp=0.02;//6050航向角PID運動控制 
	pidMPU6050YawMovement.Ki=0;
	pidMPU6050YawMovement.Kd=0.1;

然后我們把小車放在地上就可以完成一直朝著初始方向前進,如果往側(cè)面推也會馬上矯正。

轉(zhuǎn)彎90度功能(控制轉(zhuǎn)彎角度)

然后我們增加一下,如何旋轉(zhuǎn)90度程序

在串口接收回調(diào)函數(shù)表姿態(tài)PID的目標值
在這里插入圖片描述

extern tPid pidMPU6050YawMovement;  //利用6050偏航角 進行姿態(tài)控制的PID

在這里插入圖片描述

		if(g_ucUsart3ReceiveData == 'H')//轉(zhuǎn)向90度
		{				
			if(pidMPU6050YawMovement.target_val <= 180)pidMPU6050YawMovement.target_val += 90;//目標值
		}
		if(g_ucUsart3ReceiveData == 'I')//轉(zhuǎn)回90度
		{				
			if(pidMPU6050YawMovement.target_val >= -180)pidMPU6050YawMovement.target_val -= 90;//目標值
        }	

然后我們的藍牙APP增加兩個發(fā)送按鈕的設(shè)置
在這里插入圖片描述
現(xiàn)象 是上電小車向初始方向直行,如果推小車車頭方向,小車能夠立馬矯正。

然后連接藍牙發(fā)送轉(zhuǎn)90度 小車會轉(zhuǎn)90度,按下 轉(zhuǎn)回90度小車回轉(zhuǎn)回。

這樣我們就把6050轉(zhuǎn)向程序?qū)懲炅耍旅骈_始 把上面代碼如何結(jié)合一下,然后講解如何增加視覺功能。

聯(lián)系:Q,1930299709

  • 聯(lián)系方式.txt

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風險等級 參考價格 更多信息
XRCGB25M000F3A00R0 1 Murata Manufacturing Co Ltd Parallel - Fundamental Quartz Crystal, 25MHz Nom, ROHS AND REACH COMPLIANT, SMALL, SMD, 3 PIN

ECAD模型

下載ECAD模型
$0.34 查看
M25P05-AVMN6P 1 Rochester Electronics LLC 64KX8 FLASH 2.7V PROM, PDSO8, 0.150 INCH, ROHS COMPLIANT, PLASTIC, SOP-8
$0.79 查看
S29GL256P10FFI020 1 AMD Flash, 16MX16, 100ns, PBGA64,
$9.29 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜