cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7xx interrupt trigger timer counter reset

Wleon.1
Associate II

Is there a way to reset the timer (TIM4,3) via interrupt pin without using the interrupt handler/vector table?

7 REPLIES 7
berendi
Principal

Interrupt pins are for interrupts, they aren't good for much else.

Timers can be reset using the slave mode feature through trigger inputs, which are

  • The timer ETRF pin
  • Timer channel 1 or 2, filtered
  • Timer channel 1, not filtered
  • Internal trigger connections, usually coming from another timer

See the description of the timer SMCR register in the reference manual.

I'm going to show it on a STM32F746G-Discovery board.

Enable GPIOB, GPIOI and TIM3 in RCC

	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN |  RCC_AHB1ENR_GPIOIEN;
	RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;

Set PB4 to alternate function 2, i.e. map it to TIM3_CH1. See the alternate function mapping table in the datasheet.

	GPIOB->AFR[0] = (GPIOB->AFR[0] & ~GPIO_AFRL_AFRL4) | (2 << GPIO_AFRL_AFRL4_Pos);
	GPIOB->MODER = (GPIOB->MODER & ~GPIO_MODER_MODER4) | GPIO_MODER_MODER4_1;

Set the internal pulldown on PB4

	GPIOB->PUPDR = (GPIOB->PUPDR & ~GPIO_PUPDR_PUPDR4) | GPIO_PUPDR_PUPDR4_1;

Set PI1 to GPIO output. This is not necessary for the reset to function, only to get some feedback from the onboard LED connected to PI1.

	GPIOI->MODER = (GPIOI->MODER & ~GPIO_MODER_MODER1) | GPIO_MODER_MODER1_0;

Configure timer prescaler and period. I didn't bother to set up the PLL, so my board is running on 16 MHz internal clock. If your clock is faster, adjust the prescaler. At 16 MHz clock, the timer should have a period of 5 seconds. Check your clock setup, if your APB1 timer clock is e.g. 108 MHz, change PSC to 10800-1 to achieve the same period.

	TIM3->PSC = 1600 - 1;
	TIM3->EGR = TIM_EGR_UG;
	TIM3->ARR = 50000 - 1;

Set up slave mode reset according to the desciption in the Timers and external trigger synchronization chapter in the reference manual.

	TIM3->CCMR1 = 0b01 << TIM_CCMR1_CC1S_Pos;
	TIM3->SMCR =
			(0b100 << TIM_SMCR_SMS_Pos) |
			(0b101 << TIM_SMCR_TS_Pos);

Start the timer

	TIM3->CR1 = TIM_CR1_CEN;

Now the timer should run with the period set above. I'm going to visualize it through the onboard LED, flashing it when the counter is less than 1000.

	while(1) {
		if(TIM3->CNT < 1000)
			GPIOI->BSRR = 1 << 1;
		else
			GPIOI->BSRR = 1 << 17;
	}

and whenever I connect PB4 to 3.3V, the LED is flashing, meaning that the counter is reset.

In STM32F4 we have

TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset); 
TIM_SelectInputTrigger(TIM3,TIM_TS_ETRF);

But it wont work in STM32F7, is there any related functions ?

It should work the same way, provided than the pin alternate function setup is right for your MCU. But you can never know for sure with HAL.

 

Now the choice is yours, you can experiment further with HAL, changing the arguments of poorly documented functions hoping that you get lucky once, or use the well documented, properly working register interface.

This is SPL, not Cube/HAL...

JW

berendi
Principal

Oops.

And there is no SPL for STM32F7, and will probably never be.

These particular functions and the related constants should be usable for F7, though, don't they?

JW

Wleon.1
Associate II

I will try with :

   TIM_SlaveConfigTypeDef sTriggerSlaveConfig = {0};
   sTriggerSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; //resets when int
   sTriggerSlaveConfig.InputTrigger = TIM_TS_ETRF; //use external pin
   HAL_TIM_SlaveConfigSynchro_IT(&htim3,&sTriggerSlaveConfig);

lets hope that it works