摘要:使用小熊派開發板,通過硬件IIC與MPU6050六軸傳感器模塊通信,完成相應寄存器配置,成功獲取陀螺儀、加速度計數據。
本問主要講述使用小熊派開發板+MPU6050六軸傳感器,獲取加速度計以及陀螺儀信息。
一、實驗准備
1.實驗環境
- 一塊stm32開發板(推薦使用小熊派),以及數據線
- 已經安裝STM32CubeMX
- 已經安裝KeilMDK,並導入stm32開發板對應的芯片包(小熊派使用的是STM32L431RCT6)
- 一個MPU6050模塊(IIC接口)以及杜邦線
2.目標效果
- 通過CubeMX創建工程並配置參數
- IIC方式通信,配置MPU6050寄存器
- 小熊派通過IIC,獲取陀螺儀、加速度計數據
- 串口1重定向輸出編碼器轉動的角度、角速度
二、通過CubeMX生產MDK工程
A.芯片選擇
- 打開CubeMX,進入芯片選擇:
- 選擇自己的stm32芯片(即STM32L431RCT6):
B.時鍾源RCC設置
- 更改系統時鍾源
系統時鍾默認使用內部的高速時鍾(HSI),選擇使用HSE,時鍾更精確
- 設置外部時鍾對應的端口
- 配置時鍾樹
STM32L431RCT6系統時鍾最大可以為80MHz,我們配置到最大即可
C.參數配置(對應端口設置)
1)配置USART1
使用USART,模式為異步,波特率為115200,無硬件流控制
2)硬件IIC配置
IIC(Inter-Integrated Circuit)其實是IICBus簡稱,所以中文應該叫集成電路總線,它是一種串行通信總線,使用多主從架構
我們使用小熊派的I2C1,小熊派引出的引腳為PB7->I2C1_SDA,PB6->I2C1_SCL
其他選項我們保持默認即可
3)MPU6050模塊
當然,我們還需要了解MPU6050模塊的電路,更好的進行配置。當然我們也可以自主制作模塊
如果AD0腳(9腳)接地,IIC地址為0X68(不包含最低位);如果AD0腳接V3.3,則IIC地址為0X69(不包含最低位).
可以看到,AD0引腳已經被拉低,所有默認IIC地址為0x68.
最后,生成代碼就OK了
D.工程設置
一些基礎的設置,包括工程名、存儲位置、工程環境、工程中各個文件的組成
E.生成代碼
三、編寫相應代碼
1. 串口1輸出重定向
我們知道printf是打印函數,原理是根據傳入的字符串參數格式化打印輸出到stdout中。我們需要讓printf打印到串口之中,只需要在usart.c文件中模仿printf寫一個輸出函數即可
- 在添加頭文件
/* USER CODE BEGIN 0 */#include <stdarg.h>#include <string.h>#include <stdio.h>/* USER CODE END 0 */
- 寫輸出函數
/* USER CODE BEGIN 1 */void UsartPrintf(UART_HandleTypeDef *huart, char *fmt,...){ unsigned char UsartPrintfBuf[296]; va_list ap; unsigned char *pStr = UsartPrintfBuf; va_start(ap, fmt); vsprintf((char *)UsartPrintfBuf, fmt, ap); //格式化 va_end(ap); while(*pStr != 0) { USART1->TDR = *pStr++; while((USART1->ISR & 0x40) == 0); }}//注意:在usart.h中添加void UsartPrintf(UART_HandleTypeDef *huart, char *fmt,...);//使用方法:UsartPrintf(&huart1;,"hello world\r\n");/* USER CODE END 1 */
注意:自己添加的代碼,需要在begin和end之間
2.寫MPU6050驅動
我們創建兩個文件,分別是mpu6050.h和mpu6050.c
a).首先我們在mpu6050.h中宏定義相應的寄存器,方便后續使用。
在main函數中,我們首先設置計數器初值為10000,然后打開編碼器,每1S獲取一次計數器的更新值,判斷編碼器信息
因為寄存器實在太多,就沒有一一列出,可以在附件中查看哦~
b).配置各個寄存器
主要的函數為:IIC讀寫、初始化MPU6050、設置陀螺儀和加速度計滿量程、設置采樣率、讀取數據
代碼附件中有,不一一講解。
初始化函數
uint8_t MPUInit(void){ uint8_t res; extern I2C_HandleTypeDef hi2c1; HAL_I2C_Init(&hi2c1;); //初始化IIC /*上電后最好有一定延時,保證數據准確*/ HAL_Delay(500); MPU_Write_Byte(MPU_PWR_MGMT1_REG,0x80); //復位MPU6050,寫入1000 0000 MPU_Write_Byte(MPU_PWR_MGMT1_REG,0x00);//sleep寫入0,保持喚醒狀態 MPU_Set_Gyro_Fsr(3); //陀螺儀滿量程±2000 MPU_Set_Accel_Fsr(0); //加速度計滿量程±2g MPU_Set_Rate(50); //設置采樣率=50Hz MPU_Write_Byte(MPU_INT_EN_REG,0x00);//關閉所有中斷 MPU_Write_Byte(MPU_USER_CTRL_REG,0x00); //關閉從iic MPU_Write_Byte(MPU_FIFO_EN_REG,0x00); //關閉FIFO MPU_Write_Byte(MPU_INTBP_CFG_REG,0x80); //INT引腳低電平有效 res = MPU_Read_Byte(MPU_DEVICE_ID_REG); //讀取地址 UsartPrintf(&huart1;,"\r\nMPU6050:0x%2x\r\n",res); UsartPrintf(&huart1;,"\r\nMPU6050:0x%2x\r\n",MPU_ADDR); if(res == MPU_ADDR) //判斷地址是否正確 { MPU_Write_Byte(MPU_PWR_MGMT1_REG,0x01); //001,pll,x軸為參考系統時鍾源 MPU_Write_Byte(MPU_PWR_MGMT2_REG,0x00); //都不使用待機模式 MPU_Set_Rate(50); }else return 1; return 0;}
需要注意到,mpu6050上電后需要有一定延時,保證數據的穩定。重啟mpu6050會有睡眠模式,寫入關閉睡眠。最后檢測並判斷IIC地址是否正確
3.main函數
/* USER CODE BEGIN PV */short x;short y;short z;/* USER CODE END PV */ /* USER CODE BEGIN 2 */ MPUInit(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ while(MPU_Get_Gyroscope(&x,&y,&z) !=0); HAL_Delay(1000); printf("\r\n陀螺儀:x=-,y=-,z=-\r\n",x,y,z); while(MPU_Get_Accelerometer(&x,&y,&z) != 0); HAL_Delay(1000); printf("\r\n加速度計:x=-,y=-,z=-\r\n",x,y,z); /* USER CODE BEGIN 3 */ }
四、編譯+下載
點擊編譯后,0 error,0 warning
小熊派連接在電腦上,代碼下載到開發板
五、連接硬件
1.將小熊派串口1和電腦相連,即撥到 AT-MUC,按下復位鍵
2.連接MPU6050
我們只需要使用mpu6050的SDA\SCL\GND\VCC。
即:
- SDA-->PB7
- SCL-->PB6
- GND-->GND
- VCC-->5V
3.效果
打開串口調試助手,我們手動轉動開發板(包括模塊),看見陀螺儀和加速度數據不斷變化,當靜止時數據保持穩定 。
至此,我們已經可以通過小熊派以IIC獲取六軸傳感器原始數據信息
本文分享自華為雲社區《小熊派實踐——獲取MPU6050六軸原始數據》,原文作者:ttking 。