【智能家居项目】RTOS初步(3)轮询与事件驱动的组合

本文详细介绍了如何在STM32平台上,通过静态变量和中断服务函数实现LED的轮询控制、定时器定时以及事件驱动功能,包括使用标志位处理中断并调整按键和定时器的优先级。
摘要由CSDN通过智能技术生成

0.LED配置?

使用static修饰的变量具有内部链接属性,只能在当前文件中访问

一、基本概念与实验目的

实验目的:

1.轮询:定时器 不同时间 处理 不同任务 ,引出标志位,将中断函数中的处理提到主函数执行

2.事件驱动:增加按键中断,使其控制定时器的开关,同时控制LED亮灭

3.需求分析:按键中断优先级 应高于 定时器中断优先级

4.对于标志位:执行时,第一件事就是清除上次的标志位

二、CubeMx配置

1)增加LED输出配置(默认不亮),其余默认

三、函数编写

1.实验一:轮询按键中断标志,在主函数中控制定时器开关和LED亮灭

        0)相关函数及变量定义

static volatile uint8_t ledStatus = 0;//使用static修饰的变量具有内部链接属性,只能在当前文件中访问
static volatile uint8_t timStatus = 0;

#define LED(STATUS)     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, (STATUS)?GPIO_PIN_RESET:GPIO_PIN_SET)//STATUS置1则为低电平
#define LED_TOGGLE() 		HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1)//翻转电平

        1)中断服务函数

static volatile uint8_t keyFlag = 0;
static volatile uint8_t timFlag = 0;

/*中断服务函数,在main前*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin == GPIO_PIN_0)
    {
        keyFlag = 1;
    }
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    static volatile uint32_t tim2Cnt = 0;
    if(htim->Instance == TIM2)
    {
        tim2Cnt++;
        if((tim2Cnt%100)==0)
        {
            timFlag = 1;
        }
        if((tim2Cnt%200)==0)
        {
            timFlag = 2;
        }
        if((tim2Cnt%300)==0)
        {
            timFlag = 3;
        }
        if((tim2Cnt%400)==0)
        {
            timFlag = 4;
        }
        if((tim2Cnt%500)==0)
        {
            timFlag = 5;
        }
    }
}

        2) 在while中执行,开关定时器和控制LED亮灭,如果关闭定时器,则串口打印不执行

 while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    if(keyFlag)
    {
        keyFlag = 0;
        ledStatus = !ledStatus;
        timStatus = !timStatus;
        LED(ledStatus);
        if(timStatus)
        {
            HAL_TIM_Base_Start_IT(&htim2);
        }
        else
        {
            HAL_TIM_Base_Stop_IT(&htim2);
        }
    }
    switch(timFlag)
    {
        case 1:
        {
            printf("The first[1] thing process: %d\r\n", HAL_GetTick());
            timFlag = 0;
            break;
        }
        case 2:
        {
            printf("The second[2] thing process: %d\r\n", HAL_GetTick());
            timFlag = 0;
            break;
        }
        case 3:
        {
            printf("The third[3] thing process: %d\r\n", HAL_GetTick());
            timFlag = 0;
            break;
        }
        case 4:
        {
            printf("The fourth[4] thing process: %d\r\n", HAL_GetTick());
            timFlag = 0;
            break;
        }
        case 5:
        {
            printf("The fifth[5] thing process: %d\r\n", HAL_GetTick());
            timFlag = 0;
            break;
        }
        default:break;
    }
  }

2.实验二:在按键中断服务中控制定时器开关和LED亮灭

        1) 中断服务函数

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    static volatile uint8_t ledStatus = 0;
    static volatile uint8_t timStatus = 0;
    if(GPIO_Pin == GPIO_PIN_0)
    {
        keyFlag = 1;
        ledStatus = !ledStatus;
        timStatus = !timStatus;
        LED(ledStatus);
        if(timStatus)
        {
            HAL_TIM_Base_Start_IT(&htim2);
        }
        else
        {
            HAL_TIM_Base_Stop_IT(&htim2);
        }
    }
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    static volatile uint32_t tim2Cnt = 0;
    if(htim->Instance == TIM2)
    {
        tim2Cnt++;
        if((tim2Cnt%100)==0)
        {
            timFlag = 1;
        }
        if((tim2Cnt%200)==0)
        {
            timFlag = 2;
        }
        if((tim2Cnt%300)==0)
        {
            timFlag = 3;
        }
        if((tim2Cnt%400)==0)
        {
            timFlag = 4;
        }
        if((tim2Cnt%500)==0)
        {
            timFlag = 5;
        }
    }
}

        2)main函数,while串口打印TIM轮询,若按键中断关闭TIM,则串口不显示

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    switch(timFlag)//用于定时器轮询,若按键控制其关闭,则不显示
    {
        case 1:
        {
            printf("The first[1] thing process: %d\r\n", HAL_GetTick());
            timFlag = 0;
            break;
        }
        case 2:
        {
            printf("The second[2] thing process: %d\r\n", HAL_GetTick());
            timFlag = 0;
            break;
        }
        case 3:
        {
            printf("The third[3] thing process: %d\r\n", HAL_GetTick());
            timFlag = 0;
            break;
        }
        case 4:
        {
            printf("The fourth[4] thing process: %d\r\n", HAL_GetTick());
            timFlag = 0;
            break;
        }
        case 5:
        {
            printf("The fifth[5] thing process: %d\r\n", HAL_GetTick());
            timFlag = 0;
            break;
        }
        default:break;
    }
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值