這個(gè)是全網(wǎng)最詳細(xì)的STM32項(xiàng)目教學(xué)視頻。
第一篇CSDN文章在這里在這里:
75
STM32智能小車(chē)V3-STM32入門(mén)教程-openmv與STM32循跡小車(chē)-stm32f103c8t6-電賽 嵌入式學(xué)習(xí) PID控制算法 編碼器電機(jī) 跟隨
V3:HAL庫(kù)開(kāi)發(fā)、手把手教學(xué)下面功能:PID速度控制、PID循跡、PID跟隨、遙控、避障、PID角度控制、openmv視覺(jué)控制、電磁循跡、FreeRTOS、K210視覺(jué)智能車(chē)(更新中)、K230視覺(jué)智能車(chē)(更新中)、MSPM0G3507視覺(jué)智能車(chē)(更新中)
23.2.1-編寫(xiě)MPU6050初始化
前面代碼我們都把6050代碼注釋掉了,是因?yàn)?a class="article-link" target="_blank" href="/article/503831.html">MPU605代碼有循環(huán)容易卡死。我們?cè)黾佣啻窝h(huán)后就退出,這樣就不會(huì)卡死了。
復(fù)制23-1_LED_FreeRTOS的代碼,然后命名23-2_LED_FreeRTOS
我們把之前注釋掉的MPU6050初始化代碼修改成最多初始化3次,3次都不能初始化成功就退出并且串口一和藍(lán)牙打印。初始化函數(shù)返回值。
這個(gè)初始化在main.c里面
// while(MPU_Init()!=0);//初始化MPU6050模塊的MPU 注意初始化階段不要移動(dòng)小車(chē)
for(uint8_t i = 0; i < 3 ; i++)
{
uint8_t mpu_init_result = MPU_Init(); // 保存函數(shù)返回值
if(mpu_init_result == 0)//初始化成功
{
printf("In main.c:MPU_Init() was initialized successfullyn");//串口1 輸出初始化成功 注意! 這個(gè)要寫(xiě)再串口1初始化之后
sprintf((char*)Usart3String, "In main.c:MPU_Init() was initialized successfullyrn");//藍(lán)牙輸出 初始化成功
HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const char *)Usart3String),50);//阻塞式發(fā)送通過(guò)串口三輸出字符 strlen:計(jì)算字符串大小
break;
}
if(i == 3-1 )//說(shuō)明初始化失敗
{
printf("In main.c:MPU_Init() failed to initialize last return value: %dn", mpu_init_result);//串口1 輸出初始化失敗 注意! 這個(gè)要寫(xiě)再串口1初始化之后 初始化失敗及最后一次返回值
sprintf((char*)Usart3String, "In main.c:MPU_Init() failed to initialize last return value: %dn", mpu_init_result);//藍(lán)牙輸出 初始化失敗
HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const char *)Usart3String),50);//阻塞式發(fā)送通過(guò)串口三輸出字符 strlen:計(jì)算字符串大小
}
}
// while(mpu_dmp_init()!=0);//mpu6050,dmp初始化
for(uint8_t i = 0; i < 3 ; i++)
{
uint8_t mpu_dmp_init_result = mpu_dmp_init();
if(mpu_dmp_init_result == 0)//初始化成功
{
printf("In main.c:mpu_dmp_init() was initialized successfullyn");//串口1 輸出初始化成功 注意! 這個(gè)要寫(xiě)再串口1初始化之后
sprintf((char*)Usart3String, "In main.c:mpu_dmp_init() was initialized successfullyrn");//藍(lán)牙輸出 初始化成功
HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const char *)Usart3String),50);//阻塞式發(fā)送通過(guò)串口三輸出字符 strlen:計(jì)算字符串大小
break;
}
if(i == 3-1 )//說(shuō)明初始化失敗
{
printf("In main.c: mpu_dmp_init() failed to initialize, last return value: %dn", mpu_dmp_init_result);//串口1 輸出初始化失敗 注意! 這個(gè)要寫(xiě)再串口1初始化之后
sprintf((char*)Usart3String, "In main.c: mpu_dmp_init() failed to initialize, last return value: %dn", mpu_dmp_init_result);//藍(lán)牙輸出 初始化成功
HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const char *)Usart3String),50);//阻塞式發(fā)送通過(guò)串口三輸出字符 strlen:計(jì)算字符串大小
}
}
然后我們修改一下OLED顯示任務(wù)的內(nèi)容,循環(huán)讀取20次數(shù)據(jù)如果都失敗就退出循環(huán)
注意這里設(shè)置讀取次數(shù)不能太少,測(cè)試發(fā)現(xiàn)小于5次會(huì)經(jīng)常讀取失敗
OLED顯示的任務(wù)需要讀取MPU605數(shù)據(jù)
for(uint8_t i = 0; i < 20 ; i++)
{
if(mpu_dmp_get_data(&pitch,&roll,&yaw) == 0)//獲得MPU6050數(shù)據(jù)成功
{
printf("mpu_dmp_get_data() Data for successn");//串口1 輸出數(shù)據(jù)獲取成功 注意! 這個(gè)要寫(xiě)再串口1初始化之后
break;
}
if(i == 20-1 )//i已經(jīng)等于(20-1)次 還沒(méi)有退出循環(huán)說(shuō)明 說(shuō)明輸出讀取失敗
{
printf("mpu_dmp_get_data() Data acquisition failuren");//串口1 輸出數(shù)據(jù)獲取失敗 注意! 這個(gè)要寫(xiě)再串口1初始化之后
}
}
再修改一下模式5 里面獲得MPU6050數(shù)據(jù)的部分
//獲得6050數(shù)據(jù)
//如果6050無(wú)法獲得正確數(shù)據(jù),可以連接串口1 查看相關(guān)輸出
//這里的總體
for(uint8_t i = 0; i < 20 ; i++)
{
if(mpu_dmp_get_data(&pitch,&roll,&yaw) == 0)//獲得MPU6050數(shù)據(jù)成功
{
printf("mpu_dmp_get_data() Data for successn");//串口1 輸出數(shù)據(jù)獲取成功 注意! 這個(gè)要寫(xiě)再串口1初始化之后
break;
}
if(i == 20-1 )//i已經(jīng)等于(20-1)次 還沒(méi)有退出循環(huán)說(shuō)明 說(shuō)明輸出讀取失敗
{
printf("mpu_dmp_get_data() Data acquisition failuren");//串口1 輸出數(shù)據(jù)獲取失敗 注意! 這個(gè)要寫(xiě)再串口1初始化之后
}
}
23.2.2-測(cè)試MPU6050和角度控制
具體演示測(cè)試見(jiàn)視頻