cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L052 - Output PWM and Input Capture with the same Counter simultaneously

Marc1
Associate III

STM32L052
TIM21, Channel 1: Output PWM
TIM21, Channel 2: Switching between Output PWM and Input Compare
System Clock: 32 MHz

Hello,

I want to use TIM21 of STM32L052 for PWM output on channel 1 and input capture on channel 2 simultaneously.

 

uint16_t TIM_CCMR1_backup;
uint16_t TIM_CCER_backup;

// PWM on channel 1 and channel 2
void PWM_init(void)
{
  RCC->APB2ENR |= RCC_APB2ENR_TIM21EN;

  TIM21->CR1 &= ~TIM_CR1_CEN;
  TIM21->ARR = 0xFFF;
  TIM21->CR1 = TIM_CR1_ARPE;

  // TIM21, channel 1
  TIM21->CCMR1 |= (0b111 << TIM_CCMR1_OC1M_Pos);	// PWM mode 2
  TIM21->CCMR1 |= TIM_CCMR1_OC1PE;	// output compare preload enable
  TIM21->CCR1 = 0;			// reset output compare register
  TIM21->CCER |= TIM_CCER_CC1E;		// enable output

  // TIM21, channel 2
  TIM21->CCMR1 |= (0b111 << TIM_CCMR1_OC2M_Pos);	// PWM mode 2
  TIM21->CCMR1 |= TIM_CCMR1_OC2PE;		// output compare preload enable
  TIM21->CCR2 = 0;				// reset output compare register
  TIM21->CCER |= TIM_CCER_CC2E;			// enable output

  TIM21->CNT = 0;				// reset counter

  TIM21->EGR |= TIM_EGR_UG;
  TIM21->CR1 |= TIM_CR1_CEN;			// enable counter
}

void switch_channel2_to_input_compare(void)
{
  TIM_CCMR1_backup = TIM21->CCMR1;
  TIM_CCER_backup = TIM21->CCER;

  TIM21->CCER &= ~TIM_CCER_CC2E;		// disable output

  MODIFY_REG(TIM21->CCMR1, TIM_CCMR1_CC2S_Msk, 0b10 << TIM_CCMR1_CC2S_Pos);	// CC2 channel is configured as input, IC1 is mapped on TI1
  TIM21->OR = (0b101 << TIM21_OR_TI1_RMP_Pos);	// TI1 input connected to LSI clock
  TIM21->CCER = TIM_CCER_CC2E;			// capture on rising edge, enable CCR2
  TIM21->SR &= ~TIM_SR_CC2IF;			// clear interrupt flag
  TIM21->SR &= ~TIM_SR_CC2OF;			// clear interrupt flag
  TIM21->DIER = TIM_DIER_CC2IE;			// enable capture interrupt

  NVIC_EnableIRQ(TIM21_IRQn);			// enable interrupt

  TIM21->CR1 |= TIM_CR1_CEN;			// enable counter
}

void switch_channel2_back_to_output_PWM(void)
{
  TIM21->CCER &= ~TIM_CCER_CC2E;
  TIM21->CR1 &= ~TIM_CR1_CEN;
  TIM21->CCMR1 = TIM_CCMR1_backup;
  TIM21->CCER = TIM_CCER_backup;
  TIM21->CCR2 = 0;
  TIM21->CR1 |= TIM_CR1_CEN;
}

 

(1) PWM_init(): The application starts with both channels in output PWM mode.

(2) ... then switches channel 2 repeatedly to input compare mode, while channel 1 stays in output PWM mode (switch_channel2_to_input_compare()), does its measurments and ...

(3) ... then switches channel 2 back to output PWM mode (switch_channel2_back_to_output_PWM()).

The problem:
While channel 2 is in capture compare mode, channel 1 stops working (no more PWM).
Once channel 2 switches back to PWM mode, channel 1 PWM continues working.

Is it not possible to have channel 1 running in PWM mode while channel 2 being input capture mode?

15 REPLIES 15

> - different GPIO settings for the related pins
I also checked the GPIO and RCC-Enable registers. They are ok.

> - different TIM21 kernel clock setting (if TIM21 in 'L0 is capable of being clocked from a non-APB clock)
How? I couldn't find anything about clock selection of TIM21 in the reference manual.

PWM outputs are connected to LEDs. So I can see if there is any signal or not.

> (2) NVIC_SystemReset() -> ... --> PWM outputs of TIM21 are still working
> (3) NVIC_SystemReset() -> ... --> PWM outputs of TIM21 are not working anymore

NVIC_SystemReset() is not at fault here. The difference in behavior is due to the "..." between the events. We don't have much insight into that.

If you feel a post has answered your question, please click "Accept as Solution".
Marc1
Associate III

Knowing the difference between NVIC_SystemReset() and a hardware reset could help me finding the fault.

> NVIC_SystemReset() is not at fault here. The difference in behavior is due to the "..." between the events. We don't have much insight into that.

The code doesn't change between two NVIC_SystemReset(). So the behavior of the controller should be the same ... provided NVIC_SystemReset() resets everything. But there is a difference, obviously.

waclawek.jan
Super User

There is very little difference between System Reset and Power-On Reset (and NRST-pin reset). I don't t

I agree with TDK that the difference is most likely in the code run at the different occassions.

 

> > - different TIM21 kernel clock setting (if TIM21 in 'L0 is capable of being clocked from a non-APB clock)
> How? I couldn't find anything about clock selection of TIM21 in the reference manual.

I said, "if". It's quite likely it's not.

 

> PWM outputs are connected to LEDs. So I can see if there is any signal or not.

Are you sure? Would you see it even if the frequency is very low or very high? How are those LEDs exactly connected?

Post content of TIM21 and relevant GPIO registers in the "non-working" case.

JW

>> PWM outputs are connected to LEDs. So I can see if there is any signal or not.

> Are you sure? Would you see it even if the frequency is very low or very high? How are those LEDs exactly connected?
LEDs are directly connected to the Pins

Marc1
Associate III

I got it! And you were right. The problem was within the code.

And the difference between NVIC_SystemReset() and a hardware reset seem to be the timing. Maybe different clock settings? In one case the TIM21 destroying code got executed before TIM21 initialization and in the other case after TIM21 initialization.

Thank you for your help!