STM32定时器原理与使用

控制/MCU

1799人已加入

描述

一、定时器分类

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

基本定时器的核心是时基,通用计时器和高级定时器也有。

1、时钟源

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

2、计数器时钟

定时器时钟经过 PSC 预分频器之后,即 CK_CNT,用来驱动计数器计数。PSC 是一个16 位的预分频器,可以对定时器时钟 TIMxCLK 进行 1~65536 之间的任何一个数进行分频。

具体计算方式为:CK_CNT=TIMxCLK/(PSC+1)。

3.计数器

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

4、自动重装载寄存器

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

5. 定时时间的计算

定时器的定时时间等于计数器的中断周期乘以中断的次数。计数器在 CK_CNT 的驱动下,计一个数的时间则是 CK_CLK 的倒数,等于:1/(TIMxCLK/(PSC+1)),产生一次中断的时间则等于:1/(CK_CLK * ARR)。如果在中断服务程序里面设置一个变量 time,用来记录中断的次数,那么就可以计算出我们需要的定时时间等于: 1/CK_CLK *(ARR+1)*time。

1.定义

设置等待时间,到达等待时间之后执行指定的硬件操作。

定时器最基本的功能就是定时,比如说定时发送串口数据,定时采集AD数据,也可以产生PWM方波等,定时器产生PWM控制电机状态是工业控制的普通。

2、STM32F4xx系列的芯片:2个高级控制定时器(TIM1和TIM8)、10个通用定时器(10TIM2-TIM5,TIM9-TIM14)、2个基本定时器(TIM6和TIM7)、2个看门狗定时器

具体可参考中文参考手册了解其特性及原理

寄存器

3、定时器计数模式:

通用定时器可以向上计数、向下计数、向上向下双向计数模式。

①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。

②向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。

③中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。

如图:

寄存器

4、通用定时器工作原理:

● 计数器寄存器 (TIMx_CNT)

● 预分频器寄存器 (TIMx_PSC)

● 自动重载寄存器 (TIMx_ARR)

假如是向上增长模式,计数器(CNT)从0加到自动重载值(ARR),预分频器(PSC)减一次。

时间计算方式:

假设频率为:42M*2 == 84M == 84000000 == 1s //42根据定时器时钟数可知 并且一般都是*2

定时器定时1s产生中断:

ARR = 84000; // 1ms

PSC = 1000; // 1000*1ms == 1s

寄存器

如图:可知基本定时器的时钟是42M,那么对应*2就是84M=84000000=1S(ARR*PSC)

高级的既是84*2=96M=96000000=1S

-----------------------------------------------------------------------------------------------------------------------------------------------------------

5、定时器中断实现步骤

//5.1、能定时器时钟。

RCC_APB1PeriphClockCmd();

//5.2、初始化定时器,配置ARR,PSC。(申明结构体)

TIM_TimeBaseInit();

typedef struct

{

uint16_t TIM_Prescaler;

uint16_t TIM_CounterMode;

uint16_t TIM_Period;

uint16_t TIM_ClockDivision;

uint8_t TIM_RepetitionCounter;

} TIM_TimeBaseInitTypeDef;

//5.3、启定时器中断,配置NVIC(申明结构体)

NVIC_Init();

进行NVIC中断配置

NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器 3 中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级 1

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //响应优先级 3

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStructure);// ④初始化 NVIC

TIM_Cmd(TIM3,ENABLE); //⑤使能定时器 3

//5.4、设置 TIM3_DIER 允许更新中断

TIM_ITConfig();

//5.5、使能定时器。

TIM_Cmd();

//5.6、编写中断服务函数。

TIMx_IRQHandler();

//定时器 3 中断服务函数

void TIM3_IRQHandler(void)

{

if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断

{

/*处理的程序段*/

}

TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位

}

TIM3_Int_Init(5000-1,8400-1); //定时器时钟84M,分频系数8400,所以84M/8400=10Khz的计数频率,计数5000次为500ms

void TIM3_Int_Init(u16 arr,u16 psc)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

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

TIM_TimeBaseInitStructure.TIM_Period = arr; //自动重装载值

TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定时器分频

TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式

TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断

TIM_Cmd(TIM3,ENABLE); //使能定时器3

NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

//定时器3中断服务函数

void TIM3_IRQHandler(void)

{

if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断

{

LED1=!LED1;//DS1翻转

}

TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位

}

定时器初始化结构体详解

在标准库函数头文件stm32f10x_tim.h中对定时器外设建立了四个初始化结构体,基本定时器只用到其中一个即TIM_TimeBaseInitTypeDef,其他三个在高级定时器章节讲解。

typedef struct {

uint16_t TIM_Prescaler; // 预分频器

uint16_t TIM_CounterMode; // 计数模式

uint32_t TIM_Period; // 定时器周期

uint16_t TIM_ClockDivision; // 时钟分频

uint8_t TIM_RepetitionCounter; // 重复计算器

} TIM_TimeBaseInitTypeDef;1234567

(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 的个数。这里不用设置。

虽然定时器基本初始化结构体有 5 个成员,但对于基本定时器只需设置其中两个就可以。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分