cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 PWM Output Incorrect Frequency (PE9, TIM1) despite Correct Configuration

sktech
Associate II

Problem:

I'm working with an STM32H743 and trying to generate a PWM signal (Center Aligned) on PE9 using Timer1 (TIM1). Although the PWM output is functioning, the frequency is not what I expect. I’m trying to generate a 1 kHz signal, but instead, I’m getting around 833 Hz, and I’ve confirmed that the period is incorrect.This is for driving a stepper motor.

What I have done so far:

  • Clock Configuration: The system clocks (HCLK, PCLK2, SYSCLK) are verified and appear to be configured correctly.
  • Timer Configuration: I'm using Timer1 in PWM Mode 1 with a prescaler of 199 and ARR of 999 to generate a 1 kHz PWM signal (expected 1 MHz timer clock). However, I’m getting an incorrect frequency (around 833 Hz).
  • GPIO Configuration: I’ve configured PE9 for TIM1 CH1 (PWM output).

     - My Code

#include <Arduino.h> HardwareSerial SerialDebug(PA3, PA2); const uint8_t PIN_STEP = PE9; const uint8_t PIN_DIR = PE10; const uint8_t PIN_ENA = PE7; void setupTimer1() { // Enable clocks __HAL_RCC_TIM1_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); // Get actual timer clock frequency uint32_t pclk2 = HAL_RCC_GetPCLK2Freq(); uint32_t pclk1 = HAL_RCC_GetPCLK1Freq(); uint32_t timclk = HAL_RCC_GetHCLKFreq(); uint32_t sysclk = HAL_RCC_GetSysClockFreq(); SerialDebug.printf("\nClock Configuration:\n"); SerialDebug.printf("PCLK2: %lu Hz\n", pclk2); SerialDebug.printf("PCLK1: %lu Hz\n", pclk1); SerialDebug.printf("HCLK: %lu Hz\n", timclk); SerialDebug.printf("SYSCLK: %lu Hz\n", sysclk); SerialDebug.printf("SystemCoreClock: %lu Hz\n", SystemCoreClock); // Configure PE9 for Timer1 CH1 (PWM output) GPIO_InitTypeDef GPIO_Config = {0}; GPIO_Config.Pin = GPIO_PIN_9; GPIO_Config.Mode = GPIO_MODE_AF_PP; GPIO_Config.Pull = GPIO_NOPULL; GPIO_Config.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_Config.Alternate = GPIO_AF1_TIM1; HAL_GPIO_Init(GPIOE, &GPIO_Config); // Reset timer TIM1->CR1 = 0; TIM1->CR2 = 0; TIM1->SMCR = 0; TIM1->DIER = 0; TIM1->CCMR1 = 0; TIM1->CCER = 0; TIM1->BDTR = 0; // Timer configuration for HCLK = 200 MHz TIM1->PSC = 199; // Divide by 200 (200 MHz / 200 = 1 MHz) TIM1->ARR = 999; // ARR = 999 for 1 kHz (1000 cycles) TIM1->CCR1 = 500; // 50% duty cycle (ARR / 2) // Configure PWM mode 1 (OC1, PWM mode 1) TIM1->CCMR1 = (0b110 << 4) | TIM_CCMR1_OC1PE; TIM1->CCER = TIM_CCER_CC1E; // Enable capture/compare channel 1 TIM1->BDTR = TIM_BDTR_MOE; // Main output enable TIM1->CR1 = TIM_CR1_ARPE | TIM_CR1_CEN; // Enable auto-reload preload and the timer // For debug - read back the actual values SerialDebug.printf("\nTimer Configuration:\n"); SerialDebug.printf("PSC: %lu\n", TIM1->PSC); SerialDebug.printf("ARR: %lu\n", TIM1->ARR); SerialDebug.printf("CCR1: %lu\n", TIM1->CCR1); SerialDebug.printf("CR1: 0x%08lX\n", TIM1->CR1); SerialDebug.printf("CCMR1: 0x%08lX\n", TIM1->CCMR1); // Start timer TIM1->CR1 |= TIM_CR1_CEN; } void setup() { SerialDebug.begin(115200); delay(100); SerialDebug.println("\nClock Verification Test"); // Configure control pins pinMode(PIN_DIR, OUTPUT); pinMode(PIN_ENA, OUTPUT); digitalWrite(PIN_ENA, HIGH); // Disabled digitalWrite(PIN_DIR, LOW); // Forward setupTimer1(); } void loop() { if (SerialDebug.available()) { char cmd = SerialDebug.read(); if (cmd == 'e') { SerialDebug.println("Enabling motor"); digitalWrite(PIN_ENA, LOW); } else if (cmd == 'd') { SerialDebug.println("Disabling motor"); digitalWrite(PIN_ENA, HIGH); } } }
View more

 

 

  • Serial Output:

 

Clock Verification Test Clock Configuration: PCLK2: 100000000 Hz PCLK1: 100000000 Hz HCLK: 200000000 Hz SYSCLK: 400000000 Hz SystemCoreClock: 400000000 Hz Timer Configuration: PSC: 199 ARR: 999 CCR1: 500 CR1: 0x00000080 CCMR1: 0x00000068

 

  • What Happens:

    • Expected Output: A 1 kHz PWM signal with a 50% duty cycle on PE9.
    • Actual Output: The signal has an incorrect frequency of around 833 Hz (not 1 kHz as expected).

    Questions:

    1. Why am I seeing an incorrect frequency (833 Hz) instead of the expected 1 kHz?
    2. Is the timer configuration correct? I’ve ensured the prescaler and auto-reload values should generate a 1 kHz signal, but the output does not match.
    3. Could the issue be related to clock sources or the prescaler configuration? Should I double-check the timer clock frequency?

    What I’ve Tried:

    • Verified clock settings and timer registers.
    • Confirmed GPIO configuration for PE9 as an alternate function for TIM1 CH1.
    • Checked the serial output, and the values seem correct but the output does not match the expected signal frequency.

      Development Environment:

      • Platform: VS Code with PlatformIO
      • Framework: STM32 Arduino

    Any help or insight would be much appreciated. Thanks in advance!

2 REPLIES 2

Your system clock is most likely not 400MHz, but 333.200MHz, most likely as consequence of a different primary clock source frequency than you've set (e.g. you assume 12MHz primary clock but it's in fact 10MHz).

HAL_RCC_GetHCLKFreq() etc. functions don't actually *measure* the HCLK/APB etc. frequencies; rather, they rely on a system variable (SystemCoreClock) being set properly in HAL_RCC_ClockConfig() by calling HAL_RCC_GetSysClockFreq(), which in turn uses one of HSI_VALUE/CSI_VALUE/HSE_VALUE set in stm32h7xx_hal_conf.h depeding on what primary clock source you've set.

JW

Saket_Om
ST Employee

Hello @sktech 

 

Did you measure the clock frequency? If the measured value is different from the theoretical value, it could be the reason for this issue.

To measure the clock frequency, you can use an oscilloscope to monitor the output on the MCO pin.

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar