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

22.2-任務(wù)的創(chuàng)建(有代碼示例) FreeRTOS 項(xiàng)目 FreeRTOS學(xué)習(xí)筆記

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

聯(lián)系方式.txt

共1個(gè)文件

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


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

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

在這里插入圖片描述

22.2-任務(wù)的創(chuàng)建(有代碼示例)

任務(wù)創(chuàng)建生成的代碼

上一個(gè)章節(jié)我們創(chuàng)建了LED的任務(wù)這節(jié)我們分析一下相關(guān)代碼,然后再創(chuàng)建一個(gè)OLED刷新也就是模式零的任務(wù)

可以看到STM32cubemx軟件生成RTOS代碼調(diào)用的CMSIS-RTOS的函數(shù)(以os開通的函數(shù)都是CMSIS-RTOS的函數(shù))

在這里插入圖片描述
我們很容易就找到函數(shù)原型其實(shí)是
在這里插入圖片描述
在這里插入圖片描述
函數(shù)原型:

在這里插入圖片描述
函數(shù)描述:

函數(shù) xTaskCreate 用于實(shí)現(xiàn) FreeRTOS 操作系統(tǒng)的任務(wù)創(chuàng)建,并且還可以自定義任務(wù)棧的大小。

  1. 第 一 個(gè)參數(shù)填創(chuàng)建任務(wù)的函數(shù)名
  2. 第 二 個(gè)參數(shù)是任務(wù)名,這個(gè)參數(shù)主要用于調(diào)試的時(shí)候方便看是哪個(gè)任務(wù)
  3. 第 三 個(gè)參數(shù)是任務(wù)棧大小,單位 word,也就是 4 字節(jié)
  4. 第 四 個(gè)參數(shù)是創(chuàng)建的任務(wù)函數(shù)的形參
  5. 第 五 個(gè)參數(shù)是定義任務(wù)優(yōu)先級
  6. 第 六 個(gè)參數(shù)是任務(wù)句柄,用于區(qū)分不同的任務(wù)

然后我們看一下,我們生成的代碼都有那些

生成的的代碼里面會定義任務(wù)的句柄
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

動手再創(chuàng)建一個(gè)任務(wù)

我們復(fù)制上一節(jié)21-2_LED_FreeRTOS文件 命名為22-2_LED_FreeRTOS

然后點(diǎn)擊LED.ioc

我們這里再新建一個(gè)任務(wù)用于OLED刷新,也就是我們之前裸機(jī)時(shí)候的模式0大部分功能

由于OLED刷新的任務(wù)對實(shí)時(shí)性要求不高,所以我們優(yōu)先級設(shè)置低一些
在這里插入圖片描述
這里優(yōu)先級設(shè)置低于正常優(yōu)先級
在這里插入圖片描述
然后點(diǎn)擊生成代碼,可以觀察到已經(jīng)生成新的代碼,
在這里插入圖片描述這個(gè)就是我們OLED刷新任務(wù)對應(yīng)的函數(shù),我們在該函數(shù)中增加OLED刷新代碼

將之前模式零的代碼復(fù)制過去
在這里插入圖片描述

			//0LED顯示功能
		sprintf((char*)OledString, "V1:%.2fV2:%.2f", Motor1Speed,Motor2Speed);//顯示速度
		OLED_ShowString(0,0,OledString,12);//這個(gè)是oled驅(qū)動里面的,是顯示位置的一個(gè)函數(shù),
		
		sprintf((char*)OledString, "Mileage:%.2f", Mileage);//顯示里程
		OLED_ShowString(0,1,OledString,12);//這個(gè)是oled驅(qū)動里面的,是顯示位置的一個(gè)函數(shù),
		
		sprintf((char*)OledString, "U:%.2fV", adcGetBatteryVoltage());//顯示電池電壓
		OLED_ShowString(0,2,OledString,12);//這個(gè)是oled驅(qū)動里面的,是顯示位置的一個(gè)函數(shù),
		
		sprintf((char *)OledString,"HC_SR04:%.2fcmrn",HC_SR04_Read());//顯示超聲波數(shù)據(jù)
		OLED_ShowString(0,3,OledString,12);//這個(gè)是oled驅(qū)動里面的,是顯示位置的一個(gè)函數(shù),
		
		sprintf((char *)OledString,"p:%.2f r:%.2f rn",pitch,roll);//顯示6050數(shù)據(jù) 俯仰角 橫滾角
		OLED_ShowString(0,4,OledString,12);//這個(gè)是oled驅(qū)動里面的,是顯示位置的一個(gè)函數(shù),
		
		sprintf((char *)OledString,"y:%.2f  rn",yaw);//顯示6050數(shù)據(jù)  航向角
		OLED_ShowString(0,5,OledString,12);//這個(gè)是oled驅(qū)動里面的,是顯示位置的一個(gè)函數(shù),
		
	//藍(lán)牙APP顯示
		sprintf((char*)Usart3String, "V1:%.2fV2:%.2f", Motor1Speed,Motor2Speed);//顯示速度
		HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const  char  *)Usart3String),50);//阻塞式發(fā)送通過串口三輸出字符 strlen:計(jì)算字符串大小
		//阻塞方式發(fā)送可以保證數(shù)據(jù)發(fā)送完畢,中斷發(fā)送不一定可以保證數(shù)據(jù)已經(jīng)發(fā)送完畢才啟動下一次發(fā)送
		sprintf((char*)Usart3String, "Mileage:%.2f", Mileage);//顯示里程
		HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const  char  *)Usart3String),50);//阻塞式發(fā)送通過串口三輸出字符 strlen:計(jì)算字符串大小
		
		sprintf((char*)Usart3String, "U:%.2fV", adcGetBatteryVoltage());//顯示電池電壓
		HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const  char  *)Usart3String),50);//阻塞式發(fā)送通過串口三輸出字符 strlen:計(jì)算字符串大小
		
		sprintf((char *)Usart3String,"HC_SR04:%.2fcmrn",HC_SR04_Read());//顯示超聲波數(shù)據(jù)
		HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const  char  *)Usart3String),50);//阻塞式發(fā)送通過串口三輸出字符 strlen:計(jì)算字符串大小
		
		sprintf((char *)Usart3String,"p:%.2f r:%.2f rn",pitch,roll);//顯示6050數(shù)據(jù) 俯仰角 橫滾角
		HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const  char  *)Usart3String),50);//阻塞式發(fā)送通過串口三輸出字符 strlen:計(jì)算字符串大小
		
		sprintf((char *)Usart3String,"y:%.2f  rn",yaw);//顯示6050數(shù)據(jù)  航向角
		HAL_UART_Transmit(&huart3,( uint8_t *)Usart3String,strlen(( const  char  *)Usart3String),50);//阻塞式發(fā)送通過串口三輸出字符 strlen:計(jì)算字符串大小
	
		//獲得6050數(shù)據(jù)
//		while(mpu_dmp_get_data(&pitch,&roll,&yaw)!=0){}  //這個(gè)可以解決經(jīng)常讀不出數(shù)據(jù)的問題
		
		//在顯示模式電機(jī)停轉(zhuǎn) 設(shè)置小車速度為0
		motorPidSetSpeed(0,0);

有很多錯(cuò)誤,我們解決一些,freeRTOS.c增加頭文件
在這里插入圖片描述

#include "oled.h"
#include "stdio.h"
#include "motor.h"
#include "niming.h"
#include "pid.h"

#include "cJSON.h"
#include <string.h>
#include "HC_SR04.h"



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



#include "adc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

然后把main.c里面定義和聲明的變量到Freertos.c中都聲明一下, 主要聲明的時(shí)候不要賦值
在這里插入圖片描述

extern short Encode1Count ;//電機(jī)1編碼器計(jì)數(shù)值 short的類型
extern short Encode2Count ;//電機(jī)2編碼器計(jì)數(shù)值 short的類型
extern float Motor1Speed ;//電機(jī)1速度 轉(zhuǎn)/s
extern float Motor2Speed ;//電機(jī)2速度 轉(zhuǎn)/s
extern uint16_t TimerCount ;//中斷計(jì)數(shù)變量


extern tPid pidMotor1Speed;//聲明電機(jī)1PID速度控制結(jié)構(gòu)體類型變量
extern tPid pidMotor2Speed;
extern tPid pidFollow;    //定距離跟隨PID
extern tPid pidMPU6050YawMovement;  //利用6050偏航角 進(jìn)行姿態(tài)控制的PID
extern uint8_t Usart1_ReadBuf[255];	//串口1 緩沖數(shù)組
extern float p,i,d,a,b;//使用JSON時(shí)候使用的變量
extern uint8_t OledString[50];//OLED顯示使用的字符串?dāng)?shù)組
extern float Mileage;//里程數(shù)

extern tPid pidHW_Tracking;//紅外循跡的PID
extern tPid pidOpenmv_Tracking;//攝像頭的PID

extern uint8_t g_ucaHW_Read[4] ;//保存紅外對管電平的數(shù)組
extern int8_t g_cThisState ;//這次狀態(tài)
extern int8_t g_cLastState ; //上次狀態(tài)
extern float g_fHW_PID_Out;//紅外對管PID計(jì)算輸出速度
extern float g_fHW_PID_Out1;//電機(jī)1的最后循跡PID控制速度
extern float g_fHW_PID_Out2;//電機(jī)2的最后循跡PID控制速度

extern uint8_t g_ucUsart3ReceiveData;  //保存串口三接收的數(shù)據(jù)
extern uint8_t g_ucUsart2ReceiveData;  //保存串口二接收的數(shù)據(jù)

extern uint8_t Usart3String[50];//串口三輸出字符串使用的字符串?dāng)?shù)組
extern float g_fHC_SR04_Read;//超聲波傳感器讀取障礙物數(shù)據(jù)
extern float g_fFollow_PID_Out;//定距離跟隨PID計(jì)算輸出速度

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

extern float  g_fMPU6050YawMovePidOut ; //姿態(tài)PID運(yùn)算輸出
extern float  g_fMPU6050YawMovePidOut1 ; //第一個(gè)電機(jī)控制輸出
extern float  g_fMPU6050YawMovePidOut2 ; //第一個(gè)電機(jī)控制輸出

extern uint8_t g_ucMode ; 

extern int g_lHW_State;//幫助視覺調(diào)試 用于表示紅外對管或者視覺攝像頭識別狀態(tài)

編譯一下就沒有錯(cuò)誤了,然后我們把代碼燒錄觀察現(xiàn)象

下面能夠觀察到OLED屏幕在快速刷新,同時(shí)LED函數(shù)

注意如果注釋掉MPU6050初始化和數(shù)據(jù)獲取函數(shù),那么OLED上是不會顯示6050數(shù)據(jù)值的。

而且OLED刷新的任務(wù)中一定要有osDelay 確保任務(wù)能供定期進(jìn)入阻塞狀態(tài),使得其他任務(wù)能得到調(diào)度。

修改一下延時(shí)時(shí)間
在這里插入圖片描述

  • 聯(lián)系方式.txt
    下載
意法半導(dǎo)體

意法半導(dǎo)體

意法半導(dǎo)體(ST)集團(tuán)于1987年6月成立,是由意大利的SGS微電子公司和法國Thomson半導(dǎo)體公司合并而成。1998年5月,SGS-THOMSON Microelectronics將公司名稱改為意法半導(dǎo)體有限公司。意法半導(dǎo)體是世界最大的半導(dǎo)體公司之一,公司銷售收入在半導(dǎo)體工業(yè)五大高速增長市場之間分布均衡(五大市場占2007年銷售收入的百分比):通信(35%),消費(fèi)(17%),計(jì)算機(jī)(16%),汽車(16%),工業(yè)(16%)。 據(jù)最新的工業(yè)統(tǒng)計(jì)數(shù)據(jù),意法半導(dǎo)體是全球第五大半導(dǎo)體廠商,在很多市場居世界領(lǐng)先水平。例如,意法半導(dǎo)體是世界第一大專用模擬芯片和電源轉(zhuǎn)換芯片制造商,世界第一大工業(yè)半導(dǎo)體和機(jī)頂盒芯片供應(yīng)商,而且在分立器件、手機(jī)相機(jī)模塊和車用集成電路領(lǐng)域居世界前列.

意法半導(dǎo)體(ST)集團(tuán)于1987年6月成立,是由意大利的SGS微電子公司和法國Thomson半導(dǎo)體公司合并而成。1998年5月,SGS-THOMSON Microelectronics將公司名稱改為意法半導(dǎo)體有限公司。意法半導(dǎo)體是世界最大的半導(dǎo)體公司之一,公司銷售收入在半導(dǎo)體工業(yè)五大高速增長市場之間分布均衡(五大市場占2007年銷售收入的百分比):通信(35%),消費(fèi)(17%),計(jì)算機(jī)(16%),汽車(16%),工業(yè)(16%)。 據(jù)最新的工業(yè)統(tǒng)計(jì)數(shù)據(jù),意法半導(dǎo)體是全球第五大半導(dǎo)體廠商,在很多市場居世界領(lǐng)先水平。例如,意法半導(dǎo)體是世界第一大專用模擬芯片和電源轉(zhuǎn)換芯片制造商,世界第一大工業(yè)半導(dǎo)體和機(jī)頂盒芯片供應(yīng)商,而且在分立器件、手機(jī)相機(jī)模塊和車用集成電路領(lǐng)域居世界前列.收起

查看更多

相關(guān)推薦

方案定制

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