(一)前言:
在浏览固件库函数的时候,看到了void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
。百思不得其解,明明在初始化定时器的时候,已经设置定时周期了,为什么这里还需要配置(使能)一次呢?翻阅手册后,发现这个函数是用于配置预装载寄存器的,而不是用于配置重装载寄存器。
(二)预装载寄存器:
理解:
- 如果
ARPE=1
,那么调用void TIM_SetAutoreload()
修改定时周期的时候,不会在本次计时周期立即生效,会在下一次计时周期生效。 - 如果
ARPE=0
,则会在本次计时周期立即生效。
官方手册介绍:
- 寄存器介绍:
- ARPE介绍:
(三)代码验证:
当ARPE=0
时,第一次定时器的计时周期则没有发生改变,计时到2秒后,溢出。见下图:
测试代码:
#include "stm32f10x.h"
#include "delay.h"
#include "uart.h"
#include "time.h"
/*ARPE = 0;在当前周期内,如果重装载了ARR寄存器,那么这个周期的溢出值会立刻发生改变。*/
/*ARPE = 1;在当前周期内,如果重装载了ARR寄存器,那么这个周期的溢出值不会立刻发生改变。下一个周期的溢出值会发生改变。*/
void Tim_config(void);
int main(void){
uint8_t i = 0;
uint16_t time_count;
uart_config();
Tim_config();
while(1){
if(i == 0){
// 1秒后,修改计时周期
delay_ms_soft(1000);
TIM_SetAutoreload(TIM3,65535);
i = 1;
}
time_count = TIM_GetCounter(TIM3);
printf("time_count:%d\r\n",time_count);
}
}
void Tim_config(void){
TIM_TimeBaseInitTypeDef TIM3_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM3_TimeBaseInitStruct.TIM_Period = 20000 - 1;
TIM3_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1;
TIM3_TimeBaseInitStruct.TIM_ClockDivision = 0;
TIM3_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3,&TIM3_TimeBaseInitStruct);
NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
TIM_ARRPreloadConfig(TIM3,DISABLE); // 使能预装载寄存器
TIM_ClearFlag(TIM3,TIM_FLAG_Update);
TIM_Cmd(TIM3,ENABLE);
}
void TIM3_IRQHandler(void){
uint16_t timer_count = TIM_GetCounter(TIM3);
if(TIM_GetITStatus(TIM3,TIM_IT_Update) == SET){
TIM_ClearFlag(TIM3,TIM_FLAG_Update);
}
}