小弟在用定时器时做pwm,遇到一点小疑问,就是关于TIM1_PSCReloadMode是否有意义。官方手册对于预分频器时这样描述的:
预分频器可以将计数器的时钟频率按1到65536之间的任意值分频。它是基于一个(在TIMx_PSC寄存器中的)16位寄存器控制的16位计数器。这个控制寄存器带有缓冲器,它能够在工作时被改变。新的预分频器参数在下一次更新事件到来时被采用。
在学习使用PWM输出时,发现ARR和CCR寄存器也都有相应的预装载寄存器。在改变ARR的值或者CCR的值时要看是否使能相应的与装载器,来判断什么时候将预装载器的值写入影子寄存器当中。
但是我发现使用void TIM1_PrescalerConfig(u16 Prescaler, u16 TIM1_PSCReloadMode)函数改变预分频器时,有个预分频重载模式选择,可选
TIM1_PSCReloadMode_Update ;TIM1预分频值在更新事件装入。TIM1_PSCReloadMode_Immediate;TIM1预分频值即时装入。
按照手册的描述,无论怎么写入值,也都只能在下一次更新时间到来时被采用啊。
但是在做实验的时候,发现选即时装入时,就不能正确发出PWM波,后来改为在更新事件装入就可以正确发出PWM波。
而我再查找官方手册时也并没有看到像ARR和CCR寄存器那样关于使能预装载器之类的操作。
然而我在tim.c里发现,在初始化结构体时,系统选择的是预分频值即时装入
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
{
uint16_t tmpcr1 = 0;
/* Check the parameters */
assert_param(IS_TIM_ALL_PERIPH(TIMx));
assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode));
assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision));
tmpcr1 = TIMx->CR1;
if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)||
(TIMx == TIM4) || (TIMx == TIM5))
{
/* Select the Counter Mode */
tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;
}
if((TIMx != TIM6) && (TIMx != TIM7))
{
/* Set the clock division */
tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD));
tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;
}
TIMx->CR1 = tmpcr1;
/* Set the Autoreload value */
TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;
/* Set the Prescaler value */
TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;
if ((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| (TIMx == TIM16) || (TIMx == TIM17))
{
/* Set the Repetition Counter value */
TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;
/* Generate an update event to reload the Prescaler and the Repetition counter
values immediately */
TIMx->EGR = TIM_PSCReloadMode_Immediate;
}
所以我想问一下,在初始化结构体时,或者系统初始化时,是否有使能PSC预分频器预装载的操作。
为什么系统选择TIM1_PSCReloadMode_Immediate;TIM1预分频值即时装入就可以用,我用TIM1_PrescalerConfig来改变预分频值,选择即时写入却没用。
这两种模式是否有用呢?
小弟还不太明白,希望有大佬能够给点点拨,谢谢! |