Skip to main content
SKUND.11
Associate III
April 15, 2022
Question

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

  • April 15, 2022
  • 7 replies
  • 4400 views

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.

This topic has been closed for replies.

7 replies

TDK
Super User
April 15, 2022

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""."
SKUND.11
SKUND.11Author
Associate III
April 15, 2022

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.

TDK
Super User
April 15, 2022

> 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""."
SKUND.11
SKUND.11Author
Associate III
April 15, 2022

I'm sorry but I didn't get.

SKUND.11
SKUND.11Author
Associate III
April 15, 2022

i suppose you are talking about this line

TIM2->CCMR1 |= TIM_CCMR1_CC2S_0;

SKUND.11
SKUND.11Author
Associate III
April 16, 2022

@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

waclawek.jan
Super User
April 16, 2022

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

SKUND.11
SKUND.11Author
Associate III
April 16, 2022

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
Super User
April 16, 2022

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
SKUND.11Author
Associate III
April 17, 2022

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

SKUND.11
SKUND.11Author
Associate III
April 17, 2022

@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
Super User
April 17, 2022

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""."
SKUND.11
SKUND.11Author
Associate III
April 17, 2022

Okay sir