Issue in using two channels of Timer 2, one as input capture and another as output compare.
Dear All,
Board: Nucleo - H745ZI-Q
What am I trying to do ?
I am using to measure pulse width of an signal using input capture mode of timer 2 channel 1. Then multiply that width by two and wait for that much time and generate an output pulse using output compare mode of timer 2 channel 2.
What have I done?
I configure the GPIOs for Timer 2 channel 1 and Channel 2,that is pins PA0, PB3.
I configure the timer with ARR = 0xFFFF, PSC = 0x9, thus effective timer clock is 20MHz.
I configure the channel 1 as input capture mode , sensitive to both rising and falling edge.
I configure channel 2 as output compare mode, mode "0001", upon match PB3 should go high.
I enable interrupt for channel 1.
Start the timer.
When the rising edge occur, in ISR , I read CNT value.
When the fallig edge occurs, in ISR , I read CNT value, find the pulse width, multiply the valur by two, stop the counter, reset the counter, load CCR2 by the computed value and enable the channel 2 and start the timer again.
Present Issue: Pulse width calculation using input capture is working fine. But the output compare output is always becoming high after a fixed time after the input falling edge(after around 500 ns). Its behaving as if CCR2 has zero value.
Its baffling because in debug mode CCR2 is getting the value that I am loading with but the output doesnot seem to follow ccr2 value, it is always assuming ccr2 as zero somehow.
Am I doing something fundamentally wrong.
Any help is appreciated.
Thank you
Code Snippet:
Configuring Timer:
void readingPWTimer2()
{
RCC -> APB1LENR |= RCC_APB1LENR_TIM2EN;
TIM2->CR1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS); /* Select the up counter mode */
TIM2->CR1 |= 0x00000000U;
TIM2->CR1 &= ~TIM_CR1_CKD;
TIM2->ARR = 0xFFFF; /* Set the Autoreload value */
TIM2->PSC = 0x9; /* Set the Prescaler value */
TIM2->SMCR = RESET;
TIM2->CCMR1 |= TIM_CCMR1_CC1S_0;
TIM2->CCER |= (TIM_CCER_CC1P | TIM_CCER_CC1NP) ;
TIM2->CCER |= TIM_CCER_CC1E;
TIM2->SR = ~TIM_SR_CC1IF;
TIM2->DIER |= TIM_DIER_CC1IE;
TIM2->EGR |= TIM_EGR_UG;
// Setting up channel2
TIM2->CCMR1 |= (TIM_CCMR1_OC2M_0);
TIM2->CCMR1 |= TIM_CCMR1_OC2FE;
TIM2->EGR |= TIM_EGR_UG;
TIM2->CR1 |= TIM_CR1_CEN; /* Enable the TIM peripheral */
NVIC_EnableIRQ(TIM2_IRQn);
return;
}Interrupt Handler:
void Timer2CaptureCompare_Callback(void)
{
if(TIM2->SR & TIM_SR_CC1IF)
{
//clear the interrupt
TIM2->SR &= ~(TIM_SR_CC1IF);
if( timer2Ch1Is_First_Captured == 0)
{
timer2Ch1IC_Val1 = TIM2->CCR1 ;
timer2Ch1Is_First_Captured = 1;
}
else if(timer2Ch1Is_First_Captured == 1)
{
timer2Ch1IC_Val2 = TIM2->CCR1 ;
if(timer2Ch1IC_Val2 > timer2Ch1IC_Val1)
{
timer2Ch1Difference = timer2Ch1IC_Val2 - timer2Ch1IC_Val1 ;
}
timer2Ch1Is_First_Captured = 0;
// stop the timers counter
TIM2->CR1 &= ~(TIM_CR1_CEN);
// Resetting the counter
TIM2->EGR |= TIM_EGR_UG;
TIM2->CCR2 = 20*timer2Ch1Difference;
TIM2->CCER |= TIM_CCER_CC2E;
TIM2->CR1 |= TIM_CR1_CEN; /* Enable the TIM peripheral */
}
}
else
{
printf("Inside timer2 interrupt but CC1F not set");
}
}Also I have tried with ch4 instead of ch2 as output but same result.
