cancel
Showing results for 
Search instead for 
Did you mean: 

Reading two PWM signals using only two channels.

EmbeddedPepe
Associate III

Hi!

 

Library used: Standard Peripheral Library (Yea, I must use this one)

Hardware:

  • Test bench that can generate two pwm signals ( A and B )
  • Cable that connects the test bench to the other board
  • Other board that should read the signal, delivered by the cable, and detect the pwm duty cycle and frequency (one for A and one for B).

PORT D PIN 12 Tim4 Channel 1 PORT D PIN 13 Tim4 Channel 2

The test bench frequency/PWM generation is working properly so nothing to debug.

The hardware and cable connections are correct (we already triple-checked them )

The problem arises on the other board: The duty cycle calculated seems to point to only one signal, so if I disconnect the cable of the other signal I still manage to calculate the two duty cycles, meanwhile should go to zero.

 

Pin 12 Port D Timer 4 Channel 1 configuration:

 

void myPWM4_Config_1(tmyPWMInput *me) { RCC_ClocksTypeDef __RCC_CLOCK; myPWMInputCtor(me); RCC_GetClocksFreq(&__RCC_CLOCK); me->clock = __RCC_CLOCK.PCLK1_Frequency * 2; //APB1 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); me->GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; me->GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; me->GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; me->GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; me->GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOD, &me->GPIO_InitStructure); GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); TIM4_IRQHandler_ptf = TIM4_IRQ_PWM; me->NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; me->NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; me->NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; me->NVIC_InitStructure.NVIC_IRQChannelCmd = 1; NVIC_Init(&me->NVIC_InitStructure); me->TIM_TimeBaseStructure.TIM_Period = 0xFFFF; me->TIM_TimeBaseStructure.TIM_Prescaler = 840 - 1; me->TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; me->TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1; me->TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM4, &me->TIM_TimeBaseStructure); me->TIM_CH1_ICInitStructure.TIM_Channel = TIM_Channel_1; me->TIM_CH1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; me->TIM_CH1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; me->TIM_CH1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; me->TIM_CH1_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(TIM4, &me->TIM_CH1_ICInitStructure); // Select the TIM8 Input Trigger: TI1FP1 TIM_SelectInputTrigger(TIM4, TIM_TS_TI1FP1); // Select the slave Mode: Reset Mode TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset); TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable); // Enables TIM8 peripheral Preload register on ARR. TIM_ARRPreloadConfig(TIM4, ENABLE); // Configures the TIM8 Update Request Interrupt source (SETS the CR1->URS bit) TIM_UpdateRequestConfig(TIM4, TIM_UpdateSource_Regular); // Enable the CC1 and the update Interrupt Request TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE); TIM_ClearFlag(TIM4, TIM_FLAG_Update); TIM_Cmd(TIM4, ENABLE); }
View more

 

 

Pin 13 Port D Tim4 Channel 2 configuration:

 

void myPWM4_Config_2(tmyPWMInput *me) { RCC_ClocksTypeDef __RCC_CLOCK; myPWMInputCtor(me); RCC_GetClocksFreq(&__RCC_CLOCK); me->clock = __RCC_CLOCK.PCLK1_Frequency * 2; //APB1 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); me->GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; me->GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; me->GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; me->GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; me->GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOD, &me->GPIO_InitStructure); GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); TIM4_IRQHandler_ptf = TIM4_IRQ_PWM; me->NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; me->NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; me->NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; me->NVIC_InitStructure.NVIC_IRQChannelCmd = 1; NVIC_Init(&me->NVIC_InitStructure); me->TIM_TimeBaseStructure.TIM_Period = 0xFFFF; me->TIM_TimeBaseStructure.TIM_Prescaler = 840 - 1; me->TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; me->TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1; me->TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM4, &me->TIM_TimeBaseStructure); me->TIM_CH2_ICInitStructure.TIM_Channel = TIM_Channel_2; me->TIM_CH2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; me->TIM_CH2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; me->TIM_CH2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; me->TIM_CH2_ICInitStructure.TIM_ICFilter = 0x0; TIM_PWMIConfig(TIM4, &me->TIM_CH2_ICInitStructure); // Select the TIM8 Input Trigger: TI1FP1 TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2); // Select the slave Mode: Reset Mode TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset); TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable); // Enables TIM8 peripheral Preload register on ARR. TIM_ARRPreloadConfig(TIM4, ENABLE); // Configures the TIM8 Update Request Interrupt source (SETS the CR1->URS bit) TIM_UpdateRequestConfig(TIM4, TIM_UpdateSource_Regular); // Enable the CC1 and the update Interrupt Request TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE); TIM_ClearFlag(TIM4, TIM_FLAG_Update); TIM_Cmd(TIM4, ENABLE); }
View more

 

 

Capture/Compare Interrupt code:

 

void TIM4_IRQHandler( void ) { if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET) { tmyPWMInput *pPWM4_1 = &myCTRL.myHW.myPortDCfg.myPWM4_1; //PIN12 // Clear TIM8 Capture Compare1 interrupt pending bit TIM_ClearITPendingBit(TIM4, TIM_IT_CC1); pPWM4_1->HighPeriod = TIM_GetCapture1(TIM4); // length of high-portion pPWM4_1->FullPeriod = TIM_GetCapture2(TIM4); // total period myPWMCalc(pPWM4_1); //Calculate the frequency and duty cycle } if (TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET) { tmyPWMInput *pPWM4_2 = &myCTRL.myHW.myPortDCfg.myPWM4_2; //PIN13 // Clear TIM8 Capture Compare1 interrupt pending bit TIM_ClearITPendingBit(TIM4, TIM_IT_CC2); pPWM4_2->HighPeriod = TIM_GetCapture1(TIM4); // length of high-portion pPWM4_2->FullPeriod = TIM_GetCapture2(TIM4); // total period myPWMCalc(pPWM4_2); //Calculate the frequency and duty cycle } }

 

 

How do I read the two different PWM Signals Duty Cycle I receive from the test bench using only two channels of the same timer? ( the frequency get measured correctly)

Output I get: The two duty cycle i calculate are equal because they point to the same frequency signal, so If I disconnect the cable of the other signal I still read two PWM duty cycles.

What I'm supposed to see: duty cycles similar-ish and when i disconnect one signal the duty cycle of the disconnected signal should go to zero.

 
1 REPLY 1