打印

发现评估板历程中一处有疑问

[复制链接]
1728|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lanseshuijing|  楼主 | 2013-9-12 23:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
工程文件名:TIM_TimeBase
代码段:
PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 500000) - 1;
  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  /* Prescaler configuration */
  TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate);
问什么向把预分频值设置成0再用TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate);函数配置预分频值呢?
经过通过网络搜索答案如下:
原来PSC也有个预装载功能,却不像ARR和CRR那样有相关的位控制立即装载或更新事件装载。也就是说只能更新事件来装载。在上面函数中手工产生了一个更新事件,使PSC立刻生效。
但是我发现
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);函数里已经用到了
/* Generate an update event to reload the Prescaler
     and the repetition counter(only for TIM1 and TIM8) value immediatly */
  TIMx->EGR = TIM_PSCReloadMode_Immediate; 通过设置EGR位产生更新事件已经将预分频值装置到影子寄存器了
何必将预分频值先写为0再通过TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
函数在配置呢?
两个配置函数如下:
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)(~(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)(~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))  
  {
    /* Set the Repetition Counter value */
    TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;
  }

  /* Generate an update event to reload the Prescaler
     and the repetition counter(only for TIM1 and TIM8) value immediatly */
  TIMx->EGR = TIM_PSCReloadMode_Immediate;         
}


void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode)
{
  /* Check the parameters */
  assert_param(IS_TIM_ALL_PERIPH(TIMx));
  assert_param(IS_TIM_PRESCALER_RELOAD(TIM_PSCReloadMode));
  /* Set the Prescaler value */
  TIMx->PSC = Prescaler;
  /* Set or reset the UG Bit */
  TIMx->EGR = TIM_PSCReloadMode;
}




沙发
戈卫东| | 2013-9-13 07:22 | 只看该作者
他们的码有可能是为了确保安全和阅读,有些可能不是必须的

使用特权

评论回复
板凳
wnwnwn| | 2013-12-4 10:05 | 只看该作者
楼主,我也是关于TIM_Prescaler已经赋值,为什么还要用TIM_PrescalerConfig()重新赋值呢,感觉是多余的没有用处的吧。TIM_PSCReloadMode有两种方式,TIM_PSCReloadMode_Immediate和TIM_PSCReloadMode_Updata。TIM_TimeBaseInit()初始化函数中默认的是TIMx->EGR = TIM_PSCReloadMode_Immediate方式。TIM_PrescalerConfig()的目的是改变TIM_PSCReloadMode方式。如果不想改变的话,那么这条语句就是多余的。

楼主可以试下:在初始化的时候直接赋值 TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;然后,去掉TIM_PrescalerConfig()试一下。我想应该没问题的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

93

主题

749

帖子

4

粉丝