I have an STM32L476 Discovery Board. I'm trying to generate a PWM signal on the GPIO pin PE14 using TIM1_CH4 using bare-metal in CubeIDE.

I have created a new project in Cube and have kept the default System Clock Configuration. My aim is to have a duty cycle of 50%. I have prescaled by 79 in order to set the Timer Clock frequency at 1MHz.

I have gone through the Datasheet, Reference Manual, and Timer Cookbook several times but for some reason, I can't get it to work. Is there something that I have overlooked in my code?

void intialize_gpioe(void){
    RCC->AHB2ENR |= RCC_AHB2ENR_GPIOEEN;    // GPIOE clock enable
    GPIOE->MODER &= ~GPIO_MODER_MODER14;  // Configure PE14 as Alternative Function.
    GPIOE->AFR[1] &= ~GPIO_AFRH_AFRH6; // PE14 configured as AF1: TIM1_CH4
    GPIOE->AFR[1] |= 0x01000000;

void initalize_tim1(void){
    RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // TIM1 timer clock enable
    TIM1->PSC = 79; // Set Prescaler to 1MHz
    TIM1->ARR = 100;
    TIM1-> CCR4 = 50;
    TIM1->CCMR2 &= ~TIM_CCMR2_CC4S; // CC4 channel is configured as output
    TIM1->CCER &= ~TIM_CCER_CC4P;   // Output Polarity set to Active High
    TIM1->CCMR2 &= ~TIM_CCMR2_OC4M; // Output Compare 4 Mode set as PWM Mode 1.
    TIM1->CCMR2 |= TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2; // Output Compare 4 Mode set as PWM Mode 1.
    TIM1->CCMR2 |= TIM_CCMR2_OC4PE; // Enable the corresponding preload register
    TIM1->CCER |= TIM_CCER_CC4E; // Capture/Compare 4 Output Enable
    TIM1->EGR |= TIM_EGR_UG;    // Before starting the counter, you have to initialize all the registers
    TIM1->CR1 |= TIM_CR1_CEN; // Start Timer
  • \$\begingroup\$ Can you describe "can't get it to work"? Does it fail to work? What's the error message? Does it crash at run-time? Does it behave differently than expected? If so, what do you expect to happen and what happens instead? \$\endgroup\$
    – Codo
    Sep 24, 2020 at 6:10
  • \$\begingroup\$ what exactly do you mean by bare-metal? \$\endgroup\$
    – jsotola
    Sep 24, 2020 at 7:16
  • \$\begingroup\$ you have to enable ARR preload in the CR1 register. it's a must for pwm generation according to the reference manual I read earlier. (I'm answering based on another model) \$\endgroup\$ Sep 24, 2020 at 11:53
  • \$\begingroup\$ @Codo No errors in the code. But no signal appears on the pin. I know the pin works because I have a separate project to specifically test the pwm on this pin using HAL. \$\endgroup\$ Sep 24, 2020 at 12:43
  • \$\begingroup\$ @jsotola In my case, bare-metal would be register configuration with bitmasking without HAL functions. \$\endgroup\$ Sep 24, 2020 at 12:45

1 Answer 1


The GPIO Alternative function configuration is incorrect:


The correct configuration is:


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.