STM32F103C8--用STM32CubeMX生成PWM程序

demi的头像
demi 发布于:周一, 11/09/2020 - 11:06 ,关键词:

一、配置定时器为PWM产生


二、配置时钟树


三、定时器配置


四、配置完生成程序后,主程序里还要进行启动PWM就可以了

  MX_TIM3_Init();
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);//启动。置1  CCER的输出使能位bit4
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);//CCER的bit0

然后可以改变占空比了。
**特别注意:**占空比不能大于自动重载寄存器ARR的值,不然输出的都是高电平。这个问题整了一天。

五、程序分析


/* TIM3 init function */
static void MX_TIM3_Init(void)
{

  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;
//------------------实际是调用TIM_Base_SetConfig配置定时器,上一篇分析过--
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 71;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 99;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
//---------------------这个是默认的,不管-------------------------------
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
//----------------配置输出比较部分-- 上图5部分-------------------------------
  sConfigOC.OCMode = TIM_OCMODE_PWM1;//输出模式PWM1
  sConfigOC.Pulse = 80;//占空比
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;//高电平极性
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
//----------------------------------------------------------------------------------
  sConfigOC.Pulse = 50;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
  HAL_TIM_MspPostInit(&htim3);//初始化引脚IO
}

初始化PWM通道HAL_TIM_PWM_ConfigChannel------>调用

case TIM_CHANNEL_1:
{
  assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
  /* Configure the Channel 1 in PWM mode */
  TIM_OC1_SetConfig(htim->Instance, sConfig);

  /* Set the Preload enable bit for channel1 */
  htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE;//比较模式寄存器CCMR1的bit3位OC1PE置1,写入到CCR1的值在事件更新时,才会传到影子寄存器。清0则写入CCR1的值会马上起作用
  
  /* Configure the Output Fast mode */
  htim->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE;//配置CCMR1的bit2位,输出比较快速使能
  htim->Instance->CCMR1 |= sConfig->OCFastMode;
}
break;
//--------------------------------------------------------------------------------

 void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config)
   {
  uint32_t tmpccmrx = 0U;
  uint32_t tmpccer = 0U;
  uint32_t tmpcr2 = 0U;

   /* Disable the Channel 1: Reset the CC1E Bit */
  TIMx->CCER &= ~TIM_CCER_CC1E;//关通道 CCER  bit0清0

  /* 读出三个寄存器的值 */
  tmpccer = TIMx->CCER;
  tmpcr2 =  TIMx->CR2;
  tmpccmrx = TIMx->CCMR1;

  /* Reset the Output Compare Mode Bits */
  tmpccmrx &= ~TIM_CCMR1_OC1M;//复位CCMR1的bit6:4
  tmpccmrx &= ~TIM_CCMR1_CC1S;//复制CCMR1的bit1:0
  /* Select the Output Compare Mode */
  tmpccmrx |= OC_Config->OCMode;//配置OC1M为 110  PWM1模式

  /* Reset the Output Polarity level */
  tmpccer &= ~TIM_CCER_CC1P;//配置输出极性 CCER的 CC1P位
  tmpccer |= OC_Config->OCPolarity;

  if(IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_1))//如果是定时器1的123通道,还要设置互补输出
  {
    assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity));
    /* Reset the Output N Polarity level */
    tmpccer &= ~TIM_CCER_CC1NP;
    /* Set the Output N Polarity */
    tmpccer |= OC_Config->OCNPolarity;
    /* Reset the Output N State */
    tmpccer &= ~TIM_CCER_CC1NE;
  }

  if(IS_TIM_BREAK_INSTANCE(TIMx))//如果是定时器1,还要设置CR2的bit8  bit9 死区控制
  {
    /* Check parameters */
    assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState));
    assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));

    /* Reset the Output Compare and Output Compare N IDLE State */
    tmpcr2 &= ~TIM_CR2_OIS1;
    tmpcr2 &= ~TIM_CR2_OIS1N;
    /* Set the Output Idle state */
    tmpcr2 |= OC_Config->OCIdleState;
    /* Set the Output N Idle state */
    tmpcr2 |= OC_Config->OCNIdleState;
  }
  /* 把设置好的值写入这4个寄存器 */
  TIMx->CR2 = tmpcr2;
  TIMx->CCMR1 = tmpccmrx;
  TIMx->CCR1 = OC_Config->Pulse;//占空比
  TIMx->CCER = tmpccer;
}

流程图如下:


需要改变占空比的,直接调用
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,dutycycle);
改变寄存器CCR1,改变的值是立即生效还是下一个周期生效取决于CCMR1的OC1PE位

 while (1)
  {
		while(dutycycle<100)
		{
			dutycycle+=10;
			__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,dutycycle);
			HAL_Delay(1);
		}
		while(dutycycle)
		{
			dutycycle-=10;
			__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,dutycycle);
			HAL_Delay(1);
		}
}

版权声明:本文为CSDN博主 - D.luffy 的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/liangbin414/article/details/88707340

围观 479