STM32通用定时器功能:
16位向上、向下、向上/下自动装载计数器(TIMx_CNT);
16位可编程预分频器(TIMx_PSC),分频系数为1~65535;
4个独立通道(TIMx_CH1~4),这些通道可以用来作为:
输入捕获
输出比较
PWM生成
单脉冲模式输出
可使用外部信号(TIMx_ETR)控制定时电器和定时器互连(可以用1个定时器控制另一个定时器)的同步电路;
如下事件发生时产生中断/DMA:
更新:计数器溢出、初始化
触发事件(计数器启动、停止、初始化或内/外部触发计数)
输入捕获
输出比较
支持针对定位的增量(正交)编码器和霍尔传感器电路
触发输入作为外部时钟或者按周期的电流管理
通用定时器控制寄存器1(TIMx_CR1):
[tr]位功能[/tr]15:10保留,始终为0
9:8CKD[1:0]:时钟分频因子
00:tDTS = tCK_INT
01:tDTS = 2 × times × tCK_INT
10:tDTS = 4 × times × tCK_INT
11:保留
7ARPE:自动重装载预装载允许位
0:TIMx_ARR 寄存器没有缓冲;
1:TIMx_ARR 寄存器被装入缓冲器
6:5CMS[1:0]:选择中央对其模式
00:边沿对其模式
01:中央对其模式1
10:中央对其模式2
11:中央对其模式3
__注:__在计数器开启时(CEN=1),不允许从边沿对齐模式转换到中央对其模式。
4DIR:方向
0:计数器向上计数
1:计数器向下计数
3OPM:单脉冲模式
0:在发生更新事件时,计数器不停止
1:在发生下一次更新事件(清除CEN位)时,计数器停止
2URS:更新请求源
0:如果允许产生更新中断或DMA请求,则下述任一事件产生一个更新中断或DMA请求:
计数器溢出
设置UG位
从模式控制器产生的更新
1:如果允许产生更新中断或DMA请求,则只有计数器溢出才产生一个更新中断或DMA请求。
1UDIS:禁止更新,软件通过该位允许/禁止UEV事件的产生
0CEN:使能计数器
0:禁止计数器
1:使能计数器
通用定时器DMA/中断使能寄存器(TIMx_DIER):
仅关心它的第0位,该位是更新中断允许位。
通用定时器预分频寄存器(TIMx_PSC):
PSC[15:0]:预分频器的值。
计数器的时钟频率CK_CNT等于fCK_PSC/(psc[15:0]+1)。
PSC包含了当更新事件产生时装入当前预分频器寄存器的值。
定时器的时钟来源有4个:
内部时钟(CK_INT)
外部时钟模式1:外部输入脚(TIx)
外部时钟模式2:外部触发输入(ETR)
内部触发输入(ITRx):使用A定时器作为B定时器的预分频器(A为B提供时钟)
通用定时器计数寄存器(TIMx_CNT):
该寄存器存储了当前定时器的计数值
通用定时器自动重装载寄存器(TIMx_ARR) :
ARR[15:0]:自动重装载的值
当自动重装载的值为空时,计数器不工作。
通用定时器状态寄存器( TIMx_SR):
该寄存器用来标记当前与定时器相关的各种事件/中断是否发生。
定时器使用步骤:
TIM3时钟使能
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
初始化定时器参数,设置自动重装值,分频计数,计数方式等
typedef struct
{
uint16_t TIM_Prescaler; //分频系数
uint16_t TIM_CounterMode; //计数方式
uint16_t TIM_Period; //自动重载计数周期值
uint16_t TIM_ClockDivision; //分频因子
uint8_t TIM_RepetitionCounter;
} TIM_TimeBaseInitTypeDef;
例如:
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);
设置TIM3_DIER 允许更新中断
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
TIMx:是选择定时器号,这个容易理解,取值为 TIM1~TIM17。
TIM_IT:指明使能的定时器中断的类型,定时器中断的类型包括更新中断 TIM_IT_Update,触发中断TIM_IT_Trigger,以及输入捕获中断等等。
NewState:是失能还是使能。
例如:
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
TIM3中断优先级设置
在定时器中断使能之后,因为要产生中断,必不可少的要设置 NVIC 相关寄存器, 设置中断优先级。
例如:
//中断优先级 NVIC 设置
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级 0 级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级 3 级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道被使能
NVIC_Init(&NVIC_InitStructure); //④初始化 NVIC 寄存器
TIM_Cmd(TIM3, ENABLE); //⑤使能 TIM3
允许TIM3工作,也就是使能TIM3
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
例如:要使能定时器 3
TIM_Cmd(TIM3, ENABLE); //使能 TIMx 外设
编写中断服务函数
读取中断状态寄存器的值判断中断类型的函数是:
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 );
STM32通用定时器功能:
16位向上、向下、向上/下自动装载计数器(TIMx_CNT);
16位可编程预分频器(TIMx_PSC),分频系数为1~65535;
4个独立通道(TIMx_CH1~4),这些通道可以用来作为:
输入捕获
输出比较
PWM生成
单脉冲模式输出
可使用外部信号(TIMx_ETR)控制定时电器和定时器互连(可以用1个定时器控制另一个定时器)的同步电路;
如下事件发生时产生中断/DMA:
更新:计数器溢出、初始化
触发事件(计数器启动、停止、初始化或内/外部触发计数)
输入捕获
输出比较
支持针对定位的增量(正交)编码器和霍尔传感器电路
触发输入作为外部时钟或者按周期的电流管理
通用定时器控制寄存器1(TIMx_CR1):
[tr]位功能[/tr]15:10保留,始终为0
9:8CKD[1:0]:时钟分频因子
00:tDTS = tCK_INT
01:tDTS = 2 × times × tCK_INT
10:tDTS = 4 × times × tCK_INT
11:保留
7ARPE:自动重装载预装载允许位
0:TIMx_ARR 寄存器没有缓冲;
1:TIMx_ARR 寄存器被装入缓冲器
6:5CMS[1:0]:选择中央对其模式
00:边沿对其模式
01:中央对其模式1
10:中央对其模式2
11:中央对其模式3
__注:__在计数器开启时(CEN=1),不允许从边沿对齐模式转换到中央对其模式。
4DIR:方向
0:计数器向上计数
1:计数器向下计数
3OPM:单脉冲模式
0:在发生更新事件时,计数器不停止
1:在发生下一次更新事件(清除CEN位)时,计数器停止
2URS:更新请求源
0:如果允许产生更新中断或DMA请求,则下述任一事件产生一个更新中断或DMA请求:
计数器溢出
设置UG位
从模式控制器产生的更新
1:如果允许产生更新中断或DMA请求,则只有计数器溢出才产生一个更新中断或DMA请求。
1UDIS:禁止更新,软件通过该位允许/禁止UEV事件的产生
0CEN:使能计数器
0:禁止计数器
1:使能计数器
通用定时器DMA/中断使能寄存器(TIMx_DIER):
仅关心它的第0位,该位是更新中断允许位。
通用定时器预分频寄存器(TIMx_PSC):
PSC[15:0]:预分频器的值。
计数器的时钟频率CK_CNT等于fCK_PSC/(psc[15:0]+1)。
PSC包含了当更新事件产生时装入当前预分频器寄存器的值。
定时器的时钟来源有4个:
内部时钟(CK_INT)
外部时钟模式1:外部输入脚(TIx)
外部时钟模式2:外部触发输入(ETR)
内部触发输入(ITRx):使用A定时器作为B定时器的预分频器(A为B提供时钟)
通用定时器计数寄存器(TIMx_CNT):
该寄存器存储了当前定时器的计数值
通用定时器自动重装载寄存器(TIMx_ARR) :
ARR[15:0]:自动重装载的值
当自动重装载的值为空时,计数器不工作。
通用定时器状态寄存器( TIMx_SR):
该寄存器用来标记当前与定时器相关的各种事件/中断是否发生。
定时器使用步骤:
TIM3时钟使能
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
初始化定时器参数,设置自动重装值,分频计数,计数方式等
typedef struct
{
uint16_t TIM_Prescaler; //分频系数
uint16_t TIM_CounterMode; //计数方式
uint16_t TIM_Period; //自动重载计数周期值
uint16_t TIM_ClockDivision; //分频因子
uint8_t TIM_RepetitionCounter;
} TIM_TimeBaseInitTypeDef;
例如:
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);
设置TIM3_DIER 允许更新中断
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
TIMx:是选择定时器号,这个容易理解,取值为 TIM1~TIM17。
TIM_IT:指明使能的定时器中断的类型,定时器中断的类型包括更新中断 TIM_IT_Update,触发中断TIM_IT_Trigger,以及输入捕获中断等等。
NewState:是失能还是使能。
例如:
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
TIM3中断优先级设置
在定时器中断使能之后,因为要产生中断,必不可少的要设置 NVIC 相关寄存器, 设置中断优先级。
例如:
//中断优先级 NVIC 设置
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3 中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级 0 级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级 3 级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道被使能
NVIC_Init(&NVIC_InitStructure); //④初始化 NVIC 寄存器
TIM_Cmd(TIM3, ENABLE); //⑤使能 TIM3
允许TIM3工作,也就是使能TIM3
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
例如:要使能定时器 3
TIM_Cmd(TIM3, ENABLE); //使能 TIMx 外设
编写中断服务函数
读取中断状态寄存器的值判断中断类型的函数是:
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 );
举报