TIM定时器
STM32F1 系列中,除了互联型的产品,共有 8 个定时器,分为基本定时器,通用定时器和高级定时器。基本定时器 TIM6 和 TIM7 是一个 16 位的只能向上计数的定时器,只能定时,没有外部 IO。通用定时器 TIM2/3/4/5 是一个 16 位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,每个定时器有四个外部 IO。高级定时器 TIM1/8是一个 16 位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,还可以有三相电机互补输出信号,每个定时器有 8 个外部 IO。
stm32定时器分类

基本定时器-BASIC_TIM
下面我们分开介绍 先介绍基本定时器 -BASIC-TIM
基本定时器的核心是时基,不仅基本定时器有,通用定时器和高级定时器也有。
基本定时器功能框图

①时钟源
定时器时钟 TIMxCLK,即内部时钟 CK_INT,经 APB1(36M) 预分频器后分频提供,如果APB1 预分频系数等于 1,则频率不变,否则频率乘以 2,库函数中 APB1 预分频的系
数是 2,即 PCLK1=36M,所以定时器时钟 TIMxCLK=36*2=72M。 关于这个的基本定时器的时钟源我们只需要知道是72M就行了
②计数器时钟 CK_INT
定时器时钟经过 PSC 预分频器之后,即 CK_CNT,用来驱动计数器计数。PSC 是一个
16 位的预分频器,可以对定时器时钟 TIMxCLK 进行 1~65536 之间的任何一个数进行分频。具体计算方式为:CK_CNT=TIMxCLK/(PSC+1)=**72M/PSC+1;**预分频器PSC
③计数器
计数器 CNT 是一个 16 位的计数器,只能往上计数,最大计数值为 65535。当计数达
到自动重装载寄存器的时候产生更新事件,并清零从头开始计数。
④自动重装载寄存器
自动重装载寄存器 ARR 是一个 16 位的寄存器,这里面装着计数器能计数的最大数
值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断。
定时时间的计算
定时器的定时时间等于计数器的中断周期乘以中断的次数。计数器在 CK_CNT 的驱动
下,计一个数的时间则是 CK_CLK 的倒数,等于:1/(TIMxCLK/(PSC+1)),产生一次中断的时间则等于:1/(CK_CLK * ARR)。如果在中断服务程序里面设置一个变量 time,用来 记 录 中 断 的 次 数 , 那 么 就 可 以 计 算 出 我 们 需 要 的 定 时 时 间 等 于 : 1/CK_CLK * (ARR+1)time。这里官方给的优点绕 计算定时器溢出时间记住这个:Tout=(ARR+1)(PSC+1)/Tclk;Tclk=72M;
定时器初始化结构体详解
typedef struct
{
uint16_t TIM_Prescaler; //预分频系数 就是PSC的值 0~65535
uint16_t TIM_CounterMode; //计数模式
uint16_t TIM_Period; //自动装载的计数值 就是ARR 0~65535
uint16_t TIM_ClockDivision; //时钟分频 在技术模式下用不到
uint8_t TIM_RepetitionCounter; //重复次数
} TIM_TimeBaseInitTypeDef;
CounterMode计数模式
#define TIM_CounterMode_Up ((uint16_t)0x0000)
#define TIM_CounterMode_Down ((uint16_t)0x0010)
#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020)
#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040)
#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060)
虽然定时器基本初始化结构体有 5 个成员,但对于基本定时器只需设置其中两个就可
以,想想使用基本定时器就是简单。
我们先写一个基本定时器实验
编程要点:(1) 开定时器时钟 TIMx_CLK, x[6,7];
(2) 初始化时基初始化结构体;
(3) 使能 TIMx, x[6,7] update 中断;
(4) 打开定时器;
(5) 编写中断服务程序
我们这次用的是基本定时器,通用定时器和高级定时器要比基本的功能要多 通用定时器和高级定时器的定时编程要点跟基本定时器差不多,只是还要再选择下计数器的计数模式,是向上还是向下。因为基本定时器只能向上计数,且没有配置计数模式的寄存器,默认是向上。
宏定义部分
宏定义都知道写在哪个文件内吧就不多说了
#define BASIC_TIM6 // 如果使用 TIM7,注释掉这个宏即可
#ifdef BASIC_TIM6 // 使用基本定时器 TIM6
#define BASIC_TIM TIM6
#define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd
#define BASIC_TIM_CLK RCC_APB1Periph_TIM6
#define BASIC_TIM_IRQ TIM6_IRQn
#define BASIC_TIM_IRQHandler TIM6_IRQHandler
#else // 使用基本定时器 TIM7
#define BASIC_TIM TIM7
#define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd
#define BASIC_TIM_CLK RCC_APB1Periph_TIM7
#define BASIC_TIM_IRQ TIM7_IRQn
#define BASIC_TIM_IRQHandler TIM7_IRQHandler
18 #endif
//基本定时器有 TIM6 和 TIM7,我们可以有选择的使用,为了提高代码的可移植性,我
们把当需要修改定时器时需要修改的代码定义成宏,默认使用的是定时器 6,如果想修改
成定时器 7,只需要把宏 BASIC_TIM6 注释掉即可。
定时器配置
// 中断优先级配置
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);
}
/*
* 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
* TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
* 另外三个成员是通用定时器和高级定时器才有.
*-----------------------------------------------------------------------------
*typedef struct
*{ TIM_Prescaler 都有
* TIM_CounterMode TIMx,x[6,7]没有,其他都有
* TIM_Period 都有
* TIM_ClockDivision TIMx,x[6,7]没有,其他都有
* TIM_RepetitionCounter TIMx,x[1,8,15,16,17]才有
*}TIM_TimeBaseInitTypeDef;
*-----------------------------------------------------------------------------
*/
static void BASIC_TIM_Mode_Config(

本文详细介绍了STM32F1系列中的定时器,包括基本定时器、通用定时器和高级定时器的特点与功能。解释了定时器的时基单元、计数模式、中断配置等内容,并提供了基本定时器和PWM波输出的编程实例。
最低0.47元/天 解锁文章

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



