Skip to main content
AFink
Associate III
February 1, 2024
Question

PWM frequency is not as expected

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

Andrew Neil
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

 

 

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
AFink
AFinkAuthor
Associate III
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