cancel
Showing results for 
Search instead for 
Did you mean: 

PWM frequency is not as expected

AFink
Associate III

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);
}
 
2 REPLIES 2

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

 

 

 

AFink
Associate III

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