STM32之TIM-定时器的使用

Stm32之TIM-定时器的使用

  • 开发环境:Window 10
  • 开发工具:Keil uVision5 MDK
  • 硬件:STM32F103

资料参考:

1、【正点原子】STM32F103开发板资料(A盘);

2、stm32之TIM-基本定时器应用实例
https://blog.csdn.net/weixin_42653531/article/details/88527405

3、stm32的抢占优先级和响应优先级
https://blog.csdn.net/baidu_38988793/article/details/89522107



STM32F103ZE 简介

内核:ARM Cortex-M3,72MHz

内存:64kB RAM,512kB ROM

时钟和电源:2.00V—3.60V,72 MHz

通信 :SPI、I2C、UART、I2S、CAN、USART、USB、Device

定时器/计数器/PWM :8 × 16 位定时器

模拟:2通道 12位DAC,21通道 12位ADC

I/O 和封装: -40℃—85℃,144-QFP,144-BGA

官网:https://www.keil.com/dd2/stmicroelectronics/stm32f103ze/


一、定时器的概述

定时器最基本的功能就是定时处理事情。比如定时发送USART数据、定时采集AD数据、测量输入脉冲的频率(输入捕获)、产生输出波形(比较输出或PWM)等。

STM32系列的定时器分为基本定时器通用定时器高级定时器。高级定时器包括前者的全部功能。

通常地,STM32包括高级定时器TIM1、TIM8,通用定时器TIM2、TIM3、TIM4、TIM5,基本定时器TIM6、TIM7,具体详见各芯片的数据手册。

在这里插入图片描述

  • 基本定时器(TIM6、TIM7)
  • 通用定时器(TIM2、TIM3、TIM4、TIM5)
  • 高级定时器(TIM1、TIM8)

注释:STM32F103系列有8个16位的定时器,且均采用72MHz的内部时钟;而F407系列则有14个且每个定时器的时钟也不同,具体使用需结合数据手册,如下图。

在这里插入图片描述


二、定时器的使用步骤

1)TIMx时钟使能

2)初始化定时器参数,设置自动重装值,分频系数,计数方式等

3)设置TIMx_DIER允许中断

4)TIMx中断优先级设置

5)允许TIMx工作,即使能TIMx

6)编写中断服务函数

1)TIMx时钟使能

基本、通用定时器的时钟来自于APB1总线;

高级定时器(TIM1、TIM8)的时钟来自于APB2总线。

针对 TIM3 时钟使能范例:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 时钟使能

2)初始化定时器参数

库函数中定时器的初始化通过TIM_TimeBaseInit()实现

TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)

第一个参数:确定哪个定时器;
第二个参数:定时器初始化参数结构体指针,即用结构体形式对定时器的相关参数进行配置。

typedef struct 
{ 
u16 TIM_Period; 
u16 TIM_Prescaler; 
u8 TIM_ClockDivision; 
u16 TIM_CounterMode; 
u8 TIM_RepetitionCounter;
} TIM_TimeBaseInitTypeDef;
  1. TIM_Period:定时器自动重装载计数周期值,当计数寄存器的值递增到等于该值时,将相关事件标志位置位,范围0~65535。
  2. TIM_Prescaler:定时器预分频设置。时钟源经该预分频器才是定时器时钟,范围0~65535。
  3. TIM_ClockDivision:时钟分频。有不分频、二分频、四分频。基本定时器没有这个功能。
  4. TIM_CounterMode:定时器计数方式设置,有向上计数、向下计数、对齐模式等,基本定时器只能向上计数。
  5. TIM_RepetitionCounter :重复计数器,只有高级定时器才有用。

针对 TIM3 初始化范例代码格式:

定时时间=(计数值)*(定时器预分频+1)/内部时钟

STM32F103的内部时钟为72MHz,为实现0.5s定时,预分频Prescaler设置为7200-1,定时器可以得到10KHz(72MHz/((7200-1)+1))的时钟频率,计数值Period设置为5000-1,可以得到定时为0.5s(5000*(1/10kHz))的定时器。

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 5000;//设置自动重装载计数值
TIM_TimeBaseStructure.TIM_Prescaler =7199;//设置预分频
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//时钟不分频
TIM_TimeBaseStruc ture.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);//根据指定参数初始化TIMx

3)设置TIMx_DIER允许中断

在库函数里面定时器中断使能是通过 TIM_ITConfig 函数来实现

在这里插入图片描述

使能TIM3 的更新中断,格式为:

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );

4)TIMx中断优先级设置

用 NVIC_Init()函数实现中断优先级的设置

NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)

根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

NVIC_InitTypeDef定义于文件“misc.h”

typedef struct
{
u8 NVIC_IRQChannel;
u8 NVIC_IRQChannelPreemptionPriority;
u8 NVIC_IRQChannelSubPriority;
FunctionalState NVIC_IRQChannelCmd;
} NVIC_InitTypeDef;
  1. NVIC_IRQChannel:定义初始化哪个中断
  2. NVIC_IRQChannelPreemptionPriority:定义中断的抢占优先级别
  3. NVIC_IRQChannelSubPriority:定义这个中断的子优先级别
  4. NVIC_IRQChannelCmd:该中断是否使能

针对 TIM3 中断设置范例代码格式:

	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //抢占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

NVIC 的优先级组

STM32用4位寄存器位的表示中断优先级,其的分组方式如下:

第0组:所有4位用于指定响应优先级

第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级,抢占级有2^1 =2 级;子优先级2^3=8级,共2*8=16级嵌套

第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级,抢占级有2^2 =4 级;子优先级2^2=4级,共4*4=16级嵌套

第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级,抢占级有2^3 =8 级;子优先级2^1=2级,共8*2=16级嵌套

第4组:所有4位用于指定抢占式优先级

中断响应的优先级由抢占优先级和响应优先级(子优先级)确定,若抢占优先级相同,则看响应优先级,数字越小优先级越高。

1.抢占相同,子优先级不同:按照子优先级顺序排序
2.抢占和子优先级都相同但有先后:此时无抢占剥夺,依照FIFO(先进先出),前一个执行完了再执行后者;
3.抢占和子优先级都相同且同时到达:按照中断向量表顺序排先后


5)允许TIMx工作,即使能TIMx

使能定时器的函数通过 TIM_Cmd 函数来实现

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

针对 TIM3 中断设置范例代码格式:

TIM_Cmd(TIM3, ENABLE); // 使能 TIMx 外设

6)编写中断服务函数

  • 库函数中,用TIM_GetITStatus()来判断中断类型

比如要判断定时器3是否发生更新(溢出)中断,方法为:

if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
  • 固件库中使用TIM_ClearITPendingBit()清除中断标志位

比如在TIM3的溢出中断发生后,要清除中断标志位,方法是:

TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

针对 TIM3 实现定时0.5s闪烁的中断服务函数范例:

/*注意:中断处理的事情要尽可能精简,避免过长时间停留在中断里面*/

void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //判断TIM3更新中断发生与否
		{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
		LED1=!LED1;	//翻转LED1的状态,实现闪烁
		}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值