目录
一、STM32 通用定时器简介
1、STM32
的通用定时器是一个通过可编程预分频器(
PSC
)驱动的
16
位自动装载计数器(
CNT
)
构成。
STM32
的通用定时器可以被用于:测量输入信号的脉冲长度
(
输入捕获
)
或者产生输出波
形
(
输出比较和
PWM)
等。
使用定时器预分频器和
RCC
时钟控制器预分频器,脉冲长度和波形
周期可以在几个微秒到几个毫秒间调整。
STM32
的每个通用定时器都是完全独立的,没有互相
共享的任何资源。
STM3
的通用
TIMx (TIM2
、
TIM3
、
TIM4
和
TIM5)
定时器功能包括:
1)16
位向上、向下、向上
/
向下自动装载计数器(
TIMx_CNT
)。
2)16
位可编程
(
可以实时修改
)
预分频器
(TIMx_PSC)
,计数器时钟频率的分频系数为
1
~
65535
之间的任意数值。
3
)
4
个独立通道(
TIMx_CH1~4
),这些通道可以用来作为:
A
.输入捕获
B
.输出比较
C
.
PWM
生成
(
边缘或中间对齐模式
)
D
.单脉冲模式输出
4
)可使用外部信号(
TIMx_ETR
)控制定时器和定时器互连(可以用
1
个定时器控制另外
一个定时器)的同步电路。
5
)如下事件发生时产生中断
/DMA
:
A
.更新:计数器向上溢出
/
向下溢出,计数器初始化
(
通过软件或者内部
/
外部触发
)
B
.触发事件
(
计数器启动、停止、初始化或者由内部
/
外部触发计数
)
C
.输入捕获
D
.输出比较
E
.支持针对定位的增量
(
正交
)
编码器和霍尔传感器电路
F
.触发输入作为外部时钟或者按周期的电流管理
2、三种通用定时器简介

3、功能特点
4、计数器模式
5、内部时钟选择
二、相关计时器
1,当前值寄存器
2,预分频寄存器
CK_CNT=F(CK_PSC)+1
3,自动重装载寄存器
4,控制寄存器
5,中断使能寄存器
三、库函数
1
)
TIM3
时钟使能。
TIM3
是挂载在
APB1
之下,所以我们通过
APB1
总线下的时钟使能函数来使能
TIM3
。调
用的函数是:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //
时钟使能
2
)初始化定时器参数
,
设置自动重装值,分频系数,计数方式等。
在库函数中,定时器的初始化参数是通过初始化函数
TIM_TimeBaseInit
实现的:
voidTIM_TimeBaseInit(TIM_TypeDef*TIMx,
TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
第一个参数是确定是哪个定时器,这个比较容易理解。第二个参数是定时器初始化参数结
构体指针,结构体类型为
TIM_TimeBaseInitTypeDef
,下面我们看看这个结构体的定义:
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
个成员变量,要说明的是,对于通用定时器只有前面四个参数有用,
最后一个参数
TIM_RepetitionCounter
是高级定时器才有用的,这里不多解释。
第一个参数
TIM_Prescaler
是用来设置分频系数的。
第二个参数
TIM_CounterMode
是用来设置计数方式,上面讲解过,可以设置为向上计数,
向下计数方式还有中央对齐计数方式,比较常用的是向上计数模式
TIM_CounterMode_Up
和向
下计数模式
TIM_CounterMode_Down
。
第三个参数是设置自动重载计数周期值,这在前面也已经讲解过。
第四个参数是用来设置时钟分频因子。
针对
TIM3
初始化范例代码格式:
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 5000;
TIM_TimeBaseStructure.TIM_Prescaler =7199;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
3
)设置
TIM3_DIER
允许更新中断。
因为我们要使用
TIM3
的更新中断,寄存器的相应位便可使能更新中断。在库函数里面定
时器中断使能是通过
TIM_ITConfig
函数来实现的:
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)
;
第一个参数是选择定时器号,这个容易理解,取值为
TIM1~TIM17
。
第二个参数非常关键,是用来指明我们使能的定时器中断的类型,定时器中断的类型有很
多种,包括更新中断
TIM_IT_Update
,触发中断
TIM_IT_Trigger
,以及输入捕获中断等等。
第三个参数就很简单了,就是失能还是使能。
例如我们要使能
TIM3
的更新中断,格式为:
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
4
)
TIM3
中断优先级设置。
在定时器中断使能之后,因为要产生中断,必不可少的要设置
NVIC
相关寄存器,设置中
断优先级。之前多次讲解到用
NVIC_Init
函数实现中断优先级的设置,这里就不重复讲解。
5
)允许
TIM3
工作,也就是使能
TIM3
。
光配置好定时器还不行,没有开启定时器,照样不能用。我们在配置完后要开启定时器,
通过
TIM3_CR1
的
CEN
位来设置。在固件库里面使能定时器的函数是通过
TIM_Cmd
函数来实
现的:
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
这个函数非常简单,比如我们要使能定时器
3
,方法为:
TIM_Cmd(TIM3, ENABLE); //
使能
TIMx
外设
6
)编写中断服务函数。
在最后,还是要编写定时器中断服务函数,通过该函数来处理定时器产生的相关中断。在
中断产生后,通过状态寄存器的值来判断此次产生的中断属于什么类型。然后执行相关的操作,
我们这里使用的是更新(溢出)中断,所以在状态寄存器
SR
的最低位。在处理完中断之后应
该向
TIM3_SR
的最低位写
0
,来清除该中断标志。
在固件库函数里面,用来读取中断状态寄存器的值判断中断类型的函数是:
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t)
该函数的作用是,判断定时器
TIMx
的中断类型
TIM_IT
是否发生中断。比如,我们要判断定
时器
3
是否发生更新(溢出)中断,方法为:
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET){}
固件库中清除中断标志位的函数是:
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
该函数的作用是,清除定时器 TIMx 的中断 TIM_IT 标志位。使用起来非常简单,比如我们在 TIM3 的溢出中断发生后,我们要清除中断标志位,方法是: TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); 这里需要说明一下,固件库还提供了两个函数用来判断定时器状态以及清除定时器状态标 志位的函数 TIM_GetFlagStatus 和 TIM_ClearFlag,他们的作用和前面两个函数的作用类似。只 是在 TIM_GetITStatus 函数中会先判断这种中断是否使能,使能了才去判断中断标志位,而 TIM_GetFlagStatus 直接用来判断状态标志位。 通过以上几个步骤,我们就可以达到我们的目的了,使用通用定时器的的更新中断,来控 制 DS1 的亮灭。
四、硬件部分
硬件设计
本实验用到的硬件资源有:
1
) 指示灯
DS0
和
DS1
2
) 定时器
TIM3

五、软件部分
1、工程
2、main.c
3、timer.c