STM32(六)——定时器中断实验

一、通用定时器介绍

STM32F1 的通用定时器是由一个通过可编程预分频器(PSC)驱动的16位自由装载计数器(CNT)构成,可用于测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)等

二、定时器功能

通用TIMx(2、3、4、5)定时器功能包括:

   1)16位 向上 向下自动装载计数器(TIMx_CNT)

   2)16位可编程(可实时修改)预分频(TIMx_PSC)

   3 4 个独立通道( TIMx_CH1~4 ),这些通道可以用来作为:
   A .输入捕获
   B .输出比较
   C PWM 生成 ( 边缘或中间对齐模式 )
   D .单脉冲模式输出
   4 )可使用外部信号( TIMx_ETR )控制定时器和定时器互连(可以用 1 个定时器控制另外
   一个定时器)的同步电路。
   5 )如下事件发生时产生中断 /DMA
   A .更新:计数器向上溢出 / 向下溢出,计数器初始化 ( 通过软件或者内部 / 外部触发 )
   B .触发事件 ( 计数器启动、停止、初始化或者由内部 / 外部触发计数 )
   C .输入捕获
   D .输出比较
   E .支持针对定位的增量 ( 正交 ) 编码器和霍尔传感器电路
   F .触发输入作为外部时钟或者按周期的电流管理
  这里,定时器的时钟来源有 4 个:
  1 )内部时钟( CK_INT
  2 )外部时钟模式 1 :外部输入脚( TIx
  3 )外部时钟模式 2 :外部触发输入( ETR
  4 )内部触发输入( ITRx ):使用 A 定时器作为 B 定时器的预分频器( A B 提供时钟)。
  这些时钟,具体选择哪个可以通过 TIMx_SMCR 寄存器的相关位来设置。这里的 CK_INT
  时钟是从 APB1 倍频的来的, STM32 中除非 APB1 的时钟分频数设置为 1 ,否则通用定时器    TIMx 的时钟是 APB1 时钟的 2 倍,当 APB1 的时钟不分频的时候,通用定时器 TIMx 的时钟就等 于APB1 的时钟。这里还要注意的就是高级定时器的时钟不是来自 APB1 ,而是来自 APB2

  TIMx_CNT 寄存器,该寄存器是定时器的计数器,该寄存器存储了当前 定时器的计数值
首先要提
到的是,定时器相关的库函数主要集中在固件库文件 stm32f10x_tim.h stm32f10x_tim.c 文件
中。
通用定时器工作过程

接下来我们来说说他的第一个作用:
1 TIM3 时钟使能
TIM3 是挂载在 APB1 之下,所以我们通过 APB1 总线下的时钟使能函数来使能 TIM3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
2 )初始化定时器参数 , 设置自动重装值,分频系数,计数方式等。
在库函数中,定时器的初始化参数是通过初始化函数 TIM_TimeBaseInit 实现的
void TIM_TimeBaseInit(TIM_TypeDef*TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
结构体类型为 TIM_TimeBaseInitTypeDef
typedef struct
{
 uint16_t TIM_Prescaler; 
 uint16_t TIM_CounterMode; 
 uint16_t TIM_Period; 
 uint16_t TIM_ClockDivision; 
 uint8_t TIM_RepetitionCounter; 
} TIM_TimeBaseInitTypeDef
第一个参数 TIM_Prescaler 是用来设置分频系数的
第二个参数 TIM_CounterMode 是用来设置计数方式,比较常用的是向上计数模式 TIM_CounterMode_Up 和向 下计数模式 TIM_CounterMode_Down
第三个参数是设置自动重载计数周期值
第四个参数是用来设置时钟分频因子

void TIM3_Int_Init(u16 arr,u16 psc){

针对 TIM3 初始化范例代码格式:
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 5000; //设置自动装载值
TIM_TimeBaseStructure.TIM_Prescaler =7199; //设置预分频系数
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 设置计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

.....(在这之中加上使能和初始化)

3)状态标志位获取和清除 ——在中段函数里使用

 这些呢,都比较相似,那么再接着,我们就要看看使用定时器中断实现的步骤了

(1)不管是什么外设,只要使用,我们就一定需要让对应的时钟使能

(2)初始化函数(定时器)——配置预分频系数 

(3)开启相应的中断,配置NVIC——中断优先级分组和 响应与抢占优先

(4)使能定时器

(5)编写中断服务函数,在上面中断时使用

 

下面则是有关的寄存器 

 

 

 

在初始化完之后,我们还要开启中断(第三步)

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE)

这里也就是使能更新中断,然后就是中断优先级分组,在初始化一下NVIC

(分两组,这里我省略一手)

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;//TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3//响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE//使能
NVIC_Init(ANVIC_InitDtructure);//初始化NVIC

 第四步——使能定时器

TIM_Cmd(TIM3,ENABLE)

第五步——设置中断服务函数

void TIM3_IRQHandler(void)
{
  if(TIM_GetITStatus(TIM3,TIM_IT_Update)== SET)
{
LED1 = !LED1;
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
}

猜你喜欢

转载自blog.csdn.net/ArtoriaLili/article/details/122316986