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

 

 

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

 

 

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