打印
[STM32F4]

【每周分享】STM32F407的pwm频率最高能到多少?实测

[复制链接]
87|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 地瓜patch 于 2025-3-4 20:53 编辑

#申请原创# @21小跑堂

一、缘起
最近有个需求,需要产生频率和占空比可调的方波,手头上有STM32F407的板子,就用它做一下测试。
因为需求提的很高频率调节步进1%,占空比步进0.1%。测一下STM32F407定时器产生PWM的极限频率,并关注占空比调节情况。
STM32F407用的很多,用也就用了,也不是用到极致,满则亏总要留些余量。
二、说明
要测最高频率那当然要用速度最快的定时器,从芯片的结构框图中能够看到TIM1和TIM8都挂在APB2上。
从上边框图上看到APB2的频率是84MHz,但是其上的定时器是在此基础上倍频,达到168MHz。实测也是如此


顺便提一句,APB2的频率是42MHz,与其关联的TIM2,TIM3等等定时器也是在此基础上倍频,达到84MHz.

TIM1和TIM8都是16位高级定时器,可以产生pwm,功能和性能比其他定时器多一些。所以就用TIM1来进行测试。


pwm频率的计算公式 Fpwm = Fck / (ARR + 1)(CCR + 1 )
三、实测
用cubeMX配置了一个程序,但是这个程序是不能正常输出PWM波形的。
因为没有启动定时器和PWM。
在程序最后加上两条语句就可以了。

static 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 = 0;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  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_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 3-1;
  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();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  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 */

  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);
  HAL_TIM_Base_Start(&htim1);
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}
1.显测试较小频率下的占空比。
初始化TIM1的时钟为168M,周期为10us,定义脉宽为10ns
htim1.Init.Prescaler = 0;//定义频率为168MHz,即Fck
htim1.Init.Period = 1680-1;//定义周期10us,即ARR
sConfigOC.Pulse = 3-1;/定义脉宽计算值为10ns,实际测量得到8ns,即CCR
实测周期10us,脉宽8ns如下图


其余参数不变,sConfigOC.Pulse = 5-1;//脉宽20ns如下图


sConfigOC.Pulse = 6-1;//实际测量得到28ns

sConfigOC.Pulse = 7-1;//脉宽30ns,实际32ns


从以上测量可以看到,在小占空比时,误差较大,能达到20%,当然这中极端占空比较少使用。

2.测试高频pwm下,占空比的变化
测试方法如上,先计算得到PWM频率和占空比,后进行测试量取其时间。测试结果如下
2.1
htim1.Init.Prescaler = 0;//168MHz
htim1.Init.Period = 2;//周期计算得到11.90ns,实测为18ns
sConfigOC.Pulse = 1;//实测为5ns

2.2,周期24ns不变实测占空比

htim1.Init.Prescaler = 0;//168MHz
htim1.Init.Period = 3;//周期计算得到17.857ns,实测24ns
sConfigOC.Pulse = 1;//脉宽计算得到6ns,实测7.5ns

sConfigOC.Pulse = 2;//脉宽计算得到12ns,实测7ns

sConfigOC.Pulse = 3;//脉宽计算得到17.8ns,实测7.5ns

2.3周期66ns不变实测占空比

htim1.Init.Prescaler = 0;//168MHz
htim1.Init.Period = 10;//周期3=59.5ns,实测66ns
sConfigOC.Pulse = 1;//脉宽ns,实测5ns
sConfigOC.Pulse = 2;//脉宽ns,实测8ns
sConfigOC.Pulse = 3;//脉宽ns,实测16ns
sConfigOC.Pulse = 4;//脉宽ns,实测21ns
sConfigOC.Pulse = 5;//脉宽ns,实测28ns
sConfigOC.Pulse = 6;//脉宽ns,实测34ns
sConfigOC.Pulse = 7;//脉宽ns,实测40ns
sConfigOC.Pulse = 8;//脉宽ns,实测45ns
sConfigOC.Pulse = 9;//脉宽ns,实测52ns
sConfigOC.Pulse = 10;//脉宽ns,实测57ns

在高频下,占空比与周期均有较大误差。频率误差达到10%,占空比误差可达50%,且并不是线性变化。

3.低频下pwm测试
3.1    50kHz
htim1.Init.Prescaler = 1;//84MHz
htim1.Init.Period = 1680-1;//周期计算得到20us,实测20us
sConfigOC.Pulse = 168-1;//脉宽计算得到2us,实测2us
sConfigOC.Pulse = 17;//脉宽计算得到202ns,实测200ns
sConfigOC.Pulse = 2;//脉宽计算得到23.8ns,实测20ns

3.2     10kHz
htim1.Init.Prescaler = 1;//84MHz
htim1.Init.Period = 8400-1;//周期计算得到100us,实测100us
sConfigOC.Pulse = 84-1;//脉宽计算得到1us,实测1us
sConfigOC.Pulse = 8;//脉宽计算得到95.2ns,实测98ns
在低频下,占空比与周期误差较小。



四、小结
经测试,在STM32F407中用TIM1实现PWM输出,
在高频时周期与占空比都存在较大误差,数据如上所示。
在低频时周期与占空比误差较小,数据如上所示。
在50kHz下,能够满足周期调整步进1%,占空比调整步进0.1%的要求。
以上数据,在配置参数或计算结果时都存在四舍五入。
以上测试可能存在错误,欢迎指正。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1372

主题

13481

帖子

27

粉丝