cancel
Showing results for 
Search instead for 
Did you mean: 

PWM gating by other timer on STM32L412

Linas L
Senior II

Hello,

In my project I need to generate 1s on, 1s off PWM signal in hardware.

First I checked if my PWM works with simple project, and it does.

But following AN4776 for N-pulse waveform generation application example - part 1.

LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
 
  LL_TIM_DeInit(TIM1);
  LL_TIM_DeInit(TIM2);
 
  uint32_t Tim2Prescaler= (uint16_t) (80000000 / 1000000) - 1;
  uint32_t Period2 = 1000000 / 20000; 
 
  TIM2->PSC = Tim2Prescaler;
  TIM2->ARR = Period2-1;
  TIM2->RCR = ((uint32_t) 32768) -1; 
  TIM2->CCR1 = Period2 / 2;
  TIM2->CR1 &= ~ TIM_CR1_CKD;
  TIM2->CR1 |= LL_TIM_CLOCKDIVISION_DIV1;
  TIM2->CR1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
  TIM2->CR1 |= LL_TIM_COUNTERMODE_UP;
  TIM2->CCMR1 &= ~TIM_CCMR1_OC1M;
  TIM2->CCMR1 &= ~TIM_CCMR1_CC1S;
  TIM2->CCMR1 |= LL_TIM_OCMODE_PWM1;
  TIM2->CR1 |= TIM_CR1_OPM;
  TIM2->SMCR &= ~TIM_SMCR_TS;
  TIM2->SMCR |= LL_TIM_TS_ITR1;
  TIM2->SMCR &= ~TIM_SMCR_SMS;
  TIM2->SMCR |= LL_TIM_SLAVEMODE_TRIGGER;
  TIM2->CCMR1 |= TIM_CCMR1_OC1PE;
  TIM2->EGR |= TIM_EGR_UG;
  TIM2->BDTR |= TIM_BDTR_MOE;
  TIM2->CCER &= ~TIM_CCER_CC1P;
  TIM2->CCER |= LL_TIM_OCPOLARITY_LOW;
  TIM2->CCER |= TIM_CCER_CC1E;
  TIM2->CR1 |= TIM_CR1_CEN;
  
  uint32_t Tim1Prescaler= (uint16_t) ((80000000 ) / 1000000) - 1;
  uint32_t Period = 1000000/50; /* configure the period */  
  TIM1->ARR = Period-1;
  TIM1->PSC = Tim1Prescaler;
  TIM1->CR1 &= ~ TIM_CR1_CKD;
  TIM1->CR1 |= LL_TIM_CLOCKDIVISION_DIV1;
  TIM1->CR1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
  TIM1->CR1 |= LL_TIM_COUNTERMODE_UP;
  
  TIM2->CR2 &= ~ TIM_CR2_MMS;  
  TIM1->CR2 |= LL_TIM_TRGO_UPDATE;
 
  TIM1->CR1 |= TIM_CR1_CEN;

So my Master Timer is timer 1 to generate events to generate n-th signals from TIM2. But the problem is, i just get nothing. PA15 is also enabled with based on working example with just TIM2 pwm generation:

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
  LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
  //PA15 (JTDI)   ------> TIM2_CH1
  GPIO_InitStruct.Pin = LL_GPIO_PIN_15;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

Any one could spot the problem ?

1 ACCEPTED SOLUTION

Accepted Solutions

> TIM2->SMCR |= LL_TIM_TS_ITR1;

This probably is the cause of the problem.

0693W000008zrlxQAA.pngOther issues:

> TIM2->RCR = ((uint32_t) 32768) -1;

There's no RCR in TIM2.

> TIM2->BDTR |= TIM_BDTR_MOE;

There's no BDTR in TIM2.

> TIM2->CR2 &= ~ TIM_CR2_MMS;

You probably meant to do this for the TIM1_CR2.

If in doubts, read out the TIM and GPIO registers and check their content.

JW

View solution in original post

3 REPLIES 3

> TIM2->SMCR |= LL_TIM_TS_ITR1;

This probably is the cause of the problem.

0693W000008zrlxQAA.pngOther issues:

> TIM2->RCR = ((uint32_t) 32768) -1;

There's no RCR in TIM2.

> TIM2->BDTR |= TIM_BDTR_MOE;

There's no BDTR in TIM2.

> TIM2->CR2 &= ~ TIM_CR2_MMS;

You probably meant to do this for the TIM1_CR2.

If in doubts, read out the TIM and GPIO registers and check their content.

JW

Hello waclawek.jan, and thank you for these points, I was reading reference manual, but did not get to this part yet.

in that case I just have to use second timer to generate update events, and use IRQ event to enable/disable or load 0 or period/2 into CCR1 register by software. And because it is just 1Hz or something similar, it would not cause any large impact on CPU performance.

> in that case I just have to use second timer to generate update events, and use IRQ event to enable/disable or load 0 or period/2 into CCR1 register by software.

I didn't say that.

Just change TIM2_SMCR.TS to ITR0.

JW