参考江科大STM32视频。
一、TIM简介
TIM (Timer)定时器
定时器简单来说就是规定一个时间段,每过一个时间段产生一次中断,从而实现每隔一个固定时间执行一段程序的目的。
- 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
- 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时(72MHz/65536/65536再取倒数,65536是16位计数器的最大值)
- 不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
- 根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型
二、定时器类型

- STM32F103C8T6定时器资源:TIM1~4
- STM32F103ZET6定时器资源:TIM1~8
1. 基本定时器

从基准时钟到预分频器,再到计数器,计数器计数自增,同时不断地与自动重装寄存器进行比较,它俩值相等时,即计时时间到,这时会产生一个更新中断和更新事件,CPU响应更新中断,就完成了我们定时中断的任务了。
预分频器
若预分频器PSC寄存器写0,就是不分频或叫作1分频,输出频率=输入频率/1=72MHz;
若寄存器写1,就是2分频,输出频率=输入频率/2=36MHz;
若寄存器写2,就是3分频,输出频率=输入频率/3=24MHz……
实际分频系数=预分频器的值+1
该预分频器为16位,所以最大值为65535,也就是65536分频
计数器
计数器可以对预分频后的计数时钟进行计数,计数时钟每来一个上升沿,计数器的值+1,该预分频器为16位,所以值可以从0加到65535,再加便回到0重新开始。
所以计数器的值在计时过程中不断自增运行,当自增运行到目标值时,产生中断,那就完成了定时的任务。
所以还需要一个存储目标值的寄存器,即自动重装寄存器。
自动重装寄存器
自动重装寄存器也是16位,存储我们需要的计数目标。
计数值=自动重装寄存器 产生的中断叫做“更新中断”,通往NVIC,再配置好NVIC的定时器通道,那么定时器的更新中断就能得到CPU的响应了。
“更新事件”不会触发中断,但可以触发内部其他电路的工作
2. 通用定时器

基本定时器仅支持向上计数模式,通用定时器和高级定时器支持向上计数、向下计数和中央对齐计数三种模式,常用向上计数模式。
3. 高级定时器

重复次数计数器:可以实现每隔几个周期才发生一次更新事件和更新中断
三、 定时中断基本结构

1. 预分频器时序

计数器计数频率:CK_CNT = CK_PSC/ (PSC + 1)
2. 计数器时序

计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR+1)
=CK PSC/ (PSC + 1)/(ARR + 1)
3. RCC时钟树
四、定时器中断程序
Timer.c
#include "stm32f10x.h" // Device header
void Timer_Init(void)
{
//①开启时钟,选择时钟源
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_InternalClockConfig(TIM2);
//②时基单元初始化
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1; //ARR自动重装寄存器的值
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
//③使能更新中断
TIM_ClearFlag(TIM2,TIM_FLAG_Update); //清除更新中断标志位
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
//④配置NVIC
NVIC_PriorityGroupConfig (NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
//⑤启动定时器
TIM_Cmd(TIM2,ENABLE);
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
{
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
}
}
本文介绍了STM32的TIM定时器工作原理,包括基本定时器、预分频器、计数器、自动重装寄存器以及通用定时器和高级定时器的区别。还详细讲解了计数器时序和RCC时钟树,并提供了定时器中断程序的示例。

1925

被折叠的 条评论
为什么被折叠?



