【杂谈理解】STM32定时器启动模式

STM32定时器启动方式

前言

  事情的起因本来是探究为什么在中断模式下的回调中函数中,我不小心加了延时函数为什么会导致崩溃,很遗憾啊,没看出来,不过需要在中断事件中延时的话,倒是可以用轮询模式下的配置。本文探究HAL库函数定时器的两种启动方式,注释分别写着是:轮询模式,中断模式。在我们配置好一个定时器的参数后,我们在主函数中往往会选取下述一个函数来开启定时器。

  • HAL_TIM_Base_Start(&htim2);   //轮询模式
  • HAL_TIM_Base_Start_IT(&htim2);  //中断模式

环境

  • STM32F103C6T6核心板
  • STM32CubeMX生成的HAL库文件
  • 在STM32CubeMX的配置:
    • 周期为1S的定时器2(TIM2)
    • 启动PC13的LED

模式

轮询模式:是使能定时器的连续模式。它只是启动定时器的计数,在定时器的计数达到自动重装载值(ARR)时,不会产生中断事件。连续模式启动定时器适用于不需要使用中断,而是在主循环中轮询定时器的计数值,来确定是否触发特定操作的情况。例如,在每个周期结束后执行特定操作,然后重新启动定时器计数。

中断模式:是使能定时器的中断模式。它会启动定时器并设置为产生中断事件。当定时器的计数达到自动重装载值(ARR)时,会触发Update事件,并生成Update中断。使用中断模式启动定时器时,可以通过编写定时器的中断回调函数来实现在每次Update事件中执行特定操作的功能。

上述两种模式总的来说是,都打开了定时器的开始计数的功能,只是轮询模式下达到自动重装载值(ARR)时不会触发中断事件,但是在中断模式下达到时,会触发中断事件。

使用

根据上述两种启动模式的情况,下面举例出两种模式下常用的代码流程,代码省略了其它无关函数,仅为表达本文相关代码。

  • 轮询模式

    轮询模式的应用是在启动后,是要在主函数或主循环中,编写程序用于捕获指定标志位是否被触发,或者计数值是否达到指定数据等来判断,要触发的事件。而且如果是捕获指定标志位,在程序结束时,记得还有清除标志,不然的话会一直处于函数中出不去。常用的标志位:TIM_FLAG_UPDATE更新标志位,当定时器计数溢出并重新开始计数时,该标志位被置位。

    int Num;
    int main(void)
    {
        /******************
        省略其它的初始化函数
        ******************/
        //以轮询模式启动
    	HAL_TIM_Base_Start(&htim2);
        while(1)
        {
            //方法一:判断事件标志位
            if(__HAL_TIM_GET_FLAG(&htim2,TIM_FLAG_UPDATE) == 1)
            {
                //GPIO电平反转
                HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
                //清除标志位
                __HAL_TIM_CLEAR_FLAG(&htim2,TIM_FLAG_UPDATE);
            }
            //方法二:判断计数值
            Num=__HAL_TIM_GET_COUNTER(&htim2);
            if(Num>5000)
            {
              HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
            }
            else
            {
              HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
            }
        }
    }
    
  • 中断模式

    中断模式的应用是在启动后,直接重写中断事件,然后就会周期性的执行了。这里不用手动清除标志位,事件更新时会自动清除的。

    //重写中断回调事件
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    	//判断信号是否来自TIM2
    	if(htim->Instance==TIM2)
    	{
    		HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
    	}
    }
    
    int main()
    {
        /******************
        省略其它的初始化函数
        ******************/
        //以中断模式启动
        HAL_TIM_Base_Start_IT(&htim2);
        while(1)
        {
            
        }
    }
    

差异

  其实通过对比器,也能看出这两个代码相差不大,只是在中断模式下使能定时器的更新中断,一旦定时器的更新事件发生,即定时器计数溢出并重新开始计数,将会产生更新中断,要处理这个中断我们在上面可知,重写回调事件即可。

【杂谈理解】STM32定时器启动模式_第1张图片

你可能感兴趣的:(杂谈理解,stm32,单片机,嵌入式硬件,mcu)