【STM32】定时器中断原理及操作

目录

时钟的选择及分频

定时器中断有关的寄存器

定时器中断有关的库函数

1.时钟使能函数:RCC_APB1PeriphClockCmd

 2.定时器初始化函数:TIM_TimeBaseInit

3.定时器中断使能 / 选择函数:TIM_ITConfig

4.NVIC配置函数:NVIC_Init

5.定时器使能函数:TIM_Cmd

6.中断服务函数:TIM3_IRQHandler


时钟的选择及分频

一般情况定时器的始终会选择来自系统的内部时钟,由AHB时钟经APB1预分频再经历一系列操作得来的。而对于通用定时器来说,如果APB1预分频系数为1,即AHB经过APB1产生的时钟并未分频,此时需要乘于1输出;否则乘于2输出

【STM32】定时器中断原理及操作_第1张图片

而通常情况下我们APB1的时钟是36M的,经过系统时钟预变频而来,所以我们选择的是X2输出,即通用定时器时钟CK_INT是72M,CK_INT经时钟预分频因子转换后就可以得出CK_CNT

 

我们得到CN_CNT时钟后,需要使能才能让其工作。当它工作后,我们可以实现让相应的计数寄存器开始计数,直至到达我们的预装载值时就溢出,产生中断。

【STM32】定时器中断原理及操作_第2张图片

因此,一次溢出的时间Tout(us)可以由以下的公式计算得来:

Tout= ((arr+1)*(psc+1))/Tclk

其中Tclk为输入定时器的时钟频率,单位为(Mhz),psc+1就是预分频系数,所以Tclk/(psc+1)得到的就是定时器的时钟频率,倒数就是定时器的一个时钟周期,乘上预装载值就是一次达到预装载值需要几个周期,即从0达到预装载值的时间

定时器中断有关的寄存器

1.TIMx_CNT:这个寄存器是作为计数器当前值的记录器,记录当前的计数器的数值;

2.TIMx_PSC:这个寄存器用来配置预分频因子的值(CK_CNT=fck_psc/[PSC[15:0]+1]);

3.TIMx_ARR:这个寄存器用来配置自动重装载值,即计数器的触发时间的地方;

4.TIMx_CR1:这个寄存器用来控制计数模式和使能计数器;

5.TIMx_DIER:这个寄存器用来使能中断;

定时器中断有关的库函数

在说定时器中断有关的库函数之前,先来梳理一下实现定时器中断操作的步骤;

  1. 使能相应的时钟
  2. 配置相应的定时器的模式、初始化定时器
  3. 开启定时器的中断、配置NVIC函数
  4. 使能定时器
  5. 配置中断服务函数

1.时钟使能函数:RCC_APB1PeriphClockCmd

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

这个函数有两个参数,第一个参数是要使能的时钟,第二个参数是确定使能

【STM32】定时器中断原理及操作_第3张图片

 2.定时器初始化函数:TIM_TimeBaseInit

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

它有两个参数,第一个是要初始化的定时器,第二个是配置定时器相关参数功能的结构体

 这个结构体有五个成员,

  uint16_t TIM_Prescaler;         
 
  uint16_t TIM_CounterMode;       

  uint16_t TIM_Period;            

  uint16_t TIM_ClockDivision;     

  uint8_t TIM_RepetitionCounter; 

 第一个成员是TIM_Prescaler,它是设置TIM定时器的预分频系数即PSC

 第二个成员是TIM_CounterMode,它表示计数方式的选择

第三个成员是TIM_Period,它表示定时器预装载值的大小

第四个成员是TIM_ClockDivision,它设置时钟分割

第五个成员是TIM_RepetitionCounter,它我还没用到.....

3.定时器中断使能 / 选择函数:TIM_ITConfig

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );

它有三个参数,第一个是选择中断使能的定时器,第二个是中断发生方式,第三个是使能

4.NVIC配置函数:NVIC_Init

NVIC_Init(&NVIC_InitStructure); 

这个函数用于配置中断的优先级,它的参数是一个结构体,它的成员用于配置中断的模式

  uint8_t NVIC_IRQChannel;                   
  
  uint8_t NVIC_IRQChannelPreemptionPriority; 

  uint8_t NVIC_IRQChannelSubPriority;        

  FunctionalState NVIC_IRQChannelCmd;  

第一个成员是  uint8_t NVIC_IRQChannel; ,它用于选择配置哪一个定时器的中断

第二个成员是 uint8_t NVIC_IRQChannelPreemptionPriority; ,它用于配置抢占优先级

第三个成员是 uint8_t NVIC_IRQChannelSubPriority; ,它用于配置响应优先级

第四个成员是FunctionalState NVIC_IRQChannelCmd;  ,它用于使能通道

并且要记得设置中断优先级分组!!(如配置分组2)

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)

5.定时器使能函数:TIM_Cmd

TIM_Cmd(TIM3, ENABLE);

这个函数比较简单,就是使能定时器即可,第一个参数是定时器的名称,第二个参数是使能命令

6.中断服务函数:TIM3_IRQHandler

这个函数用于写产生中断后需要做的操作,例如我们可以让LED闪一下或者蜂鸣器响之类的操作

void TIM3_IRQHandler(void)

其中,在中断服务函数内部我们也需要增加一些判断,例如判断是否真的产生中断。这里我们使用函数:TIM_GetITStatus

它有两个参数,第一个是定时器,第二个是中断形式

TIM_GetITStatus(TIM3, TIM_IT_Update)

它用于获取中断的标志位,如果产生了中断,它的标志位就会变成1(SET)。

当完成一次操作后,我们需要人为手动将其标志位清0(RESET),这时需要函数:

TIM_ClearITPendingBit

TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );

它也有两个参数,第一个也是定时器,第二个也是中断的形式。

你可能感兴趣的:(STM32,stm32,单片机,arm,嵌入式硬件,c语言)