2024-11-15 05:04 PM - edited 2024-11-15 05:08 PM
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.
- 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);
}
}
}
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
Any help or insight would be much appreciated. Thanks in advance!