【STM32】STM32CubeMX使用FreeRTOS教程1----定时器学习
【STM32】STM32CubeMX使用FreeRTOS教程1----定時器學習
前言
本教程將對應外設原理,HAL庫、STM32CubeMX和FreeRTOS結合在一起講解,分析學習過程中遇到的問題和一些注意事項。
知識概括:
SMT32定時器原理
STM32CubeMX創建定時器例程
HAL庫TIM定時器函數庫
定時器中斷的創建與使用
FreeRTOS中斷級臨界代碼段理解
定時器簡介
SMT32F1系列共有8個定時器:
高級定時器(TIM1、TIM8);通用定時器(TIM2、TIM3、TIM4、TIM5);基本定時器(TIM6、TIM7)。
SMT32F4系列共有15個定時器:
高級定時器(TIM1、TIM8);通用定時器(TIM2、TIM3、TIM4、TIM5、TIM9~TIM14);基本定時器(TIM6、TIM7)。
基本定時器功能(TIM6、TIM7):
1. 16位向上、向下、向上/下自動裝載計數器
2. 16位可編程(可以實時修改)預分頻器,計數器時鐘頻率的分頻系數為1~65535之間的任意數值
3. 觸發DAC的同步電路 注:此項是TIM6/7獨有功能.
4. 位于APB1總線上**
通用定時器(TIM2~TIM5)的主要功能:
16位向上、向下、向上/下自動裝載計數器
16位可編程(可以實時修改)預分頻器,計數器時鐘頻率的分頻系數為1~65535之間的任意數值
4 個獨立通道(TIMx_CH1~4)可以用作:
測量輸入信號的脈沖長度( 輸入捕獲)
輸出比較
單脈沖模式輸出
PWM輸出(邊緣或中間對齊模式)
支持針對定位的增量(正交)編碼器和霍爾傳感器電路
如下事件發生時產生中斷/DMA:
更新:計數器向上溢出/向下溢出,計數器初始化(通過軟件或者內部/外部觸發)
觸發事件(計數器啟動、停止、初始化或者由內部/外部觸發計數)
輸入捕獲
輸出比較
位于APB1總線上
CubeMX創建freertos工程
CubeMX工程中我選的芯片為STM32F103C8T6
1、設置RCC
設置高速外部時鐘HSE 選擇外部時鐘源
2、設置時鐘
選擇外部時鐘為8MHz,在HCLK中直接輸入72,CubeMX會自動配置好。
設置時鐘后,需要選擇系統時鐘來源,當使用了FreeRtos的時候,強烈建議HAL庫使用除了Systick以外的時鐘源。也就是說當不使用FreeRtos的時候,HAL使用的是systick作為時鐘源,現在使用了rtos,不建議hal庫和rtos一起使用systick作為時鐘源。在這里我選擇了TIM1作為HAL庫時鐘。
3、設置定時器
定時器選擇內部時鐘
Prtscaler (定時器分頻系數) : 7199
Counter Mode(計數模式) Up(向上計數模式)
Counter Period(自動重裝載值) : 4999
CKD(時鐘分頻因子) : No Division 不分頻
auto-reload-preload(自動重裝載) : Enable 使能
在這里定時器溢出時間公式,根據公式溢出時間為500ms
在NVIC Settings中使能定時器中斷
4、配置freeRTOS
在Middleware中選中FREERTOS
根據自己需要裁剪freertos,我一般選中系統默認配置。
編寫定時器中斷代碼
在這里使用了兩個定時器,定時器3每1s觸發一次,優先級為4(優先級分組4),定時器4每0.5s觸發一次,優先級為5,在FreeRTOS中優先級低于configMAX_SYSCALL_INTERRUPT_PRIORITY優先級的中斷在臨界代碼段開啟時會被屏蔽(這里優先級越高,數字越低)。如果使用FreeRTOS默認配置的話configMAX_SYSCALL_INTERRUPT_PRIORITY為5。在任務中會開啟臨界代碼段觀察定時器情況。
任務代碼
在這里使用的HAL_Delay(5000);會用到TIM定時器1,他的優先級等于0,優先級最高!
void StartDefaultTask(void *argument) {/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */for(;;){printf("close\r\n");portDISABLE_INTERRUPTS();HAL_Delay(5000);printf("open\r\n");portENABLE_INTERRUPTS();osDelay(2000);}/* USER CODE END StartDefaultTask */ }定時器回調函數
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {/* USER CODE BEGIN Callback 0 *//* USER CODE END Callback 0 */if (htim->Instance == TIM1) {HAL_IncTick();}/* USER CODE BEGIN Callback 1 */if (htim->Instance == TIM3){printf("time3\r\n");}if (htim->Instance == TIM4){printf("time4\r\n");}/* USER CODE END Callback 1 */ }定時器相關函數講解:
/* USER CODE BEGIN 2 *//*使能定時器3、4中斷*/HAL_TIM_Base_Start_IT(&htim3);HAL_TIM_Base_Start_IT(&htim4);/* USER CODE END 2 */打開定時器
HAL_TIM_IRQHandler(&htim2);定時器中斷處理函數在stm32f4xx_it.c中 ,定時器中斷服務函數中這個函數的具體作用是判斷中斷是否正常,然后判斷產生的是哪一類定時器中斷(溢出中斷/PWM中斷…),然后進入相應的中斷回調函數
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)在HAL庫中,每進行完一個中斷,并不會立刻退出,而是會進入到中斷回調函數中,這里我們是使用定時器溢出中斷回調函數
void TIM3_IRQHandler(void) 首先進入中斷函數HAL_TIM_IRQHandler(&htim2);之后進入定時器中斷處理函數判斷產生的是哪一類定時器中斷(溢出中斷/PWM中斷…) 和定時器通道void HAL_TIM_PeriodElapsedCallback(&htim2); 進入相對應中斷回調函數(此處為溢出中斷)
在中斷回調函數中添加用戶代碼你也可以在在stm32f1xx_it.c中找到中斷回調函數
現象
在開啟臨界保護時,優先級低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中斷不會被觸發,而time3定時器為4,所有可以一直觸發。當關閉臨界保護后,time4中斷才能被觸發。
總結
以上是生活随笔為你收集整理的【STM32】STM32CubeMX使用FreeRTOS教程1----定时器学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Lua解析器管理器(封装解析器通用函数(
- 下一篇: el-table 树形表格 自定义展开图