目录
时钟选择:
内部时钟选择编辑
时钟计算方法:
计数器模式
向下计数模式(时钟分频因子=1,ARR=36)
向上计数模式(时钟分频因子=1,ARR=36)
中央对齐计数模式(时钟分频因子=1 ARR=6)
定时器中断实验相关寄存器
控制寄存器1(TIMx_CR1):
DMA/中断使能寄存器(TIMx_DIER):
预分频器(TIMx_PSC):
计数器(TIMxCNT):
自动重转载寄存器(TIMx_ARR):
编辑
状态寄存器(TIMx_SR):
常用库函数:
定时器参数初始化:
定时器使能函数:
定时器中断使能函数:
状态标志位获取和清除:
总结——定时器中断实现步骤
时钟选择:
计数器时钟可以由下列时钟源提供:
①内部时钟(CK_INT)
②外部时钟模式1:外部输入脚(TIx)
③外部时钟模式2:外部触发输入(ETR)
④内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。
内部时钟选择
时钟计算方法:
这里的分频系数N = CK_PSC + 1;
计数器模式
通用定时器可以向上计数、向下计数、向上向下双向计数模式。
①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
②向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
③中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。
向下计数模式(时钟分频因子=1,ARR=36)
向上计数模式(时钟分频因子=1,ARR=36)
中央对齐计数模式(时钟分频因子=1 ARR=6)
定时器中断实验相关寄存器
控制寄存器1(TIMx_CR1):
首先我们来看看 TIMx_CR1 的最低位,也就是计数器使能位,该位必须置 1,才能让定时器开始计数。 从第 4 位 DIR 可以看出默认的计数方式是向上计数, 同时也可以向下计数,第 5,6位是设置计数对齐方式的。 从第 8 和第 9 位可以看出,我们还可以设置定时器的时钟分频因子为 1,2,4。
DMA/中断使能寄存器(TIMx_DIER):
这里我们同样仅关心它的第 0 位, 该位是更新中断允许位。该位要设置为 1,来允许由于更新事件所产生的中断。
预分频器(TIMx_PSC):
该寄存器用设置对时钟进行分频,然后提供给计数器,作为计数器的时钟。
这里,定时器的时钟来源有 4 个:
1) 内部时钟(CK_INT)
2) 外部时钟模式 1:外部输入脚(TIx)
3) 外部时钟模式 2:外部触发输入(ETR)
4) 内部触发输入(ITRx):使用 A 定时器作为 B 定时器的预分频器(A 为 B 提供时钟)。
这些时钟,具体选择哪个可以通过 TIMx_SMCR 寄存器的相关位来设置。这里的 CK_INT时钟是从 APB1 倍频的来的,除非 APB1 的时钟分频数设置为 1,否则通用定时器 TIMx 的时钟是 APB1 时钟的 2 倍,当 APB1 的时钟不分频的时候,通用定时器 TIMx 的时钟就等于 APB1的时钟。这里还要注意的就是高级定时器的时钟不是来自 APB1,而是来自 APB2 的。
计数器(TIMxCNT):
该寄存器是定时器的计数器,该寄存器存储了当前定时器的计数值
自动重转载寄存器(TIMx_ARR):
该寄存器在物理上实际对应着 2 个寄存器。一个是程序员可以直接操作的,另外一个是程序员看不到的,这个看不到的寄存器在《STM32参考手册》里面被叫做影子寄存器。事实上真正起作用的是影子寄存器。 根据 TIMx_CR1 寄存器中 APRE 位的设置: APRE=0 时,预装载寄存器的内容可以随时传送到影子寄存器,此时 2者是连通的;而 APRE=1 时,在每一次更新事件(UEV)时,才把预装在寄存器的内容传送到影子寄存器。
状态寄存器(TIMx_SR):
该寄存器用来标记当前与定时器相关的各种事件/中断是否发生。
常用库函数:
定时器参数初始化:
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
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_TimeBaseStructure.TIM_Period = 4999;
TIM_TimeBaseStructure.TIM_Prescaler =7199;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
定时器使能函数:
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
定时器中断使能函数:
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
状态标志位获取和清除:
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
总结——定时器中断实现步骤
① 能定时器时钟。 RCC_APB1PeriphClockCmd();
② 初始化定时器,配置ARR,PSC。 TIM_TimeBaseInit();
③开启定时器中断,配置NVIC。 void TIM_ITConfig(); NVIC_Init();
④ 使能定时器。 TIM_Cmd();
⑥ 编写中断服务函数。 TIMx_IRQHandler();