STM32CubeIDE+FreeRTOS中斷管理實驗


定義了兩個按鍵 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,輸出對應的信息。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM