• 方案介紹
  • 附件下載
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

22.5.2-多任務(wù)創(chuàng)建和調(diào)度 FreeRTOS 項(xiàng)目 FreeRTOS學(xué)習(xí)筆記

02/14 08:56
1055
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

聯(lián)系方式.txt

共1個(gè)文件

這個(gè)是全網(wǎng)最詳細(xì)的STM32項(xiàng)目教學(xué)視頻。
第一篇CSDN文章在這里在這里:
75


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

V3:HAL庫開發(fā)、手把手教學(xué)下面功能:PID速度控制、PID循跡、PID跟隨、遙控、避障、PID角度控制、openmv視覺控制、電磁循跡、FreeRTOS、K210視覺智能車(更新中)、K230視覺智能車(更新中)、MSPM0G3507視覺智能車(更新中)

在這里插入圖片描述

22.5.2-多任務(wù)創(chuàng)建和調(diào)度(有示例代碼)

創(chuàng)建多任務(wù)時(shí)候要注意防止 低優(yōu)先級任務(wù)被"餓死"情況,要讓高優(yōu)先級任務(wù)主動(dòng)進(jìn)入阻塞態(tài)才能防止低優(yōu)先級任務(wù)被餓死。

這里我們繼續(xù)新建一個(gè)任務(wù)用于執(zhí)行裸機(jī)時(shí)候1 2 3 4 5 6 模式的代碼
在這里插入圖片描述
復(fù)制一下22-3_LED_FreeRTOS的工程,命名為22-5_LED_FreeRTOS

然后打開LED.ioc
在這里插入圖片描述

Task Name:MultiModeTask 多模式任務(wù)的意思

Priority:osPriorityAboveNormal 優(yōu)先級設(shè)置的高于正常優(yōu)先級

Stack Size (Words):128 這個(gè)任務(wù)棧 先按照默認(rèn)

Entry Function:StartMultiModTask 這是任務(wù)的函數(shù)名字

在這里插入圖片描述
把模式 1和2和3 4 5 6 的代碼都是復(fù)制到任務(wù)函數(shù)里面

復(fù)制到這里

在這里插入圖片描述
下面就是復(fù)制后的

/* USER CODE BEGIN Header_StartMultiModTask */
/**
* @brief Function implementing the MultiModeTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartMultiModTask */
void StartMultiModTask(void const * argument)
{
  /* USER CODE BEGIN StartMultiModTask */
  /* Infinite loop */
  for(;;)
  {
		if(g_ucMode == 1)
		{
		///****    紅外PID循跡功能******************/
		g_ucaHW_Read[0] = READ_HW_OUT_1;//讀取紅外對管狀態(tài)、這樣相比于寫在if里面更高效
		g_ucaHW_Read[1] = READ_HW_OUT_2;
		g_ucaHW_Read[2] = READ_HW_OUT_3;
		g_ucaHW_Read[3] = READ_HW_OUT_4;

		if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0 )
		{
	//		printf("應(yīng)該前進(jìn)rn");//注釋掉更加高效,減少無必要程序執(zhí)行
			g_cThisState = 0;//前進(jìn)
		}
		else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 1&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0 )//使用else if更加合理高效
		{
	//		printf("應(yīng)該右轉(zhuǎn)rn");
			g_cThisState = -1;//應(yīng)該右轉(zhuǎn)
		}
		else if(g_ucaHW_Read[0] == 1&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0 )
		{
	//		printf("快速右轉(zhuǎn)rn");
			g_cThisState = -2;//快速右轉(zhuǎn)
		}
		else if(g_ucaHW_Read[0] == 1&&g_ucaHW_Read[1] == 1&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0)
		{
	//		printf("快速右轉(zhuǎn)rn");
			g_cThisState = -3;//快速右轉(zhuǎn)
		}
		else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 1&&g_ucaHW_Read[3] == 0 )
		{
	//		printf("應(yīng)該左轉(zhuǎn)rn");
			g_cThisState = 1;//應(yīng)該左轉(zhuǎn)	
		}
		else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 1 )
		{
	//		printf("快速左轉(zhuǎn)rn");
			g_cThisState = 2;//快速左轉(zhuǎn)
		}
		else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 1&&g_ucaHW_Read[3] == 1)
		{
	//	    printf("快速左轉(zhuǎn)rn");
			g_cThisState = 3;//快速左轉(zhuǎn)
		}
		g_fHW_PID_Out = PID_realize(&pidHW_Tracking,g_cThisState);//PID計(jì)算輸出目標(biāo)速度 這個(gè)速度,會和基礎(chǔ)速度加減

		g_fHW_PID_Out1 = 3 + g_fHW_PID_Out;//電機(jī)1速度=基礎(chǔ)速度+循跡PID輸出速度
		g_fHW_PID_Out2 = 3 - g_fHW_PID_Out;//電機(jī)1速度=基礎(chǔ)速度-循跡PID輸出速度
		if(g_fHW_PID_Out1 >5) g_fHW_PID_Out1 =5;//進(jìn)行限幅 限幅速度在0-5之間
		if(g_fHW_PID_Out1 <0) g_fHW_PID_Out1 =0;
		if(g_fHW_PID_Out2 >5) g_fHW_PID_Out2 =5;//進(jìn)行限幅 限幅速度在0-5之間
		if(g_fHW_PID_Out2 <0) g_fHW_PID_Out2 =0;
		if(g_cThisState != g_cLastState)//如何這次狀態(tài)不等于上次狀態(tài)、就進(jìn)行改變目標(biāo)速度和控制電機(jī)、在定時(shí)器中依舊定時(shí)控制電機(jī)
		{
			motorPidSetSpeed(g_fHW_PID_Out1,g_fHW_PID_Out2);//通過計(jì)算的速度控制電機(jī)
		}
		
		g_cLastState = g_cThisState;//保存上次紅外對管狀態(tài)	

		}
		if(g_ucMode == 2)
		{
			
			//***************遙控模式***********************//
			//遙控模式的控制在串口三的中斷里面
		}
		if(g_ucMode == 3)
		{
			//******超聲波避障模式*********************//
	避障邏輯
			if(HC_SR04_Read() > 25)//前方無障礙物
			{
				motorPidSetSpeed(1,1);//前運(yùn)動(dòng)
				HAL_Delay(100);
			}
			else{	//前方有障礙物
				motorPidSetSpeed(-1,1);//右邊運(yùn)動(dòng) 原地	
				HAL_Delay(500);
				if(HC_SR04_Read() > 25)//右邊無障礙物
				{
					motorPidSetSpeed(1,1);//前運(yùn)動(dòng)
					HAL_Delay(100);
				}
				else{//右邊有障礙物
					motorPidSetSpeed(1,-1);//左邊運(yùn)動(dòng) 原地
					HAL_Delay(1000);
					if(HC_SR04_Read() >25)//左邊無障礙物
					{
						 motorPidSetSpeed(1,1);//前運(yùn)動(dòng)
						HAL_Delay(100);
					}
					else{
						motorPidSetSpeed(-1,-1);//后運(yùn)動(dòng)
						HAL_Delay(1000);
						motorPidSetSpeed(-1,1);//右邊運(yùn)動(dòng)
						HAL_Delay(50);
					}
				}
			}
		}
		if(g_ucMode == 4)
		{
		//**********PID跟隨功能***********//
			g_fHC_SR04_Read=HC_SR04_Read();//讀取前方障礙物距離
			if(g_fHC_SR04_Read < 60){  //如果前60cm 有東西就啟動(dòng)跟隨
				g_fFollow_PID_Out = PID_realize(&pidFollow,g_fHC_SR04_Read);//PID計(jì)算輸出目標(biāo)速度 這個(gè)速度,會和基礎(chǔ)速度加減
				if(g_fFollow_PID_Out > 6) g_fFollow_PID_Out = 6;//對輸出速度限幅
				if(g_fFollow_PID_Out < -6) g_fFollow_PID_Out = -6;
				motorPidSetSpeed(g_fFollow_PID_Out,g_fFollow_PID_Out);//速度作用與電機(jī)上
			}
			else motorPidSetSpeed(0,0);//如果前面60cm 沒有東西就停止
			HAL_Delay(10);//讀取超聲波傳感器不能過快
		}
		if(g_ucMode == 5)
		{
		//*************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:計(jì)算字符串大小	
			 
	//	    mpu_dmp_get_data(&pitch,&roll,&yaw);//返回值:0,DMP成功解出歐拉角
	//		while(mpu_dmp_get_data(&pitch,&roll,&yaw)!=0){}  //這個(gè)可以解決經(jīng)常讀不出數(shù)據(jù)的問題
			
			
			g_fMPU6050YawMovePidOut = PID_realize(&pidMPU6050YawMovement,yaw);//PID計(jì)算輸出目標(biāo)速度 這個(gè)速度,會和基礎(chǔ)速度加減

			g_fMPU6050YawMovePidOut1 = 1.5 + g_fMPU6050YawMovePidOut;//基礎(chǔ)速度加減PID輸出速度
			g_fMPU6050YawMovePidOut2 = 1.5 - g_fMPU6050YawMovePidOut;
			if(g_fMPU6050YawMovePidOut1 >3.5) g_fMPU6050YawMovePidOut1 =3.5;//進(jìn)行限幅
			if(g_fMPU6050YawMovePidOut1 <0) g_fMPU6050YawMovePidOut1 =0;
			if(g_fMPU6050YawMovePidOut2 >3.5) g_fMPU6050YawMovePidOut2 =3.5;//進(jìn)行限幅
			if(g_fMPU6050YawMovePidOut2 <0) g_fMPU6050YawMovePidOut2 =0;
			motorPidSetSpeed(g_fMPU6050YawMovePidOut1,g_fMPU6050YawMovePidOut2);//將最后計(jì)算的目標(biāo)速度 通過motorPidSetSpeed控制電機(jī)
		
		}
		if(g_ucMode == 6)
		{

			sprintf((char*)OledString, "lHW:%d  ", g_lHW_State);//視覺識別結(jié)果
			OLED_ShowString(0,0,OledString,12);//這個(gè)是oled驅(qū)動(dòng)里面的,是顯示位置的一個(gè)函數(shù),
			
			g_fHW_PID_Out = PID_realize(&pidOpenmv_Tracking,g_cThisState);//PID計(jì)算輸出目標(biāo)速度 這個(gè)速度,會和基礎(chǔ)速度加減

			g_fHW_PID_Out1 = 0.5 + g_fHW_PID_Out;//電機(jī)1速度=基礎(chǔ)速度+循跡PID輸出速度
			g_fHW_PID_Out2 = 0.5 - g_fHW_PID_Out;//電機(jī)1速度=基礎(chǔ)速度-循跡PID輸出速度
			if(g_fHW_PID_Out1 >1.2) g_fHW_PID_Out1 =1.2;//進(jìn)行限幅 限幅速度在0-1.2之間
			if(g_fHW_PID_Out1 <0) g_fHW_PID_Out1 =0;
			if(g_fHW_PID_Out2 >1.2) g_fHW_PID_Out2 =1.2;//進(jìn)行限幅 限幅速度在0-1.2之間
			if(g_fHW_PID_Out2 <0) g_fHW_PID_Out2 =0;
			if(g_cThisState != g_cLastState)//如何這次狀態(tài)不等于上次狀態(tài)、就進(jìn)行改變目標(biāo)速度和控制電機(jī)、在定時(shí)器中依舊定時(shí)控制電機(jī)
			{
				motorPidSetSpeed(g_fHW_PID_Out1,g_fHW_PID_Out2);//通過計(jì)算的速度控制電機(jī)
			}
			
			g_cLastState = g_cThisState;//保存上次紅外對管狀態(tài)	

		}
    osDelay(1);
  }
  /* USER CODE END StartMultiModTask */
}

這個(gè)osDelay(1)要帶著,因?yàn)橹挥懈邇?yōu)先級任務(wù)阻塞或者掛起狀態(tài),低優(yōu)先級任務(wù)才有機(jī)會運(yùn)行。
在這里插入圖片描述
并且為了我們方便查看調(diào)試任務(wù)是否執(zhí)行和剩余任務(wù)??臻g 我們增加調(diào)試信息

在這里插入圖片描述

		UBaseType_t stackHighWaterMark = uxTaskGetStackHighWaterMark(NULL);// 獲取當(dāng)前任務(wù)的棧高水位值
		printf("StartMultiModTask Mark: %u wordsn", (unsigned int)stackHighWaterMark);
		size_t freeHeapSize = xPortGetFreeHeapSize();// 獲取系統(tǒng)的可用堆空間
		printf("StartMultiModTask Free Heap Size: %u bytesn", (unsigned int)freeHeapSize);

然后我們需要修改之前寫的 幾個(gè)高水位值的輸出
在這里插入圖片描述
然后連接DAP進(jìn)行燒錄,燒錄教程見:第二章-GPIO與中斷 ->2.1-點(diǎn)燈-燒錄程序->方法一內(nèi)容

燒錄后,復(fù)位,小燈閃爍

然后連接DAP串口,串口連接和設(shè)置教程見::第四章-串口實(shí)驗(yàn)(簡單輸出)->4.2串口實(shí)驗(yàn)->接線圖->使用dap

然后可以關(guān)閉串口看一下輸出的結(jié)果

仔細(xì)觀察一下輸出結(jié)果可以找到四個(gè)任務(wù)都有輸出執(zhí)行。

前面我們 輸出的時(shí)候 把對應(yīng)函數(shù)名字記得改一下這樣方便查看每個(gè)變量

然后我們通過串口就可用觀察出來幾個(gè)任務(wù)是否在執(zhí)行,這樣會十分方便我們在FreeRTOS中調(diào)試
在這里插入圖片描述

但是我們發(fā)現(xiàn)OLED屏幕上沒有顯示當(dāng)前模式,我們從之前的main.c中把當(dāng)前模式顯示的代碼找到,增加到OLED顯示的任務(wù)中
在這里插入圖片描述

		sprintf((char *)OledString," g_ucMode:%d",g_ucMode);//顯示g_ucMode 當(dāng)前模式
		OLED_ShowString(0,6,OledString,12);	//顯示在OLED上
	
		sprintf((char *)Usart3String," g_ucMode:%d",g_ucMode);//藍(lán)牙APP顯示
		HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const  char  *)Usart3String),50);//阻塞式發(fā)送通過串口三輸出字符 strlen:計(jì)算字符串大小

然后我們按下按鍵key1 發(fā)現(xiàn)屏幕模式更新的非常慢,可能是因?yàn)槊看巫兓J胶?StartMultiModTask任務(wù)函數(shù)里面的,模式1到6中的函數(shù)就會有一部分被執(zhí)行里面調(diào)用的無法釋放CPU使用權(quán)的HAL_Delay 所以我們這里把StartMultiModTask 函數(shù)中的HAL_Delay 都換成osDelay

然后StartMultiModTask任務(wù)就會變成一下內(nèi)容:

/* USER CODE BEGIN Header_StartMultiModTask */
/**
* @brief Function implementing the MultiModeTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartMultiModTask */
void StartMultiModTask(void const * argument)
{
  /* USER CODE BEGIN StartMultiModTask */
  /* Infinite loop */
  for(;;)
  {
		UBaseType_t stackHighWaterMark = uxTaskGetStackHighWaterMark(NULL);// 獲取當(dāng)前任務(wù)的棧高水位值
		printf("StartMultiModTask Mark: %u wordsn", (unsigned int)stackHighWaterMark);
		size_t freeHeapSize = xPortGetFreeHeapSize();// 獲取系統(tǒng)的可用堆空間
		printf("StartMultiModTask Free Heap Size: %u bytesn", (unsigned int)freeHeapSize);
		
		if(g_ucMode == 1)
		{
		///****    紅外PID循跡功能******************/
		g_ucaHW_Read[0] = READ_HW_OUT_1;//讀取紅外對管狀態(tài)、這樣相比于寫在if里面更高效
		g_ucaHW_Read[1] = READ_HW_OUT_2;
		g_ucaHW_Read[2] = READ_HW_OUT_3;
		g_ucaHW_Read[3] = READ_HW_OUT_4;

		if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0 )
		{
	//		printf("應(yīng)該前進(jìn)rn");//注釋掉更加高效,減少無必要程序執(zhí)行
			g_cThisState = 0;//前進(jìn)
		}
		else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 1&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0 )//使用else if更加合理高效
		{
	//		printf("應(yīng)該右轉(zhuǎn)rn");
			g_cThisState = -1;//應(yīng)該右轉(zhuǎn)
		}
		else if(g_ucaHW_Read[0] == 1&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0 )
		{
	//		printf("快速右轉(zhuǎn)rn");
			g_cThisState = -2;//快速右轉(zhuǎn)
		}
		else if(g_ucaHW_Read[0] == 1&&g_ucaHW_Read[1] == 1&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0)
		{
	//		printf("快速右轉(zhuǎn)rn");
			g_cThisState = -3;//快速右轉(zhuǎn)
		}
		else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 1&&g_ucaHW_Read[3] == 0 )
		{
	//		printf("應(yīng)該左轉(zhuǎn)rn");
			g_cThisState = 1;//應(yīng)該左轉(zhuǎn)	
		}
		else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 1 )
		{
	//		printf("快速左轉(zhuǎn)rn");
			g_cThisState = 2;//快速左轉(zhuǎn)
		}
		else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 1&&g_ucaHW_Read[3] == 1)
		{
	//	    printf("快速左轉(zhuǎn)rn");
			g_cThisState = 3;//快速左轉(zhuǎn)
		}
		g_fHW_PID_Out = PID_realize(&pidHW_Tracking,g_cThisState);//PID計(jì)算輸出目標(biāo)速度 這個(gè)速度,會和基礎(chǔ)速度加減

		g_fHW_PID_Out1 = 3 + g_fHW_PID_Out;//電機(jī)1速度=基礎(chǔ)速度+循跡PID輸出速度
		g_fHW_PID_Out2 = 3 - g_fHW_PID_Out;//電機(jī)1速度=基礎(chǔ)速度-循跡PID輸出速度
		if(g_fHW_PID_Out1 >5) g_fHW_PID_Out1 =5;//進(jìn)行限幅 限幅速度在0-5之間
		if(g_fHW_PID_Out1 <0) g_fHW_PID_Out1 =0;
		if(g_fHW_PID_Out2 >5) g_fHW_PID_Out2 =5;//進(jìn)行限幅 限幅速度在0-5之間
		if(g_fHW_PID_Out2 <0) g_fHW_PID_Out2 =0;
		if(g_cThisState != g_cLastState)//如何這次狀態(tài)不等于上次狀態(tài)、就進(jìn)行改變目標(biāo)速度和控制電機(jī)、在定時(shí)器中依舊定時(shí)控制電機(jī)
		{
			motorPidSetSpeed(g_fHW_PID_Out1,g_fHW_PID_Out2);//通過計(jì)算的速度控制電機(jī)
		}
		
		g_cLastState = g_cThisState;//保存上次紅外對管狀態(tài)	

		}
		if(g_ucMode == 2)
		{
			
			//***************遙控模式***********************//
			//遙控模式的控制在串口三的中斷里面
		}
		if(g_ucMode == 3)
		{
			//******超聲波避障模式*********************//
	避障邏輯
			if(HC_SR04_Read() > 25)//前方無障礙物
			{
				motorPidSetSpeed(1,1);//前運(yùn)動(dòng)
				osDelay(100);
			}
			else{	//前方有障礙物
				motorPidSetSpeed(-1,1);//右邊運(yùn)動(dòng) 原地	
				osDelay(500);
				if(HC_SR04_Read() > 25)//右邊無障礙物
				{
					motorPidSetSpeed(1,1);//前運(yùn)動(dòng)
					osDelay(100);
				}
				else{//右邊有障礙物
					motorPidSetSpeed(1,-1);//左邊運(yùn)動(dòng) 原地
					osDelay(1000);
					if(HC_SR04_Read() >25)//左邊無障礙物
					{
						 motorPidSetSpeed(1,1);//前運(yùn)動(dòng)
						osDelay(100);
					}
					else{
						motorPidSetSpeed(-1,-1);//后運(yùn)動(dòng)
						osDelay(1000);
						motorPidSetSpeed(-1,1);//右邊運(yùn)動(dòng)
						osDelay(50);
					}
				}
			}
		}
		if(g_ucMode == 4)
		{
		//**********PID跟隨功能***********//
			g_fHC_SR04_Read=HC_SR04_Read();//讀取前方障礙物距離
			if(g_fHC_SR04_Read < 60){  //如果前60cm 有東西就啟動(dòng)跟隨
				g_fFollow_PID_Out = PID_realize(&pidFollow,g_fHC_SR04_Read);//PID計(jì)算輸出目標(biāo)速度 這個(gè)速度,會和基礎(chǔ)速度加減
				if(g_fFollow_PID_Out > 6) g_fFollow_PID_Out = 6;//對輸出速度限幅
				if(g_fFollow_PID_Out < -6) g_fFollow_PID_Out = -6;
				motorPidSetSpeed(g_fFollow_PID_Out,g_fFollow_PID_Out);//速度作用與電機(jī)上
			}
			else motorPidSetSpeed(0,0);//如果前面60cm 沒有東西就停止
			osDelay(10);//讀取超聲波傳感器不能過快
		}
		if(g_ucMode == 5)
		{
		//*************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:計(jì)算字符串大小	
			 
	//	    mpu_dmp_get_data(&pitch,&roll,&yaw);//返回值:0,DMP成功解出歐拉角
	//		while(mpu_dmp_get_data(&pitch,&roll,&yaw)!=0){}  //這個(gè)可以解決經(jīng)常讀不出數(shù)據(jù)的問題
			
			
			g_fMPU6050YawMovePidOut = PID_realize(&pidMPU6050YawMovement,yaw);//PID計(jì)算輸出目標(biāo)速度 這個(gè)速度,會和基礎(chǔ)速度加減

			g_fMPU6050YawMovePidOut1 = 1.5 + g_fMPU6050YawMovePidOut;//基礎(chǔ)速度加減PID輸出速度
			g_fMPU6050YawMovePidOut2 = 1.5 - g_fMPU6050YawMovePidOut;
			if(g_fMPU6050YawMovePidOut1 >3.5) g_fMPU6050YawMovePidOut1 =3.5;//進(jìn)行限幅
			if(g_fMPU6050YawMovePidOut1 <0) g_fMPU6050YawMovePidOut1 =0;
			if(g_fMPU6050YawMovePidOut2 >3.5) g_fMPU6050YawMovePidOut2 =3.5;//進(jìn)行限幅
			if(g_fMPU6050YawMovePidOut2 <0) g_fMPU6050YawMovePidOut2 =0;
			motorPidSetSpeed(g_fMPU6050YawMovePidOut1,g_fMPU6050YawMovePidOut2);//將最后計(jì)算的目標(biāo)速度 通過motorPidSetSpeed控制電機(jī)
		
		}
		if(g_ucMode == 6)
		{

			sprintf((char*)OledString, "lHW:%d  ", g_lHW_State);//視覺識別結(jié)果
			OLED_ShowString(0,0,OledString,12);//這個(gè)是oled驅(qū)動(dòng)里面的,是顯示位置的一個(gè)函數(shù),
			
			g_fHW_PID_Out = PID_realize(&pidOpenmv_Tracking,g_cThisState);//PID計(jì)算輸出目標(biāo)速度 這個(gè)速度,會和基礎(chǔ)速度加減

			g_fHW_PID_Out1 = 0.5 + g_fHW_PID_Out;//電機(jī)1速度=基礎(chǔ)速度+循跡PID輸出速度
			g_fHW_PID_Out2 = 0.5 - g_fHW_PID_Out;//電機(jī)1速度=基礎(chǔ)速度-循跡PID輸出速度
			if(g_fHW_PID_Out1 >1.2) g_fHW_PID_Out1 =1.2;//進(jìn)行限幅 限幅速度在0-1.2之間
			if(g_fHW_PID_Out1 <0) g_fHW_PID_Out1 =0;
			if(g_fHW_PID_Out2 >1.2) g_fHW_PID_Out2 =1.2;//進(jìn)行限幅 限幅速度在0-1.2之間
			if(g_fHW_PID_Out2 <0) g_fHW_PID_Out2 =0;
			if(g_cThisState != g_cLastState)//如何這次狀態(tài)不等于上次狀態(tài)、就進(jìn)行改變目標(biāo)速度和控制電機(jī)、在定時(shí)器中依舊定時(shí)控制電機(jī)
			{
				motorPidSetSpeed(g_fHW_PID_Out1,g_fHW_PID_Out2);//通過計(jì)算的速度控制電機(jī)
			}
			
			g_cLastState = g_cThisState;//保存上次紅外對管狀態(tài)	

		}
    osDelay(1);
  }
  /* USER CODE END StartMultiModTask */
}

然后按KEY1 觀察當(dāng)前模式顯示發(fā)現(xiàn)已經(jīng)快很多,但是還是感覺有點(diǎn)慢,我們提高一下OLED顯示任務(wù)的優(yōu)先級
在這里插入圖片描述
設(shè)置成正常優(yōu)先級,然后重新生成代碼
在這里插入圖片描述
編譯燒錄測試一下,這次的屏幕刷新效率會比之前高一下些。

這樣就完成了四個(gè)任務(wù)較為合理的調(diào)度,下面章節(jié)完成,任務(wù)中完善內(nèi)容,先用全局變量 實(shí)現(xiàn)之前裸機(jī)的功能。

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

相關(guān)推薦

方案定制

去合作
方案開發(fā)定制化,2000+方案商即時(shí)響應(yīng)!