Skip to main content
Explorer II
February 1, 2024
Question

PWM frequency is not as expected

  • February 1, 2024
  • 2 replies
  • 978 views

Hi,

I'd like help to understand what is thew PWM frequency.

As far as I understand:

1. The main system clock is 64MHZ -- see below SystemClock_Config()

2. PWM frequency is 64KHz (= 64MHZ / (1000 - 1))

BUT, measuring the frequency shows 4KHz (rather than 64KHz).

Can some please explain it?

 

Thanks,

Aviv

 

 
 

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

/** Configure LSE Drive Capability

*/

HAL_PWR_EnableBkUpAccess();

__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);

/** Configure the main internal regulator output voltage

*/

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

/** Initializes the CPU, AHB and APB busses clocks

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI1

|RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE

|RCC_OSCILLATORTYPE_MSI;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.LSEState = RCC_LSE_ON;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.MSIState = RCC_MSI_ON;

RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;

RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;

RCC_OscInitStruct.LSIState = RCC_LSI_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;

RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;

RCC_OscInitStruct.PLL.PLLN = 32; // PLL factor to achieve main system clock frequency = 64MHz

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; // PLL division for the main system clock to achieve main system clock frequency = 64MHz

RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

/** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4|RCC_CLOCKTYPE_HCLK2

|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_DIV1;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV2;

RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1;

 

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)

{

Error_Handler();

}

/** Initializes the peripherals clocks

*/

PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS|RCC_PERIPHCLK_RFWAKEUP

|RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART1

|RCC_PERIPHCLK_LPUART1|RCC_PERIPHCLK_USB;

PeriphClkInitStruct.PLLSAI1.PLLN = 24;

PeriphClkInitStruct.PLLSAI1.PLLP = RCC_PLLP_DIV2;

PeriphClkInitStruct.PLLSAI1.PLLQ = RCC_PLLQ_DIV2;

PeriphClkInitStruct.PLLSAI1.PLLR = RCC_PLLR_DIV2;

PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_USBCLK;

PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;

PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_HSI;

PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;

PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;

PeriphClkInitStruct.RFWakeUpClockSelection = RCC_RFWKPCLKSOURCE_LSE;

PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSE;

PeriphClkInitStruct.SmpsDivSelection = RCC_SMPSCLKDIV_RANGE1;

if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN Smps */

 

/* USER CODE END Smps */

// HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_LSE, RCC_MCODIV_1);

/** Enable MSI Auto calibration

*/

// HAL_RCCEx_EnableMSIPLLMode();

}

 

static void MX_TIM1_Init(void)
{
  /* USER CODE BEGIN TIM1_Init 0 */
 
  /* USER CODE END TIM1_Init 0 */
 
  TIM_MasterConfigTypeDef sMasterConfig = {0};
 
  /* USER CODE BEGIN TIM1_Init 1 */
 
  /* USER CODE END TIM1_Init 1 */
 
  htim1.Instance = TIM1; // PWM based on TIM1/CH3N RED_LED_R
  htim1.Init.Prescaler = 0 ; // set timer frequency = 64MHz
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = (1000 - 1);
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  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();
  }
 
  // initialize PWM for Red LED -- start
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
 
  sConfigOC.OCMode = TIM_OCMODE_PWM1; // set Timer mode to be PWM
  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;
 
  sConfigOC.Pulse = 1;
 
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)   // RED_LED_R TIM1/CH3
  {
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.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();
  }
  // initialize PWM for Red LED -- end
 
  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);
}
 
    This topic has been closed for replies.

    2 replies

    Super User
    February 1, 2024

    What chip are you using?

    Is it on a devboard, or some custom board?

     


    @AFink wrote:

    As far as I understand:

    1. The main system clock is 64MHZ


    Have you verified that?

     

     


    @AFink wrote:

    BUT, measuring the frequency shows 4KHz (rather than 64KHz).


    How do you make that measurement?

     

    Use this button to properly post source code:

    AndrewNeil_0-1706810260343.png

     

    To get that extra row of icons, press this button:

    AndrewNeil_1-1706810260341.png

     

     

     

    AFinkAuthor
    Explorer II
    February 4, 2024

    Hi Andrew,

    It's a custom board (quiet simple one...). 

    All numbers were verified by a Scope.

     

    void SystemClock_Config(void)
    
    {
    
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    
    RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
    
    /** Configure LSE Drive Capability
    
    */
    
    HAL_PWR_EnableBkUpAccess();
    
    __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
    
    /** Configure the main internal regulator output voltage
    
    */
    
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    
    /** Initializes the CPU, AHB and APB busses clocks
    
    */
    
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI1
    
    |RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE
    
    |RCC_OSCILLATORTYPE_MSI;
    
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    
    RCC_OscInitStruct.LSEState = RCC_LSE_ON;
    
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    
    RCC_OscInitStruct.MSIState = RCC_MSI_ON;
    
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    
    RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
    
    RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
    
    RCC_OscInitStruct.LSIState = RCC_LSI_ON;
    
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
    
    RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
    
    RCC_OscInitStruct.PLL.PLLN = 32; // PLL factor to achieve main system clock frequency = 64MHz
    
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    
    RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; // PLL division for the main system clock to achieve main system clock frequency = 64MHz
    
    RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
    
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    
    {
    
    Error_Handler();
    
    }
    
    /** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers
    
    */
    
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4|RCC_CLOCKTYPE_HCLK2
    
    |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_DIV1;
    
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
    RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV2;
    
    RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1;
    
     
    
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
    
    {
    
    Error_Handler();
    
    }
    
    /** Initializes the peripherals clocks
    
    */
    
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS|RCC_PERIPHCLK_RFWAKEUP
    
    |RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART1
    
    |RCC_PERIPHCLK_LPUART1|RCC_PERIPHCLK_USB;
    
    PeriphClkInitStruct.PLLSAI1.PLLN = 24;
    
    PeriphClkInitStruct.PLLSAI1.PLLP = RCC_PLLP_DIV2;
    
    PeriphClkInitStruct.PLLSAI1.PLLQ = RCC_PLLQ_DIV2;
    
    PeriphClkInitStruct.PLLSAI1.PLLR = RCC_PLLR_DIV2;
    
    PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_USBCLK;
    
    PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
    
    PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_HSI;
    
    PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
    
    PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
    
    PeriphClkInitStruct.RFWakeUpClockSelection = RCC_RFWKPCLKSOURCE_LSE;
    
    PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSE;
    
    PeriphClkInitStruct.SmpsDivSelection = RCC_SMPSCLKDIV_RANGE1;
    
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    
    {
    
    Error_Handler();
    
    }
    
    /* USER CODE BEGIN Smps */
    
     
    
    /* USER CODE END Smps */
    
    // HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_LSE, RCC_MCODIV_1);
    
    /** Enable MSI Auto calibration
    
    */
    
    // HAL_RCCEx_EnableMSIPLLMode();
    
    }
    
     
    
    static void MX_TIM1_Init(void)
    {
     /* USER CODE BEGIN TIM1_Init 0 */
     
     /* USER CODE END TIM1_Init 0 */
     
     TIM_MasterConfigTypeDef sMasterConfig = {0};
     
     /* USER CODE BEGIN TIM1_Init 1 */
     
     /* USER CODE END TIM1_Init 1 */
     
     htim1.Instance = TIM1; // PWM based on TIM1/CH3N RED_LED_R
     htim1.Init.Prescaler = 0 ; // set timer frequency = 64MHz
     htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
     htim1.Init.Period = (1000 - 1);
     htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
     htim1.Init.RepetitionCounter = 0;
     htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
     if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
     {
     Error_Handler();
     }
     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();
     }
     
     // initialize PWM for Red LED -- start
     TIM_OC_InitTypeDef sConfigOC = {0};
     TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
     
     sConfigOC.OCMode = TIM_OCMODE_PWM1; // set Timer mode to be PWM
     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;
     
     sConfigOC.Pulse = 1;
     
     if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) // RED_LED_R TIM1/CH3
     {
    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.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();
     }
     // initialize PWM for Red LED -- end
     
     /* USER CODE END TIM1_Init 2 */
     HAL_TIM_MspPostInit(&htim1);
    }
     

     

    Thanks,

    Aviv