cancel
Showing results for 
Search instead for 
Did you mean: 

Different channels of same the Timer are not working together when using with registers.

SKUND.11
Associate III

The problem that I'm facing is that I have configured Timer 2 of channel 1 as output compare and channel 2 as input capture. Let me give you a brief idea about the logic that i'm using. The on board led's GPIO is configured as output compare and i'm toggling it every 250 ms. The second channel which is input capture is set as to capture the value at rising edge. It is connect to on board led so as soon as the led turns on the input capture will capture the value which is it will do it every 250 ms. I'm sure that my init function are not wrong because i use them individually they work fine . The problem occurs as soon as i run both of them together.This program run smoothly when i use different timers for different channels. The code is given below:

Input capture and Output capture functions-

void InputCapture3()
{
	// enable clock access to GPIOA and set PA1 to alternative function and TIM2 alternative function
	RCC->AHB1ENR |=RCC_AHB1ENR_GPIOAEN;
	GPIOA->MODER &=~GPIO_MODER_MODE1_0;
	GPIOA->MODER |=GPIO_MODER_MODE1_1;
	GPIOA->AFR[0] |=AFR1_TIM;
 
	RCC->APB1ENR |=RCC_APB1ENR_TIM2EN;
	
	/*Set CH1 to input capture*/
	TIM2->CCMR1 |= TIM_CCMR1_CC2S_0;
 
	/*Set CH1 to capture at rising edge*/
	TIM2->CCER  |= TIM_CCER_CC2E;
 
	//Enabling the interrupt
	TIM2->DIER |= TIM_DIER_CC2IE;
 
	NVIC_SetPriority(TIM2_IRQn , 0);
	NVIC_EnableIRQ(TIM2_IRQn);
 
 
}
void OutputCompare()
{
	 /*Enable clock access to GPIOA*/
		RCC->AHB1ENR |=RCC_AHB1ENR_GPIOAEN;
 
		/*Set PA5 mode to alternate function*/
		GPIOA->MODER &=~(1U<<10);
		GPIOA->MODER |=(1U<<11);
 
		/*Set PA5 alternate function type to TIM2_CH1 (AF01)*/
		GPIOA->AFR[0] |=AFR5_TIM;
 
		/*Enable clock access to tim2*/
		RCC->APB1ENR |=RCC_APB1ENR_TIM2EN;
 
		/*Set prescaler value*/
		TIM2->PSC =  1600 - 1 ;  //  16 000 000 / 1 600 = 10 000
		/*Set auto-reload value*/
		TIM2->ARR =  10000 - 1;  // 10 000 / 10 000 = 1
 
		//Setting the channel as output compare mode (CC1S bit to 00)
		TIM2->CCMR1 &= ~TIM_CCMR1_CC1S_0;
		TIM2->CCMR1 &= ~TIM_CCMR1_CC1S_1;
 
 
		/*Set output compare toggle mode*/
		TIM2->CCMR1 |= TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1;
 
		/*Enable tim2 ch1 in compare mode*/
		TIM2->CCER |= TIM_CCER_CC1E;
 
 
}

The input capture interrupt handler-

void TIM2_IRQHandler(void)
{
	if(TIM2->SR & TIM_SR_CC2IF)   //Checking the interrupt flag
	{
	      TIM2->SR = ~TIM_SR_CC2IF;  // clearing the interrupt flag
              /*Read captured value*/
	      timestamp =  TIM2->CCR2;
	}

and the main code-

/* USER CODE BEGIN 2 */
InputCapture3();
OutputCompare();
TIM2->CR1 = TIM_CR1_CEN; // enable the timer
  /* USER CODE END 2 */

I think there is problem in starting of the timer but i'm not sure what's going wrong. When i use HAL library i don't have any problem.

15 REPLIES 15

Yes sir, I know that...that's why i have use "|=" instead of "=". i have tried that too. I haven't updated the code here yet.

TDK
Guru

I watched the video. "timestamp" seemed to be updated in both cases. Wasn't immediately clear what you were doing with the wire in the second case, or how CH1 and CH2 were tied together.

There are two errors I pointed out in the code, perhaps correct those, post updated code, and perhaps also post TIM register content.

If you feel a post has answered your question, please click "Accept as Solution".
SKUND.11
Associate III

@TDK​  Yeah the wire was supposed to be medium to connect the two channels(CH1 and CH2). I was constantly removing & connecting it again the wire for input capture I/O to get a rising edge( it was irrelevant)

The main thing was that when the both channels were connected and running only one of them was working(Output compare).

And yeah I updated the code :

  1. As soon as the interrupt occurs in the interrupt handler, I'm checking the interrupt flag and then clearing the flag.
  2. i have replace "=" with "|=" so that it should overwrite the values.

And one thing i want to ask is that -

  • I'm setting the prescalar to "something" in the output compare function and I'm the disabling the prescalar for input capture mode in input capture function because I wish to the capture to be performed at each valid transition.

So is there a problem in it or not?

TDK
Guru

The timer only has one counter. PSC/ARR are per-timer, not per-channel, so these cannot be set per-channel. The channels all see the same CNT counter.

If you feel a post has answered your question, please click "Accept as Solution".

Okay sir

And sir what to you mean by "post TIM register content"