測試STM32CubeMX+FreeRTOS,實現定時器控制LED、串口打印
在STM32CubeMX+FreeRTOS實現LED燈閃、實現串口打印基礎上,配置定時器,控制LED,并打印任務進度
試驗工具:
1.STM32CubeMX 5.1.0
2.keil uVision4
3.STM32F405RGT6板子(只引出來串口1.2、3個LED、SWD仿真調試口)
4.JLINK下載工具
5.串口工具
配置步驟:
1.打開上個LED燈閃,串口打印工程,打開STM32CubeMX類型文件,配置定時器
2.添加定時器任務及參數
3.生成代碼,代碼生成需要時間,耐心等待
4.程序修改測試
5.拓展
6.驗證
7.驗證結果(對指針和地址這里有疑問???待解決。)
1.配置定時器
2.添加定時器任務及參數
3.生成代碼,打開工程
4.程序修改測試
打開程序freertos.c文件,在
/* USER CODE BEGIN RTOS_TIMERS */
? /* start timers, add new ones, ... */
這里,添加啟動定時器任務
osStatus timerResult = osOK ;
timerResult = osTimerStart(myTimer01Handle,1000);
if(osOK == timerResult)
{
? printf("Start osTimer");
}
else
{
? printf("Start osTimer Error");
}
在回調函數void Callback01(void const * argument)里添加燈閃和打印任務
printf("Start LED5 FLASH Task");
HAL_GPIO_TogglePin(LED5_GPIO_Port,LED5_Pin);
程序編譯,燒錄程序,通過串口助手和燈閃觀察測試結果。
只有燈5在閃滅,每秒改變一次狀態。
5.拓展
可以配置2個定時器任務,添加任務生成代碼后,別忘了啟動定時器任務2
osTimerStart(myTimer02Handle,1000);//定時時間1000=1S,可以改成自己用的時間500或2000等等
在任務2回調函數里計數,比如10次,每次+1,到次數后停止定時器
printf("Stop Timer Task\r\n");
osTimerStop(myTimer01Handle);
可以看到燈4在閃了5次后不再變換狀態,燈5一直都在交替閃滅 。
回調函數程序如下
void Callback01(void const * argument)
{
? /* USER CODE BEGIN Callback01 */
? printf("Start LED5 FLASH Task");
? HAL_GPIO_TogglePin(LED5_GPIO_Port,LED5_Pin);
? /* USER CODE END Callback01 */
}
void Callback02(void const * argument)
{
? /* USER CODE BEGIN Callback02 */
static uint8_t TimerCount = 0;
printf("Callback02\r\n");
if(TimerCount == 10)
{
printf("Stop Timer Task\r\n");
osTimerStop(myTimer01Handle);
}
else
{
printf("Start LED4 FLASH Task");
HAL_GPIO_TogglePin(LED4_GPIO_Port,LED4_Pin);
}
? TimerCount++;
? /* USER CODE END Callback02 */
}
6.待驗證
看網上有說osTimerCreate這個函數osTimerCreate(osTimer(myTimer02), osTimerPeriodic, NULL);,最后一個NULL參數,和回調函數入口參數(void const * argument)有關系,可以在配置時改變NULL為自己定義的值,回調函數用同一個,以參數作為標識,判斷是那個定時器任務,作相應處理,試驗沒成功,留作參考。
參考來源https://blog.csdn.net/ichamber/article/details/53240733
初始化函數修改
osTimerDef(myTimer01, Callback);
? myTimer01Handle = osTimerCreate(osTimer(myTimer01), osTimerPeriodic, (void*)0);
? /* definition and creation of myTimer02 */
? osTimerDef(myTimer02, Callback);
? myTimer02Handle = osTimerCreate(osTimer(myTimer02), osTimerPeriodic, (void*)1);
回調函數
void Callback(void const * argument)
{
? /* USER CODE BEGIN Callback01 */
printf("argument = %d\r\n",argument);
switch((uint32_t)argument){
case 536871560:HAL_GPIO_TogglePin(LED5_GPIO_Port,LED5_Pin); break;
case 536871808:HAL_GPIO_TogglePin(LED4_GPIO_Port,LED4_Pin); break;
}
? /* USER CODE END Callback01 */
}
7.驗證結果
這種方法可以實現,但入口參數我還沒有找到更好的辦法,我是把參數值打印出來,然后有修改CASE后面的數值,之前寫的是
case 0:HAL_GPIO_TogglePin(LED5_GPIO_Port,LED5_Pin); break;
case 1:HAL_GPIO_TogglePin(LED4_GPIO_Port,LED4_Pin); break;
燒錄之后燈不會閃,我看打印出來的數據是536871560和536871808,我就把程序改成了
case 536871560:HAL_GPIO_TogglePin(LED5_GPIO_Port,LED5_Pin); break;
case 536871808:HAL_GPIO_TogglePin(LED4_GPIO_Port,LED4_Pin); break;
程序正常運行了,修改定時器啟動值osTimerStart(myTimer02Handle,1000);//定時時間1000=1S,可以改成自己用的時間500或2000等等,可以看到燈閃頻率變化。