void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) { /* Check the parameters */ assert_param(IS_TIM_123458_PERIPH(TIMx)); assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode)); assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision)); /* Select the Counter Mode and set the clock division */ TIMx->CR1 &= CR1_CKD_Mask & CR1_CounterMode_Mask;//回复5楼 TIMx->CR1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision | TIM_TimeBaseInitStruct->TIM_CounterMode;
/* Set the Autoreload value */ TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;
/* Set the Prescaler value */ TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;
if (((*(uint32_t*)&TIMx) == TIM1_BASE) || ((*(uint32_t*)&TIMx) == TIM8_BASE)) { /* Set the Repetition Counter value */ TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter; }
/* Generate an update event to reload the Prescaler value immediatly */ TIMx->EGR = TIM_PSCReloadMode_Immediate; }
//================================ 回6楼 ,你说的 和 我在1楼说的是一样的啊!!!! 解释不了ARR的值如何传送到它的影子寄存器? 我在一楼说了ARR的值传送到对应的影子寄存器的值的两种方法:TIMx_ARR的值是传送到它对应的影子寄存器中,可以这样做:当TIMx_CR1的位APRE=0时,立即将TIMx_ARR的值传送到它对应的影子寄存器中。当TIMx_CR1的位APRE=1时,则当发生更新事件时,将TIMx_ARR的值传送到它对应的影子寄存器中。 可是 现在情况是禁止更新事件,并且APRE=1.所以这两种方法都行不通。 所以按道理说只能通过设置EGR的UG为1了,因为手册中说UG=1时,Re-initialize the counter and generates an update of the registers.), 但是TIMx->EGR = TIM_PSCReloadMode_Immediate; 上面的注释是 /* Generate an update event to reload the Prescaler value immediatly */就是说设置UG=1仅仅为了立即重装PSC的值。 并且即便把TIMx->EGR = TIM_PSCReloadMode_Immediate; 删除,ARR的值仍会传送到它的影子寄存器中。 真不知道是如何传送的?
手册中讲ARR自装载寄存器时,是这样说的: ================================================================= The update event is sent when the counter reaches the overflow (or underflow when downcounting) and if the UDIS bit equals 0 in the TIMx_CR1 register. It can also be generated by software. ================================================================= 更新事件是这样产生的: 计数器溢出 and UDIS=0 也可以通过软件产生(就是设置UG)
将int main(void)函数里面的TIM_ARRPreloadConfig(TIM3, ENABLE);挪到下面的位置,似乎就不能装进影子寄存器了!!! void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) { /* Check the parameters */ assert_param(IS_TIM_123458_PERIPH(TIMx)); assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode)); assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision)); /* Select the Counter Mode and set the clock division */ TIMx->CR1 = (uint16_t)0x0002; TIM_ARRPreloadConfig(TIM3, ENABLE); TIMx->CR1 &= CR1_CKD_Mask & CR1_CounterMode_Mask; TIMx->CR1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision | TIM_TimeBaseInitStruct->TIM_CounterMode;
/* Set the Autoreload value */ TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;
/* Set the Prescaler value */ TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;
if (((*(uint32_t*)&TIMx) == TIM1_BASE) || ((*(uint32_t*)&TIMx) == TIM8_BASE)) { /* Set the Repetition Counter value */ TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter; }
/* Generate an update event to reload the Prescaler value immediatly */ TIMx->EGR = TIM_PSCReloadMode_Immediate; }