STM32CUBEIDE-F407(1)-生成互补带死区的PWM

本文详细介绍了如何使用STM32CUBEIDE配置STM32F407的高级定时器TIM1生成互补带死区的PWM信号,涉及定时器工作原理、计数模式、PWM模式设置和IDE操作步骤。
摘要由CSDN通过智能技术生成

概述

本章通过STM32CUBEIDE配置STM32F407输出互补带死区的PWM

定时器原理

本文选用的定时器为高级定时器TIM1,可生成互补带死区的PWM,其内部定时器原理如下图所示

其生成PWM波最主要的模块为其时基单元,时基单元主要包括:计数器寄存器 (TIMx_CNT)、预分频器寄存器 (TIMx_PSC)、自动重载寄存器 (TIMx_ARR)、重复计数器寄存器 (TIMx_RCR)。

预分频器可对计数器时钟频率进行分频,分频系数介于 1 65536 之间。

在递增计数模式下,计数器从 0 计数到自动重载值( TIMx_ARR 寄存器的内容),然后重新
0 开始计数并生成计数器上溢事件。如下图所示
在递减计数模式下,计数器从自动重载值( TIMx_ARR 寄存器的内容)开始递减计数到 0
然后重新从自动重载值开始计数并生成计数器下溢事件。如下图所示
在中心对齐模式下,计数器从 0 开始计数到自动重载值( TIMx_ARR 寄存器的内容) — 1
生成计数器上溢事件;然后从自动重载值开始向下计数到 1 并生成计数器下溢事件。之后从
0 开始重新计数。
将通道配置为输出模 式时,其输出比较中断标志将在以下模式下置 1 ,即:计数器递减计数(中心对齐模式 1 CMS = 01 ”)、计数器递增计数(中心对齐模式 2 CMS = 10 ”)以及计数器递增 / 减计数(中心对齐模式 3 CMS = 11 ”)。
在中心对齐模式下,如果 RCR 值为奇数,更新事件将在上溢或下溢时发生,这取决于何时
写入 RCR 寄存器以及何时启动计数器。如果在启动计数器前写入 RCR ,则 UEV 在上溢时
发生。如果在启动计数器后写入 RCR ,则 UEV 在下溢时发生。例如,如果 RCR = 3 UEV
将在每个周期的第四个上溢或下溢事件时生成(取决于何时写入 RCR )。

PWM模式

脉冲宽度调制模式可以生成一个信号,该信号频率由 TIMx_ARR 寄存器值决定,其占空比则
TIMx_CCRx 寄存器值决定。
通过向 TIMx_CCMRx 寄存器中的 OCxM 位写入 110 PWM 模式 1 )或 111 PWM 模式
2 ),可以独立选择各通道 (每个 OCx 输出对应一个 PWM )的 PWM 模式。
PWM 模式( 1 2 )下, TIMx_CNT 总是与 TIMx_CCRx 进行比较,以确定是TIMx_CCRxTIMx_CNT 还是 TIMx_CNTTIMx_CCRx (取决于计数器计数方向)。

PWM边沿对齐模式-递增计数/递减计数

TIMx_CR1 寄存器中的 DIR 位为低时执行递增计数,只要 TIMx_CNT < TIMx_CCRxPWM 参考信号 OCxREF 便为 高电平,否则为低电平。递减计数相似

PWM中心对齐模式

在根据 TIMx_CR1 寄存器中 CMS=01 而选择的中心对齐模式 1 下,当计数器递减计数
时,比较标志置 1

死区

高级控制定时器( TIM1 TIM8 )可以输出两路互补信号,并管理输出的关断与接通瞬间。

IDE操作

本章选用的为TIM1定时器,采用中心对齐模式1,生成互补带死区的PWM

注意,这里的PWM频率为定时器时钟频率/((PSC+1)*(ARR+1)*2)

若RCR=0,则其中断频率为PWM频率的两倍

void MX_TIM1_Init(void)
{

  /* USER CODE BEGIN TIM1_Init 0 */

  /* USER CODE END TIM1_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

  /* USER CODE BEGIN TIM1_Init 1 */

  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 5-1;
  htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
  htim1.Init.Period = 1680-1;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_ENABLE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 168;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */
//    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
//  //  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 124);
//    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
//    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);

}

在main.c函数里进行开启PWM操作

{
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
  HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
}
注意,生成互补的PWM,需要将两个通道都开启
 TIM1->CCR1=800;//根据此句语句对CCR1赋值,可改变输出PWM占空比
最终输出互补带死区的PWM

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以为你提供一个实现的思路,具体实现步骤如下: 1. 配置 TIM3 的时钟源和预分频系数,使其工作在合适的频率下。 2. 配置 TIM3 的自动重载寄存器 ARR,设置 PWM 的周期。 3. 配置 TIM3 的 PWM 模式为模式 1 或模式 2,并设置 PWM 的占空比。 4. 配置 TIM3 的互补输出模式,使其能够输出互补带死区PWM 信号。 下面是使用 HAL 库实现上述步骤的示例代码: ```c #include "stm32f0xx_hal.h" TIM_HandleTypeDef htim3; void TIM3_PWM_Init(void) { TIM_OC_InitTypeDef sConfigOC; // 使能 TIM3 时钟 __HAL_RCC_TIM3_CLK_ENABLE(); // 配置 TIM3 的时钟源和预分频系数 htim3.Instance = TIM3; htim3.Init.Prescaler = 0; // 不分频 htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 999; // PWM 周期为 1ms htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_Base_Init(&htim3); // 配置 TIM3 的 PWM 模式和占空比 sConfigOC.OCMode = TIM_OCMODE_PWM1; // PWM 模式 1 sConfigOC.Pulse = 500; // 占空比为 50% sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1); // 配置 TIM3 的互补输出模式 TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig; sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; sBreakDeadTimeConfig.DeadTime = 100; // 死区时间为 100us sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE; sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE; HAL_TIMEx_ConfigBreakDeadTime(&htim3, &sBreakDeadTimeConfig); // 启动 TIM3 的 PWM 输出 HAL_TIM_Base_Start(&htim3); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); } ``` 注意,上述代码中使用的是 PWM 模式 1,如果需要使用 PWM 模式 2,只需要将代码中的 `sConfigOC.OCMode` 设置为 `TIM_OCMODE_PWM2` 即可。同时,死区时间可以根据实际需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值