cubemx_time_pwm分析

来源:互联网 发布:egd网络小黄金骗局 编辑:程序博客网 时间:2024/06/07 00:52

PWM模式下可以产生一个由ARR(自动重装载寄存器)寄存器确定频率,CCR(捕获比较寄存器)寄存器确定占空比的信号。

在设置时自动装装载的预装载位和捕获比较寄存器的预装载位。这样只有发送更新事件预装载寄存器的值传到影子寄存器,所以开始计数前通过设置EGR寄存器的UG位来产生一个更新事件初始化定时器。

我们这里讲解的就选取向上计数。都是一样的道理。


还是首先是一个时基单元的参数配置。直接看初始化函数的关键代码。


void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{


  if(tim_baseHandle->Instance==TIM3)
  {
  /* USER CODE BEGIN TIM3_MspInit 0 */


  /* USER CODE END TIM3_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_TIM3_CLK_ENABLE();


    /* Peripheral interrupt init */
    HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(TIM3_IRQn);
  /* USER CODE BEGIN TIM3_MspInit 1 */


  /* USER CODE END TIM3_MspInit 1 */
  }
}


void TIM_Base_SetConfig(TIM_TypeDef *TIMx, TIM_Base_InitTypeDef *Structure)
{
  uint32_t tmpcr1 = 0;
  tmpcr1 = TIMx->CR1;


  /* Set TIM Time Base Unit parameters ---------------------------------------*/
  if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx))
  {
    /* Select the Counter Mode */
    tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
    tmpcr1 |= Structure->CounterMode;
  }


  if(IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx))
  {
    /* Set the clock division */
    tmpcr1 &= ~TIM_CR1_CKD;
    tmpcr1 |= (uint32_t)Structure->ClockDivision;
  }


  TIMx->CR1 = tmpcr1;


  /* Set the Autoreload value */
  TIMx->ARR = (uint32_t)Structure->Period ;


  /* Set the Prescaler value */
  TIMx->PSC = (uint32_t)Structure->Prescaler;


  if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx))
  {
    /* Set the Repetition Counter value */
    TIMx->RCR = Structure->RepetitionCounter;
  }


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

所以初始化函数主要是打开了time外设时钟,设置了中断。并且将配置参数写入寄存器,通过EGR的UG位触发一个更新时间去写到影子寄存器。这就更新了定时器。


我们从名字得出这个配置就是配置时钟的。我们去看一下


可以看出先是清除了四个位,功能分别是关闭从模式(若CEN==1,预分频器时钟为内部时钟),内部触发0(用于同步计数器触发输入),外部触发预分频。

我们的参数满足第一个case条件,将低三位写入了0,查手册可以得知就是关闭从模式(若CEN==1,预分频器时钟为内部时钟),所以我们可以直接用了内部时钟。

  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }


看出这个作用,初始化需要的中断,DMA,GPIO和时钟,因为之前已经初始化了,所以这里不再初始化,下一步又把时基单元配置了下,觉得这里配置是基单元有点重复,可以删除一个。

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }

这个是关于主模式的设置,因为我们没有用到定时器去触发定时器,所以简单看下就好,


先是清除了MMS位,然后与等于0x0000(宏定义),这样查手册看寄存器得知EGR的UG位被用于作为触发输出。

然后清除了MSM位,这就被设置了主从模式无作用。

下面就是关键部分的代码了。


因为PWM是一个输出,所以我们配置了输出通道的参数。


初始化函数是一个多分支语句,我们看一个即可。都是一样的操作。


首先是失能了通道x的输出,使用三个变量得到了CCER,CR2,CCMR2的寄存器值。

然后清除了两个控制位之后配置为PWM模式1(在向上计数时,一旦TIMx_CNT<TIMx_CCRx时通道1为有效电平,否则为无效电平)

通道3输出使能。



这是关于高级定时器的,没有用到。


这里三条代码都是写入到寄存器,还有一个就是设置了Pulse的值。设置了CCRx的值,

回到case条件配置了通道x的预装载使能和快速使能。

HAL_TIM_MspPostInit(&htim3);最后的这句代码就是GPIO的配置了。


0 0
原创粉丝点击