转一个stm32单一计时器多路捕获PWM信号的方案

地址:http://bbs.5imx3g.com/forum.php?mod=viewthread&tid=70

OP: Ok, I've got it (mostly) worked out thanks to a post here and a post elsewhere. The key is changing polarity of the signal in the IRQ handler. Here, I am assuming that the PWMs are phase aligned, so I only need to check for rising/falling edges of the Channel 1 signal. But this could easily be adapted to allow for PWMs that are not phase-aligned.
Here is my current code, reading 4 PWM signals with a single timer (the ccr[] array holds the current PWM pulse widths):

  1. // Hold onto the Channel 1 init structure -- we will use it to reverse
  2. // polarity on every edge interrupt.
  3. static TIM_ICInitTypeDef TIM_CH1_ICInitStructure;
  4. #define GPIO_AF_TIM2 GPIO_AF_2
  5. void ConfigPwmIn() {
  6. GPIO_InitTypeDef GPIO_InitStructure;
  7. TIM_ICInitTypeDef TIM_ICInitStructure;
  8. NVIC_InitTypeDef NVIC_InitStructure;
  9. TIM_DeInit(TIM2 );
  10. /* TIM2 clock enable */
  11. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  12. /* GPIOC clock enable */
  13. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
  14. /* TIM2 GPIO pin configuration : CH1=PD3, C2=PD4, CH3=PD7, CH4=PD6 */
  15. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_7 | GPIO_Pin_6;
  16. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  17. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  18. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  19. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  20. GPIO_Init(GPIOD, &GPIO_InitStructure);
  21. /* Connect pins to TIM3 AF2 */
  22. GPIO_PinAFConfig(GPIOD, GPIO_PinSource3, GPIO_AF_TIM2 );
  23. GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_TIM2 );
  24. GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_TIM2 );
  25. GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_TIM2 );
  26. NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  27. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  28. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  29. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  30. NVIC_Init(&NVIC_InitStructure);
  31. /* Enable capture*/
  32. TIM_CH1_ICInitStructure.TIM_Channel = TIM_Channel_1;
  33. TIM_CH1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  34. TIM_CH1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  35. TIM_CH1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  36. TIM_CH1_ICInitStructure.TIM_ICFilter = 0;
  37. TIM_ICInit(TIM2, &TIM_ICInitStructure);
  38. TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  39. TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
  40. TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  41. TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  42. TIM_ICInitStructure.TIM_ICFilter = 0;
  43. TIM_ICInit(TIM2, &TIM_ICInitStructure);
  44. TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
  45. TIM_ICInit(TIM2, &TIM_ICInitStructure);
  46. TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
  47. TIM_ICInit(TIM2, &TIM_ICInitStructure);
  48. /* Enable TIM2 */
  49. TIM_Cmd(TIM2, ENABLE);
  50. /* Enable CC1-4 interrupt */
  51. TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
  52. /* Clear CC1 Flag*/
  53. TIM_ClearFlag(TIM2, TIM_FLAG_CC1 | TIM_FLAG_CC2 | TIM_FLAG_CC3 | TIM_FLAG_CC4 );
  54. }
  55. static volatile uint32_t ccr[4];
  56. static volatile char pulseState = 0;
  57. void TIM2_IRQHandler() {
  58. if (TIM2 ->SR & TIM_IT_CC1 ) {
  59.   TIM2 ->SR &= (~TIM_IT_CC1 );
  60.   if (pulseState == 0) {
  61.    TIM_CH1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
  62.    // Any time we get a rising edge on CH1, we reset the counter. All channels are
  63.    // phase aligned, so they all use this as a reference.
  64.    TIM_SetCounter(TIM2, 0);
  65.   } else {
  66.    TIM_CH1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  67.    // Pull the value on the falling edge.
  68.    ccr[0] = TIM_GetCapture1(TIM2 );
  69.   }
  70.   pulseState = !pulseState;
  71.   // Reverse polarity.
  72.   TIM_ICInit(TIM2, &TIM_CH1_ICInitStructure);
  73. }
  74. if (TIM2 ->SR & TIM_IT_CC2 ) {
  75.   TIM2 ->SR &= (~TIM_IT_CC2 );
  76.   ccr[1] = TIM_GetCapture2(TIM2 );
  77. }
  78. if (TIM2 ->SR & TIM_IT_CC3 ) {
  79.   TIM2 ->SR &= (~TIM_IT_CC3 );
  80.   ccr[2] = TIM_GetCapture3(TIM2 );
  81. }
  82. if (TIM2 ->SR & TIM_IT_CC4 ) {
  83.   TIM2 ->SR &= (~TIM_IT_CC4 );
  84.   ccr[3] = TIM_GetCapture4(TIM2 );
  85. }
  86. }
复制代码

你可能感兴趣的:(stm32)