Tim定时器学习打卡

一,定时器简介

1,定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断(基本功能)。

2,定时器构成:16位计数器,时基单元,自动重装载值的时基单元。

3,时基单元包括:计数器寄存器(TIMX_CNT)、预分频器寄存器(TIMX_PSC)、自动重装载值(TIMX_ARR)。

4,定时器的功能:基本的定时中断功能、内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式 。

5、分类:高级定时器(TIM1、TIM8)、通用计时器(TIM2、3、4、5)、基本定时器三种(TIM6、7) 

6,定时器本质上也是一个计数器,在72MHZ计数时钟下可以实现最大59.65s的计时(1/(72M/65536/65536))(中断频率)

7,STM32定时器支持级联模式,STM32定时器级联是指将多个定时器连接在一起,形成一个更高级别的定时器。这种技术可以扩展定时器的功能,提高定时器的精度和灵活性。

二,定时器类型

基本定时器:(TIM6、7):

1,基本定时器框图:由时基单元 + 触发控制器组成。

2,基本定时器功能:所连总线:APB1,拥有定时中断、主模式触发DAC的功能。

一,时钟源(TIMx_CLK)

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

二,计数器时钟(CK_CLK)

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

三,计数器寄存器(CNT)

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

四,自动重装载值寄存器(ARR)

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

五,定时器计算

CK_CLK = 72M(TIMx_CLK)/(ARR + 1)/(PSC + 1)。

六,定时器初始化结构体
typedef struct
{
  uint16_t TIM_Prescaler;                //预分频系数(CNT)     
  uint16_t TIM_CounterMode;              //计数模式(基本定时器只能向上)
  uint16_t TIM_Period;                   //定时器周期(ARR)
  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 的个数。这里不用设置。

七,实例:

使用OLED来计时,每隔1s实现led翻转

中断配置函数:

void timer_gpio_config(void)
{
    RCC_PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
    
    TIM_InternalClockConfig(TIM6);

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    
    TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;      //分频为1  
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;  //向上计数
	TIM_TimeBaseInitStruct.TIM_Period= 10000 - 1;               //重装载值
	TIM_TimeBaseInitStruct.TIM_Prescaler= 7200 - 1;             //预分频值
    //公式 CK_CLK = TIMX_CLK/(ARR + 1)/(PSC + 1)
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;             //重复计数

    TIM_TimeBaseInit(TIM6,&TIM_TimeBaseInitStruct);

    TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);
    //NVIC中断配置
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);             //NVIC中断分组

    NVIC_InitTypeDef NVIC_InitStruct;

	NVIC_InitStruct.NVIC_IRQChannel=TIM6_IRQn;                  //中断通道6
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;                  //中断使能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;       //抢占优先级为1
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;               //响应优先级为1
    
	NVIC_Init(&NVIC_InitStruct);                                
    
    TIM_Cmd(TIM6,ENABLE);                                        //开启定时
}

中断函数:

void TIM6_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM6,TIM_IT_Update) == SET)
	{
		uckey++;
        Num=1;
		TIM_ClearITPendingBit(TIM6,TIM_IT_Update);
	}

}

主函数:


int main(void)
{
	led_gpio_config();
	timer_gpio_config();
    led_Turn();
	OLED_Init();

	while(1)
	{
		OLED_ShowNum(1,1,uckey,3);
        if(Num == 1)
		{
			led_Turn();
			Num=0;
		}
		

		
		
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值