這個是全網(wǎng)最詳細(xì)的STM32項(xiàng)目教學(xué)視頻。
第一篇在這里:
視頻在這里
**V3:HAL庫開發(fā)、手把手教學(xué)下面功能:PID速度控制、PID循跡、PID跟隨、遙控、避障、PID角度控制、openmv視覺控制、電磁循跡、FreeRTOS、K210視覺智能車(更新中)、K230視覺智能車(更新中)、MSPM0G3507視覺智能車(更新中)**
21.2-工程中添加FreeRTOS(掌握)
用STM32CubeMX添加FreeRTOS
在編寫加入FreeRTOS操作系統(tǒng)之前最好應(yīng)該先測試一下,裸機(jī)對應(yīng)的程序是否正常執(zhí)行,比如我們更改的19-5代碼的裸機(jī)程序的功能是否都正常,小車能否能供正常執(zhí)行,那六個模式,能夠正常執(zhí)行那六個模式后,再繼續(xù)編寫增加FreeRTOS的程序。
讓文件MyCode_V3.3.0處于一個相對簡單短的路徑且沒有中文的路徑。
我們使用19-5的工程
復(fù)制一些19-5(因?yàn)?0章電磁循跡使用GPIO和經(jīng)典的紅外循跡使用的一樣,所以我們不修改20章節(jié)代碼)的文件改名為21-2_LED_FreeRTOS
雙擊LED.ioc,STM32CubeMX就會打開配置文件
更改時鐘
在 System Core
中選擇 SYS
,對 Timebase Source
進(jìn)行設(shè)置,選擇 TIM3
作為HAL庫的時基(除了 SysTick
和其他已經(jīng)使用的定時器 外都可以)
為什么這里Timebase Source (HAL庫時基源)不能再選擇SysTick
(滴答定時器),因?yàn)槲覀円褂肍reeRTOS而 FreeRTOS需要一個時鐘基準(zhǔn)用于任務(wù)和時間管理,這個FreeRTOS的時鐘基準(zhǔn)默認(rèn)使用了SysTick
(滴答定時器), 所以我們避免沖突給Timebase Source (HAL庫時基源)選擇一個非SysTick定時器。
選擇V1
選擇FreeRTOS中的CMSIS_V1接口
在 Middleware
中選擇 FREERTOS
設(shè)置,并選擇 CMSIS_V1
接口版本
CMSIS是一種接口標(biāo)準(zhǔn),目的是屏蔽軟硬件差異以提高軟件的兼容性。RTOS v1使得軟件能夠在不同的實(shí)時操作系統(tǒng)下運(yùn)行(屏蔽不同RTOS提供的API的差別),而RTOS v2則是拓展了RTOS v1,兼容更多的CPU架構(gòu)和實(shí)時操作系統(tǒng)。因此我們在使用時可以根據(jù)實(shí)際情況選擇,如果學(xué)習(xí)過程中使用STM32F1、F4等單片機(jī)時沒必要選擇RTOS v2,更高的兼容性背后時更加冗余的代碼,理解起來比較困難。
這里有一個中斷的錯誤提示我們看一下
點(diǎn)擊NVIC->查看提示
Preemption priorities have been set to 5 according to FREERTOS parameter LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY.
根據(jù)FREERTOS參數(shù)LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY設(shè)置搶占優(yōu)先級為5。
這個LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 是系統(tǒng)可管理的最高優(yōu)先級如果設(shè)置為5,則優(yōu)先級數(shù)值為0,1,2,3,4的中斷是不受FreeRTOS管理的,不可被屏蔽,也不能調(diào)用FreeRTOS中的API接口函數(shù),而中斷優(yōu)先級在5-15的中斷受系統(tǒng)FreeRTOS管理,可以被屏蔽。
這個值默認(rèn)是5
這是是提示我們有中斷優(yōu)先級高于系統(tǒng)可管理的最高優(yōu)先級了,CubeMX 自動限制 一般中斷的搶占優(yōu)先級不得高于 5
所以我們先把之前設(shè)置的KEY按鍵相關(guān)外部中斷優(yōu)先級提高,設(shè)置為5
然后點(diǎn)擊OK
這是提示的兩個錯誤的中斷優(yōu)先級
把這兩個都設(shè)置為5
這樣的話需要測試一下按鍵里面還是否可以寫HAL延時函數(shù),因?yàn)槲覀兒竺嬲鹿?jié)會把按鍵寫到任務(wù)中所以這里不在測試中斷中的功能。
添加任務(wù)
新建一個任務(wù),這里新增一個用于LED閃爍的任務(wù)。
系統(tǒng)默認(rèn)會有一個默認(rèn)任務(wù)-defaultTask,這個默認(rèn)任務(wù)是可以更改或者刪除的。這里我們先留著。
下面我們新增一個LED任務(wù)。
編寫任務(wù)函數(shù)
這個任務(wù)的函數(shù)里面點(diǎn)燈。
點(diǎn)擊關(guān)閉
點(diǎn)擊這個后就是keil 打開代碼
然后我們點(diǎn)擊編譯下。
編譯一下,有些錯誤需要我們解決一下
查看第一個錯誤,雙擊 發(fā)現(xiàn)是
編譯后發(fā)現(xiàn)還有一個錯誤,錯誤說的是:HAL_TIM_PeriodElapsedCallback
函數(shù)被重復(fù)定義,在 main.c
和其他文件(例如 stm32f1xx_it.c
)中都定義了
為了解決這個問題,我們?nèi)炙阉?ctrl+f)一下函數(shù)HAL_TIM_PeriodElapsedCallback
我們發(fā)現(xiàn)兩個文件都定義了,HAL_TIM_PeriodElapsedCallback函數(shù),其中main.c 是我們在增加FreeRTOS后,又STM32Cubemx生成的的部分。所以我們保留man.c里面的函數(shù),將stm32f1xx_it.c
中的函數(shù)移到main.c 中
實(shí)現(xiàn)如下 將代碼放到BEGIN和END中
然后注釋掉stm32f1xx_it中的函數(shù)
這部分注釋 掉
增加相關(guān)定時和注釋掉之前的聲明如下
short Encode1Count = 0;//電機(jī)1編碼器計(jì)數(shù)值 short的類型
short Encode2Count = 0;//電機(jī)2編碼器計(jì)數(shù)值 short的類型
float Motor1Speed = 0.00;//電機(jī)1速度 轉(zhuǎn)/s
float Motor2Speed = 0.00;//電機(jī)2速度 轉(zhuǎn)/s
uint16_t TimerCount = 0;//中斷計(jì)數(shù)變量
然后編譯一下,沒有錯誤了
然后我們再任務(wù)里面增加反轉(zhuǎn)LED對應(yīng)引腳的代碼
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);//切換LED GPIO狀態(tài)
osDelay(300);
編譯燒錄到板子可以觀察到核心板小燈閃爍。
如果使用DAP下載設(shè)置如下(具體的下載接線和設(shè)置見第二章內(nèi)容)
如果芯片和連接正常會出現(xiàn)