STM32CubeMX之定时器PWM输出

STM32CubeMX之定时器PWM输出

知识百科 – PWM简介

  PWM是一种对模拟信号电平进行​​ ​​数字编码​​​​​的方法。通过高​​ ​​分辨率​​​​计数器的使用,方波的占空比被调制用来对一个具体​​ ​​模拟信号​​​​的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。
  脉宽调制(PWM,Pulse Width Modulation)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中 。
  PWM的一个优点是从处理器到​​ ​被控系统​​​信号都是数字形式的,再进行数模转换。可将噪声影响降到最低(可以跟电脑一样)。噪声只有在强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,也才能对数字信号产生影响。

STM32定时器PWM输出简介

  定时器脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。在TIMx_CCMRx寄存器中的OCxM位写入’110’(PWM模式1)或’111’(PWM模式2),能够独立地设置每个OCx输出通道产生一路PWM。必须设置TIMx_CCMRx寄存器OCxPE位以使能相应的预装载寄存器,最后还要设置TIMx_CR1 寄存器的ARPE位, (在向上计数或中心对称模式中)使能自动重装载的预装载寄存器。
   仅当发生一个更新事件的时候,预装载寄存器才能被传送到影子寄存器,因此在计数器开始计数之前,必须通过设置TIMx_EGR寄存器中的UG位来初始化所有的寄存器。OCx的极性可以通过软件在TIMx_CCER寄存器中的CCxP位设置,它可以设置为高电平有效或低电平有效。 TIMx_CCER寄存器中的CCxE位控制OCx输出使能。

  • PWM模式介绍

  在计数器向上计数模式下(即TIMx_CR1的DIR位为0) ,当TIMx_CNT<TIMx_CCRx时PWM信号参考OCxREF为高,否则为低。如果TIMx_CCRx中的比较值大于自动重装载值(TIMx_ARR),则OCxREF保持为’1’。如果比较值为0,则OCxREF保持为’0’。 下图为TIMx_ARR=8(ARR重装载寄存器,表示定时器的计数周期)时边沿对齐的PWM波形实例。
在这里插入图片描述

  本示例实现 IO 输出模式–PWM 波形输出。 以 LED 驱动为例, 使用定时器高级功能(PWM 模式), 实现呼吸灯效果。

1.硬件接口

  本硬件平台有3个LED灯分别为LED2、LED3、LED4LED2接PA1,LED2接PB8,LED4接PB9,硬件原理图如下:
在这里插入图片描述
  根据STM32引脚定义手册或者STM32CUbeMX软件我们可得知定时器4的CH1和CH2对应外部引脚PB8和PB9。
在这里插入图片描述

2 软件设计

  打开STM32CubeMX工具,配置定时器4,将PB8配置为定时器4通道3(复用推挽输出),PB9配置为定时器4通道4(复用推挽输出)。
在这里插入图片描述
在这里插入图片描述
  定时器4 基本配置及PWM模式配置
  配置定时器通道模式为PWM模式,设置分频系数为72,重装载值为500,设置有效电平为低电平。
在这里插入图片描述

3.参数说明

模式 说明
Input capture direct mode 输入捕获直接模式
Input capture indirectmode 输入捕获间接模式
Input capture triggered by TRC 输入捕获触发器模式
Output compare no output 输出比较(冻结模式000 )
Output compare CH3 输出比较(001)
PWM Generation No output PWM产生无输出
PWM Generation CH3 PWM输出到CH3
CH3 Combined channels 联合通道
xor activation 定时器输入异或模式
在这里插入图片描述

4. 代码生成

  TIM4基本功能配置

/* TIM4 init function */
void MX_TIM4_Init(void)
{
    
    
  TIM_ClockConfigTypeDef sClockSourceConfig = {
    
    0};
  TIM_MasterConfigTypeDef sMasterConfig = {
    
    0};
  TIM_OC_InitTypeDef sConfigOC = {
    
    0};

  htim4.Instance = TIM4;//定时器4
  htim4.Init.Prescaler = 72-1;//分频系数72分频
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;//向上计数方式
  htim4.Init.Period = 300;//重装装载值
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;//无时钟分频
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;//自动重装载预装载使能
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)//初始化定时器
  {
    
    
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  {
    
    
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
  {
    
    
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  {
    
    
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;//PWM模式1,CNT<CCR为有效电平
  sConfigOC.Pulse = 0;//占空比
  sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;//有效电平时间
  sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;//快速比较使能
  if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)//PWM模式初始化
  {
    
    
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  {
    
    
    Error_Handler();
  }
  HAL_TIM_MspPostInit(&htim4);//硬件层初始户化

}

在这里插入图片描述
  PWM模式配置:
在这里插入图片描述
  PB8、PB9引脚配置和PWM模式使能

HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_3);//初始化通道3
HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_4);//初始化通道4

  引脚模式配置及PWM初始化

void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{
    
    

  GPIO_InitTypeDef GPIO_InitStruct = {
    
    0};
  if(timHandle->Instance==TIM4)
  {
    
    
  /* USER CODE BEGIN TIM4_MspPostInit 0 */

  /* USER CODE END TIM4_MspPostInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**TIM4 GPIO Configuration
    PB8     ------> TIM4_CH3
    PB9     ------> TIM4_CH4
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* USER CODE BEGIN TIM4_MspPostInit 1 */
  HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_3);//启动通道3
  HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_4);//启动通道4
  /* USER CODE END TIM4_MspPostInit 1 */
  }
}

在这里插入图片描述

4.呼吸灯主函数示例

while (1)
  {
    
    
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		/*实现呼吸灯*/
		if(flag==0)i++;
		else i--;
		if(i>=300)flag=1;
		if(i==0)flag=0;
		HAL_Delay(3);
		htim4.Instance->CCR3=i;//调节占空比
		htim4.Instance->CCR4=i;
  }

5.HAL库定时器常用函数介绍

  HAL库中定时器基本功能函数源码均在stm32f1xx_hal_tim.c中,高级功能函数在stm32f1xx_hal_tim_ex.c中,本小节主要介绍几个常用函数。(以下列举函数可能需要用户调用或修改)。

扫描二维码关注公众号,回复: 15143211 查看本文章
/*硬件层初始化:时钟、中断,DMA*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim);
/*中断方式开启定时器*/
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
/*DMA方式开启定时器*/
HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length);
/*开启定时器PWM模式*/
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);

/*获取状态*/
HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim);
/*中断方式开启定时器输入捕获功能*/
HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)

6.软件仿真效果展示

  通过KEIL软件仿真,查看引脚电平变化,KEIL软件相关设置:
CPU DLL:SARMCM3.DLL
Dialog DLL:DARMSTM.DLL Parameter:-pSTM32F103C8
在这里插入图片描述
  进入仿真模式:
在这里插入图片描述
  查看引脚电平变化波形:在这里插入图片描述
在这里插入图片描述
  波形效果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44453694/article/details/122351580