[其他ST产品] STM32CubeMX之定时器PWM输出

[复制链接]
 楼主| xiyaoko2365 发表于 2023-10-28 21:17 | 显示全部楼层 |阅读模式
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输出使能。


 楼主| xiyaoko2365 发表于 2023-10-28 21:17 | 显示全部楼层
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波形实例。

86873653d09f9a8c8d.png

 本示例实现 IO 输出模式–PWM 波形输出。 以 LED 驱动为例, 使用定时器高级功能(PWM 模式), 实现呼吸灯效果。
 楼主| xiyaoko2365 发表于 2023-10-28 21:18 | 显示全部楼层
硬件接口
  本硬件平台有3个LED灯分别为LED2、LED3、LED4LED2接PA1,LED2接PB8,LED4接PB9,硬件原理图如下:

69226653d0a15a3bf6.png
 楼主| xiyaoko2365 发表于 2023-10-28 21:18 | 显示全部楼层
 根据STM32引脚定义手册或者STM32CUbeMX软件我们可得知定时器4的CH1和CH2对应外部引脚PB8和PB9。
20112653d0a2175867.png
 楼主| xiyaoko2365 发表于 2023-10-28 21:18 | 显示全部楼层
软件设计
  打开STM32CubeMX工具,配置定时器4,将PB8配置为定时器4通道3(复用推挽输出),PB9配置为定时器4通道4(复用推挽输出)。

92355653d0a2d71a0d.png
 楼主| xiyaoko2365 发表于 2023-10-28 21:18 | 显示全部楼层
 楼主| xiyaoko2365 发表于 2023-10-28 21:19 | 显示全部楼层
定时器4 基本配置及PWM模式配置
  配置定时器通道模式为PWM模式,设置分频系数为72,重装载值为500,设置有效电平为低电平。

79161653d0a4c3d402.png
 楼主| xiyaoko2365 发表于 2023-10-28 21:19 | 显示全部楼层
.参数说明
41798653d0a5e931b4.png
 楼主| xiyaoko2365 发表于 2023-10-28 21:19 | 显示全部楼层
 楼主| xiyaoko2365 发表于 2023-10-28 21:19 | 显示全部楼层
代码生成
  TIM4基本功能配置
  1. /* TIM4 init function */
  2. void MX_TIM4_Init(void)
  3. {
  4.   TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  5.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  6.   TIM_OC_InitTypeDef sConfigOC = {0};

  7.   htim4.Instance = TIM4;//定时器4
  8.   htim4.Init.Prescaler = 72-1;//分频系数72分频
  9.   htim4.Init.CounterMode = TIM_COUNTERMODE_UP;//向上计数方式
  10.   htim4.Init.Period = 300;//重装装载值
  11.   htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;//无时钟分频
  12.   htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;//自动重装载预装载使能
  13.   if (HAL_TIM_Base_Init(&htim4) != HAL_OK)//初始化定时器
  14.   {
  15.     Error_Handler();
  16.   }
  17.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  18.   if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  19.   {
  20.     Error_Handler();
  21.   }
  22.   if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
  23.   {
  24.     Error_Handler();
  25.   }
  26.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  27.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  28.   if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  29.   {
  30.     Error_Handler();
  31.   }
  32.   sConfigOC.OCMode = TIM_OCMODE_PWM1;//PWM模式1,CNT<CCR为有效电平
  33.   sConfigOC.Pulse = 0;//占空比
  34.   sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;//有效电平时间
  35.   sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;//快速比较使能
  36.   if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)//PWM模式初始化
  37.   {
  38.     Error_Handler();
  39.   }
  40.   if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  41.   {
  42.     Error_Handler();
  43.   }
  44.   HAL_TIM_MspPostInit(&htim4);//硬件层初始户化

  45. }
 楼主| xiyaoko2365 发表于 2023-10-28 21:20 | 显示全部楼层
 楼主| xiyaoko2365 发表于 2023-10-28 21:20 | 显示全部楼层
PWM模式配置:
16082653d0a8c641f1.png
 楼主| xiyaoko2365 发表于 2023-10-28 21:21 | 显示全部楼层
PB8、PB9引脚配置和PWM模式使能

HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_3);//初始化通道3
HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_4);//初始化通道4
 楼主| xiyaoko2365 发表于 2023-10-28 21:21 | 显示全部楼层
 引脚模式配置及PWM初始化
  1. void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
  2. {

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

  7.   /* USER CODE END TIM4_MspPostInit 0 */

  8.     __HAL_RCC_GPIOB_CLK_ENABLE();
  9.     /**TIM4 GPIO Configuration
  10.     PB8     ------> TIM4_CH3
  11.     PB9     ------> TIM4_CH4
  12.     */
  13.     GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
  14.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  15.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  16.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  17.   /* USER CODE BEGIN TIM4_MspPostInit 1 */
  18.   HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_3);//启动通道3
  19.   HAL_TIM_PWM_Start(timHandle,TIM_CHANNEL_4);//启动通道4
  20.   /* USER CODE END TIM4_MspPostInit 1 */
  21.   }
  22. }
 楼主| xiyaoko2365 发表于 2023-10-28 21:30 | 显示全部楼层
 楼主| xiyaoko2365 发表于 2023-10-28 21:30 | 显示全部楼层
呼吸灯主函数示例

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;
  }
 楼主| xiyaoko2365 发表于 2023-10-28 21:32 | 显示全部楼层
5.HAL库定时器常用函数介绍
  HAL库中定时器基本功能函数源码均在stm32f1xx_hal_tim.c中,高级功能函数在stm32f1xx_hal_tim_ex.c中,本小节主要介绍几个常用函数。(以下列举函数可能需要用户调用或修改)。

  1. /*硬件层初始化:时钟、中断,DMA*/
  2. void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim);
  3. /*中断方式开启定时器*/
  4. HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
  5. /*DMA方式开启定时器*/
  6. HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length);
  7. /*开启定时器PWM模式*/
  8. HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);

  9. /*获取状态*/
  10. HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim);
  11. /*中断方式开启定时器输入捕获功能*/
  12. HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
 楼主| xiyaoko2365 发表于 2023-10-28 21:32 | 显示全部楼层
软件仿真效果展示
  通过KEIL软件仿真,查看引脚电平变化,KEIL软件相关设置:
CPU DLL:SARMCM3.DLL
Dialog DLL:DARMSTM.DLL Parameter:-pSTM32F103C8
84082653d0d658c1cc.png
 楼主| xiyaoko2365 发表于 2023-10-28 21:32 | 显示全部楼层
 进入仿真模式:
88387653d0d727989d.png
 楼主| xiyaoko2365 发表于 2023-10-28 21:32 | 显示全部楼层
查看引脚电平变化波形:

9505653d0d7ec3553.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

511

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

36

主题

511

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部