最简单DIY基于STM32F407探索者开发板的MPU6050陀螺仪姿态控制舵机程序
STM32庫函數開發系列文章目錄
第一篇:STM32F103ZET6單片機雙串口互發程序設計與實現
第二篇:最簡單DIY基于STM32單片機的藍牙智能小車設計方案
第三篇:最簡單DIY基于STM32F407探索者開發板的MPU6050陀螺儀姿態控制舵機程序
文章目錄
- STM32庫函數開發系列文章目錄
- 前言
- 一、最簡單DIY基于STM32F407探索者開發板的MPU6050陀螺儀姿態控制舵機程序是什么?
- 二、使用步驟
- 1.準備硬件
- 2.準備正點原子開源的MPU6050的代碼
- 3.準備正點原子PWM輸出的代碼
- 4.修改源碼和組合源碼(這部分原創)
- 三、運行與調試
- 總結
前言
????daodanjishui物聯網核心原創技術之最簡單DIY基于STM32F407探索者開發板的MPU6050陀螺儀姿態控制舵機程序。
????市面上有各種開源STM32舵機控制器,但是有復雜的有簡單的,如果想快速入門stm32f407zgt6姿態傳感器的舵機控制,這個方案會給你一個快捷高效的方案。
一、最簡單DIY基于STM32F407探索者開發板的MPU6050陀螺儀姿態控制舵機程序是什么?
????我記得在“51單片機智能小設計”專欄中講述了51單片機如何通過寄存器激發PWM波控制sg90舵機的博文。但是由于51單片機資源有限,再加上復雜的姿態解算,很難同時完成姿態解算控制舵機的任務,所以誕生了這個博文。
????這次的方案主要是:基于正點原子STM32F407探索者開發板和MPU6050陀螺儀來采集航向角從而使用IO口直接控制一個舵機翻轉。下面請看全家福:
????這次的程序使用的stm32庫函數來編程,說實話也修改了正點原子開發板配套的例程,正點原子移植了arduino版本的IIC控制MPU6050的庫才有了我這個下文,為了實現這個STM32舵機的控制,我查閱了網上很多有關舵機控制的資料和視頻,我幾乎橫掃了全部正點原子關于舵機控制的論壇帖子,有含金量的帖子基本上沒有多少,給出源碼的程序我覺得多多少少有點問題,也踩了很多坑!有些人會說:“daodanjishui你何必那么執著呢?大把arduino的庫給你使用來控制舵機,控制MPU6050,你卻硬要從底層出發去控制舵機!”我說:“一個合格的軟硬件設計工程師至少要攻破底層,才能真正流暢地控制硬件。做到這一點,隨隨便便去控制一個機械手又有何難呢?再寫一個上位機去控制舵機又有何難呢?再多寫一個手機控制舵機的APP又有何難?假如一直在用匿名四軸的上位機調試MPU6050,你能寫一個自己的上位機出來嗎?人家目前不開源,你還能寫出這樣的上位機么?呵呵”。到目前為止,我確實寫出了一個舵機控制的上位機:最簡單DIY基于C#和51單片機上下位機一體化的PCA9685舵機控制程序,總之寫代碼是痛苦的,在這個吃快餐的時代最好的辦法就是復制粘貼“拿來主義”,但是并不是什么都可以拿的,有時候自己去嘗試的時候才發現沒有東西可以拿,只能硬著頭皮擼起袖子加油干。
優酷視頻演示地址:https://v.youku.com/v_show/id_XNTAxMDg2NzE0OA==.html
直接觀看
最簡單DIY基于STM32F407探索者開發板的MPU6050陀螺儀姿態控制舵機程序
二、使用步驟
1.準備硬件
1.1正點原子探索者開發板一個,如果沒有的話用STM32F407ZGT6核心板也可以的,現在美國ST公司禁售該芯片,估計以后這個芯片就被淘汰了。
1.2舵機sg90一個。
1.3MPU6050模塊一個。
1.4正點原子4.3寸電容顯示屏一個。(如果沒有的話可以屏蔽該部分代碼)
2.準備正點原子開源的MPU6050的代碼
我采用庫函數開發,所以代碼直接使用該開發板配套的免費開源源碼進行二次開發。源碼來源:探索者光盤資料\A盤\4,程序源碼\2,標準例程-庫函數版本\實驗32 MPU6050六軸傳感器實驗
代碼如下(示例):
#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "key.h" #include "lcd.h" #include "mpu6050.h" #include "inv_mpu.h" #include "inv_mpu_dmp_motion_driver.h" //ALIENTEK 探索者STM32F407開發板 實驗32 //MPU6050六軸傳感器 實驗 -庫函數版本 //技術支持:www.openedv.com //淘寶店鋪:http://eboard.taobao.com //廣州市星翼電子科技有限公司 //作者:正點原子 @ALIENTEK//串口1發送1個字符 //c:要發送的字符 void usart1_send_char(u8 c) {while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); USART_SendData(USART1,c); } //傳送數據給匿名四軸上位機軟件(V2.6版本) //fun:功能字. 0XA0~0XAF //data:數據緩存區,最多28字節!! //len:data區有效數據個數 void usart1_niming_report(u8 fun,u8*data,u8 len) {u8 send_buf[32];u8 i;if(len>28)return; //最多28字節數據 send_buf[len+3]=0; //校驗數置零send_buf[0]=0X88; //幀頭send_buf[1]=fun; //功能字send_buf[2]=len; //數據長度for(i=0;i<len;i++)send_buf[3+i]=data[i]; //復制數據for(i=0;i<len+3;i++)send_buf[len+3]+=send_buf[i]; //計算校驗和 for(i=0;i<len+4;i++)usart1_send_char(send_buf[i]); //發送數據到串口1 } //發送加速度傳感器數據和陀螺儀數據 //aacx,aacy,aacz:x,y,z三個方向上面的加速度值 //gyrox,gyroy,gyroz:x,y,z三個方向上面的陀螺儀值 void mpu6050_send_data(short aacx,short aacy,short aacz,short gyrox,short gyroy,short gyroz) {u8 tbuf[12]; tbuf[0]=(aacx>>8)&0XFF;tbuf[1]=aacx&0XFF;tbuf[2]=(aacy>>8)&0XFF;tbuf[3]=aacy&0XFF;tbuf[4]=(aacz>>8)&0XFF;tbuf[5]=aacz&0XFF; tbuf[6]=(gyrox>>8)&0XFF;tbuf[7]=gyrox&0XFF;tbuf[8]=(gyroy>>8)&0XFF;tbuf[9]=gyroy&0XFF;tbuf[10]=(gyroz>>8)&0XFF;tbuf[11]=gyroz&0XFF;usart1_niming_report(0XA1,tbuf,12);//自定義幀,0XA1 } //通過串口1上報結算后的姿態數據給電腦 //aacx,aacy,aacz:x,y,z三個方向上面的加速度值 //gyrox,gyroy,gyroz:x,y,z三個方向上面的陀螺儀值 //roll:橫滾角.單位0.01度。 -18000 -> 18000 對應 -180.00 -> 180.00度 //pitch:俯仰角.單位 0.01度。-9000 - 9000 對應 -90.00 -> 90.00 度 //yaw:航向角.單位為0.1度 0 -> 3600 對應 0 -> 360.0度 void usart1_report_imu(short aacx,short aacy,short aacz,short gyrox,short gyroy,short gyroz,short roll,short pitch,short yaw) {u8 tbuf[28]; u8 i;for(i=0;i<28;i++)tbuf[i]=0;//清0tbuf[0]=(aacx>>8)&0XFF;tbuf[1]=aacx&0XFF;tbuf[2]=(aacy>>8)&0XFF;tbuf[3]=aacy&0XFF;tbuf[4]=(aacz>>8)&0XFF;tbuf[5]=aacz&0XFF; tbuf[6]=(gyrox>>8)&0XFF;tbuf[7]=gyrox&0XFF;tbuf[8]=(gyroy>>8)&0XFF;tbuf[9]=gyroy&0XFF;tbuf[10]=(gyroz>>8)&0XFF;tbuf[11]=gyroz&0XFF; tbuf[18]=(roll>>8)&0XFF;tbuf[19]=roll&0XFF;tbuf[20]=(pitch>>8)&0XFF;tbuf[21]=pitch&0XFF;tbuf[22]=(yaw>>8)&0XFF;tbuf[23]=yaw&0XFF;usart1_niming_report(0XAF,tbuf,28);//飛控顯示幀,0XAF } int main(void) { u8 t=0,report=1; //默認開啟上報u8 key;float pitch,roll,yaw; //歐拉角short aacx,aacy,aacz; //加速度傳感器原始數據short gyrox,gyroy,gyroz; //陀螺儀原始數據short temp; //溫度NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置系統中斷優先級分組2delay_init(168); //初始化延時函數uart_init(500000); //初始化串口波特率為500000LED_Init(); //初始化LED KEY_Init(); //初始化按鍵LCD_Init(); //LCD初始化MPU_Init(); //初始化MPU6050POINT_COLOR=RED;//設置字體為紅色 LCD_ShowString(30,50,200,16,16,"Explorer STM32F4"); LCD_ShowString(30,70,200,16,16,"MPU6050 TEST"); LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(30,110,200,16,16,"2014/5/9");while(mpu_dmp_init()){LCD_ShowString(30,130,200,16,16,"MPU6050 Error");delay_ms(200);LCD_Fill(30,130,239,130+16,WHITE);delay_ms(200);}LCD_ShowString(30,130,200,16,16,"MPU6050 OK");LCD_ShowString(30,150,200,16,16,"KEY0:UPLOAD ON/OFF");POINT_COLOR=BLUE;//設置字體為藍色 LCD_ShowString(30,170,200,16,16,"UPLOAD ON "); LCD_ShowString(30,200,200,16,16," Temp: . C"); LCD_ShowString(30,220,200,16,16,"Pitch: . C"); LCD_ShowString(30,240,200,16,16," Roll: . C"); LCD_ShowString(30,260,200,16,16," Yaw : . C"); while(1){key=KEY_Scan(0);if(key==KEY0_PRES){report=!report;if(report)LCD_ShowString(30,170,200,16,16,"UPLOAD ON ");else LCD_ShowString(30,170,200,16,16,"UPLOAD OFF");}if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0){ temp=MPU_Get_Temperature(); //得到溫度值MPU_Get_Accelerometer(&aacx,&aacy,&aacz); //得到加速度傳感器數據MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz); //得到陀螺儀數據if(report)mpu6050_send_data(aacx,aacy,aacz,gyrox,gyroy,gyroz);//用自定義幀發送加速度和陀螺儀原始數據if(report)usart1_report_imu(aacx,aacy,aacz,gyrox,gyroy,gyroz,(int)(roll*100),(int)(pitch*100),(int)(yaw*10));if((t%10)==0){ if(temp<0){LCD_ShowChar(30+48,200,'-',16,0); //顯示負號temp=-temp; //轉為正數}else LCD_ShowChar(30+48,200,' ',16,0); //去掉負號 LCD_ShowNum(30+48+8,200,temp/100,3,16); //顯示整數部分 LCD_ShowNum(30+48+40,200,temp%10,1,16); //顯示小數部分 temp=pitch*10;if(temp<0){LCD_ShowChar(30+48,220,'-',16,0); //顯示負號temp=-temp; //轉為正數}else LCD_ShowChar(30+48,220,' ',16,0); //去掉負號 LCD_ShowNum(30+48+8,220,temp/10,3,16); //顯示整數部分 LCD_ShowNum(30+48+40,220,temp%10,1,16); //顯示小數部分 temp=roll*10;if(temp<0){LCD_ShowChar(30+48,240,'-',16,0); //顯示負號temp=-temp; //轉為正數}else LCD_ShowChar(30+48,240,' ',16,0); //去掉負號 LCD_ShowNum(30+48+8,240,temp/10,3,16); //顯示整數部分 LCD_ShowNum(30+48+40,240,temp%10,1,16); //顯示小數部分 temp=yaw*10;if(temp<0){LCD_ShowChar(30+48,260,'-',16,0); //顯示負號temp=-temp; //轉為正數}else LCD_ShowChar(30+48,260,' ',16,0); //去掉負號 LCD_ShowNum(30+48+8,260,temp/10,3,16); //顯示整數部分 LCD_ShowNum(30+48+40,260,temp%10,1,16); //顯示小數部分 t=0;LED0=!LED0;//LED閃爍}}t++; } }3.準備正點原子PWM輸出的代碼
因為控制舵機需要用到PWM波,那么就需要用到PWM有關的開源代碼,代碼路徑是:探索者光盤資料\A盤\4,程序源碼\2,標準例程-庫函數版本\實驗9 PWM輸出實驗
#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "pwm.h"//ALIENTEK 探索者STM32F407開發板 實驗9 //PWM輸出實驗-庫函數版本 //技術支持:www.openedv.com //淘寶店鋪:http://eboard.taobao.com //廣州市星翼電子科技有限公司 //作者:正點原子 @ALIENTEKint main(void) { u16 led0pwmval=0; u8 dir=1;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置系統中斷優先級分組2delay_init(168); //初始化延時函數uart_init(115200);//初始化串口波特率為115200TIM14_PWM_Init(500-1,84-1); //84M/84=1Mhz的計數頻率,重裝載值500,所以PWM頻率為 1M/500=2Khz. while(1) //實現比較值從0-300遞增,到300后從300-0遞減,循環{delay_ms(10); if(dir)led0pwmval++;//dir==1 led0pwmval遞增else led0pwmval--; //dir==0 led0pwmval遞減 if(led0pwmval>300)dir=0;//led0pwmval到達300后,方向為遞減if(led0pwmval==0)dir=1; //led0pwmval遞減到0后,方向改為遞增TIM_SetCompare1(TIM14,led0pwmval); //修改比較值,修改占空比} }4.修改源碼和組合源碼(這部分原創)
這里有兩部分原創的代碼:
(1)第一部分
(2)第二部分
//下面的測試代碼,讓舵機從0度轉到180,再回到0度,不斷循環led0pwmval=975;//0度TIM_SetCompare1(TIM14,led0pwmval);delay_ms(1000);led0pwmval=950;//45度TIM_SetCompare1(TIM14,led0pwmval);delay_ms(1000);led0pwmval=925;//90度TIM_SetCompare1(TIM14,led0pwmval);delay_ms(1000);led0pwmval=900;//135度TIM_SetCompare1(TIM14,led0pwmval);delay_ms(1000);led0pwmval=875;//180度TIM_SetCompare1(TIM14,led0pwmval);delay_ms(1000);說明:第一個部分是舵機控制的核心算法,我自己推導出來化簡的。第二部分是舵機測試程序,測試舵機固定動作的。讀者根據這些代碼推敲出結果是沒有問題的,我當時也花了不少時間去推敲。如果真的不想推敲了,請下載我最后附錄上的工程代碼。
三、運行與調試
(1)功能說明:用MPU6050的姿態數據控制舵機翻轉0到180度,并且支持用匿名四軸上位機調試仿真波形和舵機狀態,買家可以根據代碼改為多個舵機控制。
(2)代碼說明:用MDK5寫的庫函數代碼
(3)硬件說明:需要用到正點原子探索者開發板,配套他們自家的4.3寸電容屏,配套他們自己家的MPU6050模塊,一個其他家的SG90舵機。如果經濟條件不錯的買家就可以拿正點原子全家桶套裝來測試,連線基本上不用考慮,直接插上就能用,除了舵機那個數據線要自己接而已。要是想省錢,那就自己琢磨程序里面有注釋的IO管腳定義去自己接線了,同時也要考慮沒有接顯示屏會遇到什么錯誤自己慢慢排查,反正接舵機的IO口是PA7,我是全家桶套裝的使用者,不需要考慮那么多
(4) 軟件說明:用了正點原子探索者庫函數版本 實驗32 MPU6050六軸傳感器實驗 的代碼進行修改而成,正點原子的手冊也介紹的程序基本使用方法和代碼注釋,另外還可以使用匿名四軸的上位機來調試舵機。需要接上串口,波特率調到500000(最大)。如下圖所示:
仿真說明:姿態波形展示如下圖
舵機翻轉角度圖,航向角變化就是舵機角度的變化如下圖是0度
舵機翻轉角度圖,航向角變化就是舵機角度的變化如下圖是26度
舵機翻轉9度情況如下圖顯示
翻轉90度的舵機如下
????通過上面運行與調試證明了程序狀態良好,達到博文提出的要求。
總結
????有些讀者說:為什么不用PCA9685控制舵機呢?其實我已經推出,只不過這是STM32控制舵機的入門篇,不能一下子加大難度。
????擴展說明:如果搞定了一個舵機,那么就可以搞定多個舵機,用庫函數寫代碼效率是很高的,不像我上次用51單片機控制舵機那么麻煩的,全部是配置寄存器和定時器。所以我稱之為最簡單的舵機控制程序,我寫的核心的代碼就幾行,能看懂的讀者就賺大了。剩下的就是正點原子的MPU6050示例代碼,不懂的讀者可以親自看看正點原子的教程文檔。
????下期預告:下期用stm32控制PCA9685模塊間接去集群控制多個舵機,并且用紅外線遙控器控制舵機組成的機械臂,精彩不容錯過,值得期待。
最后附上本博文代碼下載地址:https://www.cirmall.com/circuit/22260/
直接跳轉
正點原子相關代碼免費下載
總結
以上是生活随笔為你收集整理的最简单DIY基于STM32F407探索者开发板的MPU6050陀螺仪姿态控制舵机程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java版的mrp模拟器,mrp模拟器
- 下一篇: 手机游戏简要介绍