STM32F303ZE:PWM只有一半的频率

STM32F303ZE:PWM只有一半的频率,stm32,frequency,clock,pwm,Stm32,Frequency,Clock,Pwm,我目前正在为一个项目进行STM32编程。对于这个项目,我需要产生一个20kHz(=f_pwm)的中心对齐pwm。使用CubeMX,我使用PLLCLK*2将TIM1时钟设置为144 MHz(=f_tim)。然后我将ARR寄存器设置为period=f_tim/(2*f_pwm)。*2来自中心对齐模式,因为它向上和向下计数。 在用这些参数编程STM32之后,我只得到10 kHz(在示波器上测量)。我的计算和时钟设置似乎是正确的(通过生成的代码和写入的寄存器进行检查),所以我现在没有主意了。有没有人已经

我目前正在为一个项目进行STM32编程。对于这个项目,我需要产生一个20kHz(=f_pwm)的中心对齐pwm。使用CubeMX,我使用PLLCLK*2将TIM1时钟设置为144 MHz(=f_tim)。然后我将ARR寄存器设置为period=f_tim/(2*f_pwm)。*2来自中心对齐模式,因为它向上和向下计数。 在用这些参数编程STM32之后,我只得到10 kHz(在示波器上测量)。我的计算和时钟设置似乎是正确的(通过生成的代码和写入的寄存器进行检查),所以我现在没有主意了。有没有人已经遇到过这样的问题,或者知道原因是什么?找到我的CubeMX时钟配置和相应的代码部分

多亏了大家的关注

系统时钟配置:

    void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART3|RCC_PERIPHCLK_TIM1
                              |RCC_PERIPHCLK_ADC12|RCC_PERIPHCLK_ADC34
                              |RCC_PERIPHCLK_TIM20;
  PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
  PeriphClkInit.Adc12ClockSelection = RCC_ADC12PLLCLK_DIV64;
  PeriphClkInit.Adc34ClockSelection = RCC_ADC34PLLCLK_DIV64;
  PeriphClkInit.Tim1ClockSelection = RCC_TIM1CLK_PLLCLK;
  PeriphClkInit.Tim20ClockSelection = RCC_TIM20CLK_PLLCLK;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
TIM1初始化:

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

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 1;
  htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3;
  htim1.Init.Period = 3600;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  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_3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  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.BreakFilter = 0;
  sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
  sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
  sBreakDeadTimeConfig.Break2Filter = 0;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  HAL_TIM_MspPostInit(&htim1);

}
设置CCR和启动PWM:

//Sets TIM_CCR (Compares to counter value), From _hal_tim_ex.h:921
  __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_3,1800);
  //Start PWM
  HAL_TIM_PWM_Start_IT(&htim1,TIM_CHANNEL_3);

我自己解决了:我把预分频器(寄存器TIMx_PSC)设置为1(逻辑思维,f_tim/1=f_tim,对吗?)。将其设置为0后,我得到了所需的f_pwm。然后我翻开STM的数据表,发现f_tim的计算公式如下:f_tim=f_clk/(PSC+1)。因此:将预刻度设置为0会给出1的预刻度,设置为1会给出2,等等。

我自己解决了这个问题:我将预刻度设置为1(好吧,f_tim/1=f_tim,对吗?)。将其设置为0后,我得到了所需的f_pwm。由此,我将假设0的预分频给出实际的PLLCLK*2,而>0的预分频器给出从PLLCLK(也是SYSCLK)派生的计时器时钟。无论如何,感谢所有可能在这个问题上投入时间的人!另一个注释:检查数据表中相应的寄存器PSC,发现这一个:fCK_PSC/(PSC[15:0]+1)。有趣的是,实际的预设值是设定值+1。您可能希望制定一个答案并接受它,以帮助其他人更容易地找到问题的解决方案:)