定義了兩個按鍵 KEY1 與 KEY2 的觸發方式為中斷觸發,在中斷觸發的時候通過消息隊列將消息傳遞給任務, 任務接收到消息就將信息通過printf打印出來。
創建工程RTOS_Interrupt,
配置HCLK,使用內部晶振,頻率為180MHZ(根據板子設置)
將SYS中時基源(Timebase Source)改為除SysTick之外的任意定時器即可,如:
配置板載的按鍵KEY1和KEY2
配置FreeRTOS,使用CMSIS_V1,
定義一個任務,
Ctrl + S生成代碼
修改代碼,
1,在main.h中添加
/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "stdio.h" /* USER CODE END Includes */
2,在mian.c中添加
/* USER CODE BEGIN PFP */ int _write(int file , char *ptr,int len) { int i = 0; for(i = 0;i<len;i++) ITM_SendChar((*ptr++)); return len; } /* USER CODE END PFP */ ... ... ... /* USER CODE BEGIN 2 */ printf("starting...\n"); /* USER CODE END 2 */ ... ... ...
3,在main.c中修改任務入口函數的內容
/* USER CODE BEGIN Header_StartGetQueueTask */ /** * @brief Function implementing the GetQueueTask thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_StartGetQueueTask */ void StartGetQueueTask(void const * argument) { /* USER CODE BEGIN 5 */ osEvent theEvent; /* Infinite loop */ for(;;) { theEvent = osMessageGet(myQueue01Handle, osWaitForever); if(theEvent.status == osEventMessage) { printf("What triggers the interrupt is KEY%ld !\n",theEvent.value.v); } osDelay(1); } /* USER CODE END 5 */ }
4,在stm32f4xx_it.c中添加代碼
/* USER CODE BEGIN Includes */ #include "cmsis_os.h" /* USER CODE END Includes */ ... ... ... /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ extern osMessageQId myQueue01Handle; extern osSemaphoreId myBinarySem01Handle; static uint32_t send_data1 = 1; static uint32_t send_data2 = 2; /* USER CODE END PV */
5,在stm32f4xx_it.c中修改兩個按鍵的中斷函數
/** * @brief This function handles EXTI line0 interrupt. */ void EXTI0_IRQHandler(void) { /* USER CODE BEGIN EXTI0_IRQn 0 *///確保是否產生了 EXTI Line 中斷 uint32_t ulReturn; /* 進入臨界段,臨界段可以嵌套 */ ulReturn = taskENTER_CRITICAL_FROM_ISR(); /* 將數據寫入(發送)到隊列中,等待時間為 0 */ osMessagePut(myQueue01Handle, send_data1,0); //如果需要的話進行一次任務切換 // portYIELD_FROM_ISR(pxHigherPriorityTaskWoken); // osThreadYield(); /* 退出臨界段 */ taskEXIT_CRITICAL_FROM_ISR( ulReturn ); /* USER CODE END EXTI0_IRQn 0 */ HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); /* USER CODE BEGIN EXTI0_IRQn 1 */ /* USER CODE END EXTI0_IRQn 1 */ }
/** * @brief This function handles EXTI line[15:10] interrupts. */ void EXTI15_10_IRQHandler(void) { /* USER CODE BEGIN EXTI15_10_IRQn 0 *///確保是否產生了 EXTI Line 中斷 uint32_t ulReturn; /* 進入臨界段,臨界段可以嵌套 */ ulReturn = taskENTER_CRITICAL_FROM_ISR(); /* 將數據寫入(發送)到隊列中,等待時間為 0 */ osMessagePut(myQueue01Handle, send_data2,0); //如果需要的話進行一次任務切換 // portYIELD_FROM_ISR(pxHigherPriorityTaskWoken); // osThreadYield(); /* 退出臨界段 */ taskEXIT_CRITICAL_FROM_ISR( ulReturn ); /* USER CODE END EXTI15_10_IRQn 0 */ HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13); /* USER CODE BEGIN EXTI15_10_IRQn 1 */ /* USER CODE END EXTI15_10_IRQn 1 */ }
修改完畢后點擊 小錘子 構建工程,然后點擊Debug,按如下步驟配置ITM調試
全速運行之前一定要先點擊SWV ITM data Console 頁面中的紅色圓圈
現象:
按下KEY1或KEY2,輸出對應的信息。