cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L011 TIM2 PWM no output

STM32L09
Associate II

Select PA1 as TIM2 CH2, those code are copy from ST official example(TIM21), and changed to TIM2.

STM32L09_0-1746884305122.png

no output from PA1, code as below:

void ConfigureTIM2AsPWM_EdgeAligned(void)
{
/* (1) Enable the peripheral clock of Timer x */
/* (2) Enable the peripheral clock of GPIOA */
/* (3) Select alternate function mode on GPIOA pin 1 */
/* (4) Select AF2 on PA1 in AFRH for TIM2_CH2 */

RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; /* (1) */
RCC->IOPENR |= RCC_IOPENR_GPIOAEN; /* (2) */
GPIOA->MODER |= 0X00000008; /* (3) */
GPIOA->AFR[0] |= 0X00000020; /* (4) */

/* (1) Set prescaler to 15, so APBCLK/16 i.e 1MHz */
/* (2) Set ARR = 8, as timer clock is 1MHz the period is 9 us */
/* (3) Set CCRx = 4, , the signal will be high during 4 us */
/* (4) Select PWM mode 1 on OC2 (OC2M = 110),
enable preload register on OC2 (OC2PE = 1) */
/* (5) Select active high polarity on OC2 (CC2P = 0, reset value),
enable the output on OC2 (CC2E = 1)*/
/* (6) Enable output (MOE = 1)*/
/* (7) Enable counter (CEN = 1)
select edge aligned mode (CMS = 00, reset value)
select direction as upcounter (DIR = 0, reset value) */
/* (8) Force update generation (UG = 1) */

TIM2->PSC = 15; /* (1) */
TIM2->ARR = 8; /* (2) */
TIM2->CCR1 = 4; /* (3) */
TIM2->CCMR1 |= TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE; /* (4) */
TIM2->CCER |= TIM_CCER_CC2E; /* (5) */
TIM2->CR1 |= TIM_CR1_CEN; /* (7) */
TIM2->EGR |= TIM_EGR_UG; /* (8) */
}

1 ACCEPTED SOLUTION

Accepted Solutions
waclawek.jan
Super User

@STM32L09,

> TIM2->CCR1 = 4; /* (3) */

does not set TIM2_CH2 but TIM2_CH1. You would spot it yourself, would you print out and check the TIM2 registers content.

JW

View solution in original post

9 REPLIES 9
KnarfB
Super User

The |= is wrong for MODER (and in general for AFR too). You need to set some bit(s) and clear other(s).

A general pattern is 

GPIOA->MODER = (GPIOA->MODER & ~GPIO_MODER_MODE1_Msk) | (2 << GPIO_MODER_MODE1_Pos); // alternate mode

or some macros wrapping that.

hth

KnarfB

 

STM32L09
Associate II

thanks, KnarfB, I realize default value for MODE is 0XFFFF FFFF, so I should clear some bits.

but seems still have other problems, still no PWM.

waclawek.jan
Super User

Read out and check/post content of GPIO and TIM registers.

Check given pin's connection by setting it as GPIO Output and toggling it "manually".

JW

I use USART2 to print the register value, the value is HEX format.

GPIOA->MODER:EBEBFCF9
GPIOA->AFR[0]:20

PA1 configuration is correct.

waclawek.jan
Super User

Okay, and what about the TIM2 registers?

And did you test the pin's connection as I recommended, by setting it to output and toggling in software?

JW

Hl_st
ST Employee

Hello,

I have made an example code which is below. The code sets TIM2 to generate PWM on PA1. It comes from LL library so it can be reduced for your specific case, but it works right, I have tested it on my NUCLEO board.

  SET_BIT(RCC->APBENR1, RCC_APBENR1_TIM2EN);  /* TIM2 clock enable */
  SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN);   /* GPIOA clock enable */
  MODIFY_REG(GPIOA->MODER, ((GPIO_PIN_1 * GPIO_PIN_1) * GPIO_MODER_MODE0), ((GPIO_PIN_1 * GPIO_PIN_1) * GPIO_MODER_MODE0_1)); /* Set PA5 pin mode to alternate function */
  MODIFY_REG(GPIOA->AFR[0], ((((GPIO_PIN_1 * GPIO_PIN_1) * GPIO_PIN_1) * GPIO_PIN_1) * GPIO_AFRL_AFSEL0),
               ((((GPIO_PIN_1 * GPIO_PIN_1) * GPIO_PIN_1) * GPIO_PIN_1) * 0x2U)); /* Set PA5 pin alternate function to AF2 */
  TIM2->PSC = 15; /* */
  TIM2->ARR = 199999; /* */
  TIM2->CCR2 = 99999; /* */
  MODIFY_REG(TIM2->CCMR1, (TIM_CCMR1_OC2M_Msk | TIM_CCMR1_OC2PE_Msk), (TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE)); /* Enable PWM1 mode, enable pre-load */
  TIM2->CCER |= TIM_CCER_CC2E; /*  */
  TIM2->CR1 |= TIM_CR1_CEN; /* */
  TIM2->EGR |= TIM_EGR_UG;  /* */

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

waclawek.jan
Super User

Hi @Hl_st ,

Can you please explain

(GPIO_PIN_1 * GPIO_PIN_1)

 in setting GPIOA->MODER?

Thanks,

JW

[EDIT] OK never mind, I see it now - if GPIO_PIN_N == 1 << N, this expression results in 1 << (2*N). Quite unusual nonetheless.

 

waclawek.jan
Super User

@STM32L09,

> TIM2->CCR1 = 4; /* (3) */

does not set TIM2_CH2 but TIM2_CH1. You would spot it yourself, would you print out and check the TIM2 registers content.

JW

Many thanks, it works now.