STM32CubeMX的TIM1互补PWM输出,HAL库(2路,带死区)

芯片为STM32F407ZG,使用的是高级定时器TIM1的PWM互补PWM输出。
效果:

整体的:(通道0~3分别是CH1、CH1N、CH2、CH2N。)在这里插入图片描述
细节:
在这里插入图片描述

CH1和CH1N的死区时间是0.375us(公式算出来应该是公式0.3us左右,跟逻辑分析仪的采样频率有关系)
CH1和CH2、CH1N和CH2N是同步的,以前做H桥的话就需要这种吧(对角同时导通),有相位差的后面再研究。(补充:后面发现这个问题F3系列的芯片比较好实现,用非对称PWM,F4可以用TIM1和TIM8配合实现,原理利用TIM1去触发TIM8)

STM32CubeMX配置:
在这里插入图片描述
main函数

 /* USER CODE BEGIN 2 */
	/****普通定时器***/
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
	/****高级定时器互补输出***/
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);
	HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1);
	HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2);
	/****寄存器方法修改比较寄存器的值,ARR的值cube配置为1000***/
	TIM1->CCR1=249;
	TIM1->CCR2=249;
  /* USER CODE END 2 */

说明:
代码中普通定时器只是为了测试!
高级定时器与普通定时器用法有微笑区别,网上查资料总是误导,很多教程都提到要用HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1)这一句,但是只有这一句CH1N会有输出,CH1就没了,走了不少弯路。

细看高级定时器的函数名,一个是PWM、一个是PWMN,而HAL_TIMEx_PWMN_Start与HAL_TIM_PWM_Start相比多了一个Ex,所在的.c文件也不相同。猜想带Ex的可能是扩展功能吧

再来看看死区时间计算吧:
cubemx生成的代码如下:

void MX_TIM1_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 167;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 999;
  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_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 99;
  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();
  }
  sConfigOC.Pulse = 199;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 50;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_TIM_MspPostInit(&htim1);
}

sBreakDeadTimeConfig.DeadTime = 50;这句就是死区时间了,怎么算,参考STM32F4xx中文参考手册.pdf
在这里插入图片描述
DeadTime 是直接写入DTG[7:0],显然,当DeadTime <128时,最高位都是0,按照最上面的那条公式算就好了,DT=50Tdtg,其中,Tdtg=tDTS=1/164Mhz(tim1接在高速时钟APB2),算出来就是DT=501/164M=0.3048us了

个人调试心得,感谢点赞

  • 30
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
STM32CubeMX 中生成带死区PWM 确实有一些步骤。下面是一个简单的步骤,供您参考: 1. 打开 STM32CubeMX,并选择您要使用的 MCU 型号。 2. 在 "Pinout" 选项卡中选择您要使用的 PWM 引脚。 3. 在 "Configuration" 选项卡中,选择 "TIMx" 配置器,并启用 PWM 模式。 4. 在 "TIMx" 配置器中,启用 "Advanced" 选项。 5. 在 "Advanced" 选项卡中,启用 "Complementary" 模式,并启用 "DeadTime insertion". 6. 在 "Advanced" 选项卡中,可以设置死区时间和极性。 完成上述步骤后,您可以在代码中使用 HAL 库来初始化 PWM 并设置死区时间和极性。例如: ```c TIM_HandleTypeDef htim; // 配置 PWM死区时间 htim.Instance = TIMx; htim.Init.Prescaler = ...; htim.Init.Period = ...; htim.Init.ClockDivision = ...; htim.Init.CounterMode = TIM_COUNTERMODE_UP; htim.Init.RepetitionCounter = ...; htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_PWM_Init(&htim) != HAL_OK) { Error_Handler(); } HAL_TIM_PWM_ConfigChannel(&htim, &sConfigOC, TIM_CHANNEL_1); HAL_TIM_PWM_ConfigChannel(&htim, &sConfigOC, TIM_CHANNEL_2); HAL_TIM_PWM_MspInit(&htim); // 设置死区极性和时间 HAL_TIMEx_ConfigCommutationEvent_IT(&htim, TIM_TS_NONE, TIM_COMMUTATIONDELAY_0); HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig); HAL_TIMEx_ConfigComplementaryOutputChannel(&htim, &sComplementaryConfigOC, TIM_CHANNEL_1); HAL_TIMEx_ConfigComplementaryOutputChannel(&htim, &sComplementaryConfigOC, TIM_CHANNEL_2); HAL_TIMEx_ConfigComplementaryOutputNChannel(&htim, &sComplementaryConfigOCN, TIM_CHANNEL_1); HAL_TIMEx_ConfigComplementaryOutputNChannel(&htim, &sComplementaryConfigOCN, TIM_CHANNEL_2); HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig); ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值