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
TDK
Guru

What chip?

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

> The problem occurs as soon as i run both of them together.

Could do a little better in explaining the problem. In what way are they not working? Is the LED not toggling? Is the CCR2 value not as expected?

Need to clear the flag in TIM2_IRQHandler otherwise it will endlessly get called. You should also verify the flag is set and clear it before performing logic associated with that.

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

> TIM2->CCMR1 = TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1;

This clears the settings you made in InputCapture3.

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

The one that I'm using is STM32F401RE.

When i say they together don't work...I mean that the led is toggling but the input is not capturing the value at rising edge.

And the checking the flag and clearing it..I have done that to.

I'm sorry but I didn't get.

i suppose you are talking about this line

TIM2->CCMR1 |= TIM_CCMR1_CC2S_0;

Use |= instead of = to set bits without changing ones that are already set.
If you feel a post has answered your question, please click "Accept as Solution".

Thank you for the feedback.

But the results are still the same..it's not working(led is toggling but it's not capture the value as soon as a rising edge occurs.

Is there any thing other than this that i can do?

SKUND.11
Associate III

@TDK​ I have personally made this video...it's a 30 seconds clip just to show you how things are working. Would be a great if you could see this. I need to solve this problem as soon as possible.

https://drive.google.com/file/d/1L_FaZHVX5Xv8tdzcSNaixqnJu02fhZY5/view?usp=sharing

As TDK said, the second time you write into TIM2->CCMR1 overwrites what you wrote the first time.

In doubts, always start with reading content of TIM and relevant GPIO registers and check/post them.

JW