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,输出对应的信息。

posted @ 2019-12-12 17:12  飞起的小田  阅读(1943)  评论(0编辑  收藏  举报