Skip to main content
Lyu.1
Senior
May 25, 2020
Solved

PWM output synchronization problem

  • May 25, 2020
  • 12 replies
  • 2961 views

Hi,Master:

​

​Platform: STM32F301K8U

CPU clock frequency:72M

​

As shown in the figure, the original analog video signal (PA7 pin) is compared with DAC1_CH1 through a comparator, and a pulse sequence with a slightly changed duty cycle and period is output. ).

my question:

How to control PA8 (or PA9 / PA10) to output a pulse sequence that is inverse to this pulse sequence, but the phase shift should not exceed 0.25us? I now capture the input of PA3 and control the PWM output of PA8 in its interrupt, resulting in the output waveform always being slower than PA2 (much greater than 0.25us).

Thank you very much.

​

This topic has been closed for replies.
Best answer by berendi

> I now capture the input of PA3

Is it externally connected to PA2? Fine, then you can use timer 2 input capture 3 and 4 DMA requests to control any GPIO pin you like, provided the necessary resources, TIM2 channels 3 and 4 and DMA1 channels 1 and 7 are free.

  • Map PA3 to TIM2_CH4, PA8 as GPIO output.
  • Define two memory constants. When copied to GPIOA->BSRR, they would set the output pin high or low
volatile uint32_t pa8_low = (1 << 24);
volatile uint32_t pa8_high = (1 << 8);
  • Set up DMA1 channel 1 to copy one word in circular mode from &pa8_low to &GPIOA->BSRR
DMA1_Channel1->CMAR = (uint32_t)&pa8_low;
DMA1_Channel1->CPAR = (uint32_t)&GPIOA->BSRR;
DMA1_Channel1->CNDTR = 1;
DMA1_Channel1->CCR =
 DMA_CCR_MSIZE_1 | // memory size 32 bits
 DMA_CCR_PSIZE_1 | // peripheral size 32 bits
 DMA_CCR_CIRC | // circular mode
 DMA_CCR_DIR | // memory to peripheral
 DMA_CCR_EN; // enable channel
  • Set DMA channel 7 the same way, but with &pa8_high instead
  • Configure TIM2 input capture channels 3 and 4 to capture on opposite edges of TI4
TIM2->CCMR2 =
 TIM_CCMR2_CC3S_1 | // 10: CC3 channel is configured as input, IC3 is mapped on TI4
 TIM_CCMR2_CC4S_0; // 01: CC4 channel is configured as input, IC4 is mapped on TI4
TIM2->CCER =
 TIM_CCER_CC3E | // enable capture on channel 3
 TIM_CCER_CC4E | // enable capture on channel 4
 TIM_CCER_CC4P; // invert capture edge on channel 4
  • Enable DMA requests on TIM2 channels 3 and 4
TIM2->DIER = TIM_DIER_CC3DE|TIM_DIER_CC4DE;
  • Enable the timer
TIM2->CR1 = TIM_CR1_CEN;

12 replies

berendi
berendiBest answer
Principal
May 25, 2020

> I now capture the input of PA3

Is it externally connected to PA2? Fine, then you can use timer 2 input capture 3 and 4 DMA requests to control any GPIO pin you like, provided the necessary resources, TIM2 channels 3 and 4 and DMA1 channels 1 and 7 are free.

  • Map PA3 to TIM2_CH4, PA8 as GPIO output.
  • Define two memory constants. When copied to GPIOA->BSRR, they would set the output pin high or low
volatile uint32_t pa8_low = (1 << 24);
volatile uint32_t pa8_high = (1 << 8);
  • Set up DMA1 channel 1 to copy one word in circular mode from &pa8_low to &GPIOA->BSRR
DMA1_Channel1->CMAR = (uint32_t)&pa8_low;
DMA1_Channel1->CPAR = (uint32_t)&GPIOA->BSRR;
DMA1_Channel1->CNDTR = 1;
DMA1_Channel1->CCR =
 DMA_CCR_MSIZE_1 | // memory size 32 bits
 DMA_CCR_PSIZE_1 | // peripheral size 32 bits
 DMA_CCR_CIRC | // circular mode
 DMA_CCR_DIR | // memory to peripheral
 DMA_CCR_EN; // enable channel
  • Set DMA channel 7 the same way, but with &pa8_high instead
  • Configure TIM2 input capture channels 3 and 4 to capture on opposite edges of TI4
TIM2->CCMR2 =
 TIM_CCMR2_CC3S_1 | // 10: CC3 channel is configured as input, IC3 is mapped on TI4
 TIM_CCMR2_CC4S_0; // 01: CC4 channel is configured as input, IC4 is mapped on TI4
TIM2->CCER =
 TIM_CCER_CC3E | // enable capture on channel 3
 TIM_CCER_CC4E | // enable capture on channel 4
 TIM_CCER_CC4P; // invert capture edge on channel 4
  • Enable DMA requests on TIM2 channels 3 and 4
TIM2->DIER = TIM_DIER_CC3DE|TIM_DIER_CC4DE;
  • Enable the timer
TIM2->CR1 = TIM_CR1_CEN;

Lyu.1
Lyu.1Author
Senior
May 26, 2020

This method looks very good, thank you for your idea, I will try.

waclawek.jan
Super User
May 25, 2020

Can't you simply use an invertor as an external chip?

Otherwise, you'd need to us COMP->TIM1_IC1, set TIM1 to slave Reset mode using TI1FP1 as TRGI and then generate any required sequence on TIM1_CH2 which is PA9 .

Of course that would reset the output generation upon any input edge, no sophisticated discrimination is possible at that stage. There would be some delay involved, too, probably 2-3 TIM1 input clock cycles.

JW

Lyu.1
Lyu.1Author
Senior
May 26, 2020

This method should also look great. I need to get familiar with the slave mode control of the timer. Berendi also provides a good idea. I will try your ideas. Thank you for your help. Thank you for your efforts!