TIM—基本定时器

TIM 定时器概述

TIM 定时器是 STM32 中功能最强大、结构最复杂的一个外设。
其基本功能是可以从名字的得出“定时”,定时器可以对输入的时钟进行计数,并且在计数值达到设定值时出发中断。其内部拥有 16 位计数器、预分频器、自动重装寄存器的时基单元,在 72MHz 计数时种下可以实现最大 59.65S 定时。
除了基本的定时中断功能,其还包含内外时钟源选择、输入捕获、输入比较、编码器接口、主从触发等多种功能,定时器根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型。

TIM 定时器的三种类型

基本定时器功能框图讲解 

基本定时器的核心是时基,不仅基本定时器有,通用定时器和高级定时器也有。学习定时器时,
我们先从简单的基本定时器学起,到了后面的通用和高级定时器的学习中,我们直接跳过时基部
分的讲解即可

时钟源 

定时器时钟 TIMxCLK,即内部时钟 CK_INT,经 APB1 预分频器后分频提供,如果 APB1 预分频
系数等于 1,则频率不变,否则频率乘以 2,库函数中 APB1 预分频的系数是 2,即PCLK1=36M,
所以定时器时钟 TIMxCLK=36*2=72M

计数器时钟

定时器时钟经过 PSC 预分频器之后,即 CK_CNT,用来驱动计数器计数。 PSC 是一个 16 位的预分频器,可以对定时器时钟 TIMxCLK 进行 1~65536 之间的任何一个数进行分频。具体计算方式为: CK_CNT=TIMxCLK/(PSC+1)

计数器

计数器 CNT 是一个 16 位的计数器,只能往上计数,最大计数值为 65535。当计数达到自动重装
载寄存器的时候产生更新事件,并清零从头开始计数

自动重装载寄存器

自动重装载寄存器 ARR 是一个 16 位的寄存器,这里面装着计数器能计数的最大数值。当计数到
这个值的时候,如果使能了中断的话,定时器就产生溢出中断

时钟周期与时钟频率的转换

1khz等于1ms。因为1khz表示每秒钟振动或振荡1000次,而1ms是千分之一秒,即0.001秒。因此,1khz的频率对应的时间周期是1/1000秒,也就是1ms

  • 时钟频率    时钟周期
  • 1Hz       1s
  • 1KHz    1ms
  • 1MHz    1μs
  • 1GHz    1ns

定时器初始化结构体详解

typedef struct {
     uint16_t TIM_Prescaler; // 预分频器

     uint16_t TIM_CounterMode; // 计数模式

     uint32_t TIM_Period; // 定时器周期

     uint16_t TIM_ClockDivision; // 时钟分频

     uint8_t TIM_RepetitionCounter; // 重复计算器

 } TIM_TimeBaseInitTypeDef;

(1) TIM_Prescaler:定时器预分频器设置,时钟源经该预分频器才是定时器时钟,它设定 TIMx_PSC寄存器的值。可设置范围为 0 至 65535,实现 1 至 65536 分频

(2) TIM_CounterMode:定时器计数方式,可是在为向上计数、向下计数以及三种中心对齐模式。基本定时器只能是向上计数,即 TIMx_CNT 只能从 0 开始递增,并且无需初始化。

(3) TIM_Period:定时器周期,实际就是设定自动重载寄存器的值,在事件生成时更新到影子寄
存器。可设置范围为 0 至 65535。

(4) TIM_ClockDivision:时钟分频,设置定时器时钟 CK_INT 频率与数字滤波器采样时钟频率分
频比,基本定时器没有此功能,不用设置。

(5) TIM_RepetitionCounter:重复计数器,属于高级控制寄存器专用寄存器位,利用它可以非常容易控制输出 PWM 的个数。这里不用设置。

编程(TIM定时器定时1s)

1.配置TIM初始化和中断 

#define            BASIC_TIM                   TIM6
#define            BASIC_TIM_APBxClock_FUN     RCC_APB1PeriphClockCmd
#define            BASIC_TIM_CLK               RCC_APB1Periph_TIM6
#define            BASIC_TIM_Period            1000-1
#define            BASIC_TIM_Prescaler         71
#define            BASIC_TIM_IRQ               TIM6_IRQn
#define            BASIC_TIM_IRQHandler        TIM6_IRQHandler

// 中断优先级配置
static void BASIC_TIM_NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
 
    // 设置中断组为0
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);	
	
		// 设置中断来源
    NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ ;
	
		// 设置主优先级为 0
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	
 
	  // 设置抢占优先级为3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;	

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
}

static void BASIC_TIM_Mode_Config(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
		
		// 开启定时器时钟,即内部时钟CK_INT=72M
    BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, ENABLE);
	
		// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
    TIM_TimeBaseStructure.TIM_Period = BASIC_TIM_Period;	

	  // 时钟预分频数为
    TIM_TimeBaseStructure.TIM_Prescaler= BASIC_TIM_Prescaler;
	
		// 时钟分频因子 ,基本定时器没有,不用管
    //TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
		
		// 计数器计数模式,基本定时器只能向上计数,没有计数模式的设置
    //TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 
		
		// 重复计数器的值,基本定时器没有,不用管
		//TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
	
	  // 初始化定时器
    TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseStructure);
		
		// 清除计数器中断标志位
    TIM_ClearFlag(BASIC_TIM, TIM_FLAG_Update);
	  
		// 开启计数器中断
    TIM_ITConfig(BASIC_TIM,TIM_IT_Update,ENABLE);
		
		// 使能计数器
    TIM_Cmd(BASIC_TIM, ENABLE);	
}

void BASIC_TIM_Init(void)
{
	BASIC_TIM_NVIC_Config();
	BASIC_TIM_Mode_Config();
}

 2.编写TIM中断函数,进行计时

void  BASIC_TIM_IRQHandler (void)
{
	if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET ) 
	{	
		time++;
		TIM_ClearITPendingBit(BASIC_TIM , TIM_FLAG_Update);  		 
	}		 	
}



 

  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值