cancel
Showing results for 
Search instead for 
Did you mean: 

PWM output synchronization problem

Lyu.1
Associate II

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.

1 ACCEPTED SOLUTION

Accepted Solutions
berendi
Principal

> 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;

View solution in original post

12 REPLIES 12
berendi
Principal

> 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;

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

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

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!

Hi,​ berendi 

Now I still have problems:

Since PA2 did a comparison output and could not be mapped to time2 ch3, then now only the red line can be captured for DMA control PA8 output. But TI4FP3 and TI4FP4 are all homologous, and there is no way to do a rising edge capture and a falling edge capture.

Thank you very much.

0693W000001pl3hQAA.jpg

Hi,waclawek

The slave mode reset can only trigger the counter reset. Now let the PA9 output follow PA2 / PA3 (duty cycle and period are slightly changed dynamically), how to define the TIM1_CH2 output comparison value?

Thank you very much.

Yes there is. That's why TIM_CCER_CC4P is set, to invert the capture edge, i.e. capture on falling edge on CH4 only.

As I've said, there' s no sophisticated control possible.

JW