STM32定时器中断实例探究

STM32的定时器中断与实例

  • 一、关于定时器
  • 二、点亮LED和串口输出
  • 2.1定时器点亮LED
  • 2.1.1生成过程
  • 2.1.2代码更改
  • 2.1.3结果展示
  • 2.2定时中断与串口输出
  • 2.2.1创建工程
  • 2.2.2代码更改
  • 2.2.3结果展示
  • 三、呼吸灯
  • 3.1PWM调制
  • 3.2工程实现
  • 3.2.1建立工程
  • 3.2.3更改代码
  • 3.2.3结果展示
  • 四、总结
  • 五、参考

  • 一、关于定时器

    定时器是存在于STM32单片机中的一个外设。STM32总共有8个定时器,分别是2个高级定时器(TIM1、TIM8),4个通用定时器(TIM2、TIM3、TIM4、TIM5)和2个基本定时器(TIM5、TIM6)。具体分类如下

    定时器相当于给CPU上了一个闹钟,CPU平时处理其它任务,当定时时间到了以后,处理定时相关的任务。
    下面我们根据一张图来介绍定时器的基本原理


    在stm32中存在频率精确的内部时钟(即晶振),频率为72MHZ。由于频率较大,我们可以通过函数设置分频系数n,则输出频率变为72/nMHZ。经分频后的时钟经过计算器,规定每经过一个周期,计算器的读数(CK_CNT)加一,读数的范围由上表可知为1~65535,当然了,通过改变初始化函数,我们可以改变这个数的初始值和所能达到的最大值(不一定是65535)。当计数达到自动重装载寄存器的时候产生中断,这就是定时器中断。
    通过上述介绍,我们不难发现,我们可以通过设置分频量,CK_CNT的最大值和最小值就可以设定定时时间了。定时器的定时时间等于计数器的中断周期乘以中断的次数。计数器在 CK_CNT 的驱动下,计一个数的时间则是 CK_CLK 的倒数,为1/TIMxCLK/(PSC+1)),产生一次中断的时间则等于:1/(CK_CLK * ARR)。如果在中断服务程序里面设置一个变量 time,用来 记 录 中断 的 次 数,那 么 就 可以 计 算 出我们 需 要 的定 时 时 间等于 :
    1/CK_CLK * (ARR+1)*time
    如果想要了解更多的关于定时器的理论,可以去看看《零死角玩转STM32—F103指南者 》
    零死角玩转STM32—F103指南者

    二、点亮LED和串口输出

    2.1定时器点亮LED

    我们使用CubeMx完成定时器的相关配置和引脚输出配置。

    2.1.1生成过程

    1.我们打开的是定时器2,为通用寄存器,具体配置如下:选择内部时钟,分频系数为71,实际运行的时候为72。分频后的频率为1MHZ,即周期为1us。CK_CNT的周期为5000,即5ms发生一次中断。

    2.打开定时器中断

    3.生成中断优先级配置代码

    4.输出工程

    2.1.2代码更改

    打开工程文件后,我们还要进行一些代码配置
    1.打开定时器

    HAL_TIM_Base_Start_IT(&htim2);
    

    2.修改中断函数

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    	static uint32_t time_cnt =0;
    
    	if(htim->Instance == TIM2)
    	{
    		if(++time_cnt >= 200)
    		{
    			time_cnt =0;
    			HAL_GPIO_TogglePin(D1_GPIO_Port,D1_Pin);
    		}
    	}
    }
    

    该函数为定时器的中断回调函数,当产生定时中断的时候,会自动调用这个函数。在函数内部定义了一个静态变量:time_cnt。当它大于等于100的时候,才会执行if里面的代码。也就是说需要发生100次中断,才会让LED的状态翻转。前面已经算过了,一次定时中断的时间是0.005秒,所以200次中断的时间是0.005*200=0.5秒。也就是说每隔1秒,LED的状态翻转一次。

    2.1.3结果展示

    定时器led

    2.2定时中断与串口输出

    我们也可在led灯的思路上做一些更改,打开串口,做一个定时器控制的串口输出,具体思路和LED灯的相差不大

    2.2.1创建工程

    具体操作通过上一例相同,唯一需要加的步骤为打开串口

    2.2.2代码更改

    代码的更改如下
    1.打开串口

    MX_USART1_UART_Init();
    

    2.定义输出数组

    char message[]="hello Windows\r\n";//输出信息
    
    

    3.更改中断函数

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    	static uint32_t time_cnt =0;
    
    	if(htim->Instance == TIM2)
    	{
    		if(++time_cnt >= 1000)
    		{
    			time_cnt =0;
    			
    				HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF); 
    		}
    	}
    }
    

    不难看出,输出的周期为5s,内容为hello Windows

    2.2.3结果展示

    定时器串口_1

    三、呼吸灯

    3.1PWM调制

    使用脉冲占空比拟合不同波形的方式称为 PWM(脉冲宽度调制)控制技术——通过 对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值)。PWM 控制 的基本原理为:冲量相等而开头不同的窄脉冲加在具有惯性的环节上时,其效果基本 相同。其中冲量指窄脉冲的面积;效果相同指环节输出响应波形基本相同。在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF),如图所示。

    我们可以通过控制周期内脉冲的占空比来调整所控制的模拟信号。占空比变大,周期内的冲量也会变大,模拟信号周期内的积分也会变大,下图可以很好的体现这一点。

    3.2工程实现

    3.2.1建立工程

    1.配置定时器,选择定时器3和定时器4

    不同时钟的4个通道引脚图如下,可知T3C2接PA7, T4C2接PB8


    3.配置时钟

    4.输出工程

    3.2.3更改代码

    1.设置占空比初始值

    uint16_t duty_num = 10;
    

    更改while函数

    while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    		HAL_Delay(50);
    		duty_num = duty_num + 10;
    		if(duty_num > 500)
    		{
    			duty_num = 0;
    		}
    		__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,duty_num);
    			__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,duty_num);
    
      }
    

    这个实验没有用的中断,使用不需要配置中断函数(也没有打开中断~~~)

    3.2.3结果展示

    呼吸灯

    四、总结

    有了前面学习中断的基础,本次对定时器的学习还是比较轻松的。PWM的原理很好的揭示了在电路中,数字信号是如何控制模拟信号的,这个很重要,也很实用。

    五、参考

    1.搞懂什么是PWM控制
    2.PWM技术——百度百科
    3.你足够了解pwm吗?搞清楚pwm控制技术
    4.STM32-定时器详解

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32定时器中断实例探究

    发表评论