STM32整理之通用定时器(一)

最近课题组的一个项目用到了STM32的定时器功能,因此对此进行一下整理,以免后续用到的话可以迅速的将相关知识拾起来,因为主要记录重点用到的功能,所以难免对其他地方有些疏忽。

STM32的定时器功能十分强大,有高级定时器---TIM1和TIM8,基本定时器---TIM6和TIM7,还有通用定时器---TIM2~TIM5,因为项目中主要应用的是通用定时器,因此主要讲解通用定时器的应用。

目前用到通用定时器比较多的功能是:

  • 1ms计时    https://blog.csdn.net/Heart_M/article/details/104136313

  • PWM波生成

  • 输入捕获

 通用定时器的一个很重要的功能就是用来计时,计时时间到了之后触发定时器中断,来处理相应的事件,本次以1ms计时来对相关知识点进行整理总结。

定时思路:

通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器(CNT)构成。

其中PSC表示对时钟进行分频的系数(比如时钟为72MHz,如果分频系数为7200的话,那么供给计数器计数的时钟就为10kHz,周期为0.1ms),然后计数器以这个时钟开始计数,达到预设的自动重装载值就会发生溢出,如果打开了中断使能,那么溢出的时候就会进入相应的中断函数,之后计数器从0开始重新计数,周而复始。

相关寄存器:

寄存器的介绍以时钟使能、分频系数和自动重装载值得配置、中断使能、计数器使能的顺序介绍,这也是在编写程序时的顺序

  • 时钟使能  TIM3需要开启RCC中的APB1ENR时钟,关于RCC在此不做介绍
  • 参数配置  

       TIMx_PSC 预分频寄存器

STM32整理之通用定时器(一)_第1张图片

      此寄存器为16位寄存器,计数器的时钟频率CK_CNT为

      定时器的时钟来源有4个:

  •  内部时钟CK_INT:

        我们很多时候都是采用的内部时钟,是从APB1倍频来的,不过需要注意一下,除非 APB1 的时钟分频数设置为 1,否则通用定时器 TIMx 的时钟 ,顺便提一句,高级定时器的时钟来自于APB2

  •  外部时钟模式1:外部输入脚
  •  外部时钟模式2:外部触发引脚
  •  内部触发引脚

    后面三种方式等涉及到的时候再做整理

       TIMx_ARR  自动重装载寄存器 

STM32整理之通用定时器(一)_第2张图片

       此寄存器为16位寄存器,其值为计数器从0开始达到此值之后发生溢出产生中断(当然前提是向上计数,默认即可) 

       这个寄存器在物理上对应着两个寄存器,一个程序员可以直接操作,一个不能操作,叫影子寄存器,这两个寄存器中间有一个“开关”连着,要是“开关”开着,那么ARR的值直接同步到影子寄存器,要是“开关”关着,就得等更新事件时,才能将ARR的值转移到影子寄存器,而控制这个的“开关”就是 TIMx_CR1寄存器中 APRE 位的设置:0时为开,1时为关

  • 中断使能

        TIMx_DIER  DMA/中断使能寄存器

        因此我们需要运用定时功能每隔一段时间处理相应的事件,因此必须要开启中断功能

        在这个16位寄存器中,我们需要关心的是UIE(允许更新中断):1:允许,0:禁止

        因此我们需要在编程中将此位置1

  • 计数器使能

        TIMx_CR1  控制寄存器1

       这一步是关于实现1ms定时的最后一步,在前面配置完成之后,需要打开计数器,否则计数器不会开始计数

       同样的,在此篇中,我们只需要关注 CEN(使能计数器):1:使能,0:禁止

       因此我们需要在编程中将此位置1

  • 中断类型判断

        TIMx_SR  状态寄存器

       我们主要通过状态寄存器来判断中断的类型,因为在TIM3的中断包含很多不同的中断类型,本次我们使用的是UIF(更新中断标记),在更新中断发生的时候,该位由硬件置1,在处理完事件之后用软件清0

编程实现:

      本次编程实现主要通过操作寄存器,后续再写关于库函数的版本

      

/*----------------------------------------------------------
函数功能:
        TIM3初始化
-----------------------------------------------------------*/
void TIM3_Int_Init(u16 arr, u16 psc){
    RCC->APB1ENR |= 1<<1;            //TIM3时钟使能
    TIM3->ARR = arr;                 //设置自动重装载值
    TIM3->PSC = psc;                 //设置预分频值
    TIM3->DIER |= 1<<0;              //开启中断使能
    TIM3->CR1 |= 0x01;               //开启计数器使能
    MY_NVIC_Init(1,3,TIM3_IRQn,2);   //TIM3中断设置
}
/*----------------------------------------------------------
函数功能:
        TIM3中断处理
-----------------------------------------------------------*/

void TIM3_IRQHandler(void){
    if(TIM3->SR&0X0001)             //溢出中断
    {
     //中断处理事件 
    } 
    TIM3->SR&=~(1<<0);              //清除中断标志位
}

在程序初始化函数中,初始化的基本步骤为时钟使能分频系数和自动重装载值得配置中断使能计数器使能,直接操作寄存器介绍部分的相关寄存器即可

在TIM3中断处理函数中,需要先根据状态寄存器的值来判断此次产生的中断属于什么类型,然后执行相关的操作。

你可能感兴趣的:(嵌入式开发)