[Solved] Use timer for precise interrupt

Post here first, or if you can't find a relevant section!
Step73
Posts: 27
Joined: Tue Jan 14, 2020 2:55 pm

[Solved] Use timer for precise interrupt

Post by Step73 »

I need to use an interrupt every 50 ms to control a stepper motor.
I'm able to do this with the standard Arduino board (AVR-based) but I'm too new to STM32 to do the same.

I searched in the forum, but I'm also not sure if I need to find something suitable for my Nucleo F429ZI board.
Would you please put me on the right way? It's not clear if I have to manually set the CPU registers (after reading the huge manual) or there's a framework function to help me.
Step73
Posts: 27
Joined: Tue Jan 14, 2020 2:55 pm

Re: Use timer for precise interrupt

Post by Step73 »

User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Use timer for precise interrupt

Post by fpiSTM »

Step73 wrote: Tue Jan 14, 2020 8:39 pm Perhaps this might be useful?

https://github.com/stm32duino/STM32Exam ... llback.ino
You find the right example ;)
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Use timer for precise interrupt

Post by fpiSTM »

Here you will find further reading on the HardwareTimer API:
https://github.com/stm32duino/wiki/wiki ... er-library
Step73
Posts: 27
Joined: Tue Jan 14, 2020 2:55 pm

Re: Use timer for precise interrupt

Post by Step73 »

Thanks. Just a clarification. In the README I read:
Some instances are used by Servo, Tone and SoftSerial (see TIMER_SERVO, TIMER_TONE and TIMER_SERIAL) but only when they are used. Just be sure there is no conflict with your own usage.
Well, is there a simple way to check such a conflict? I use several libraries (servo, stepper, etc...). I have to manually check their source code?
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Use timer for precise interrupt

Post by fpiSTM »

They are defined in the variant.h.

But If you do not use Servo, Tone and softwareSerial libraries then it is ok.
Step73
Posts: 27
Joined: Tue Jan 14, 2020 2:55 pm

Re: Use timer for precise interrupt

Post by Step73 »

I cannot get it to work.
Here my minimal example, almost the same of the linked one:

Code: Select all

void setup()
{
  pinMode(LED_RED, OUTPUT); 
  digitalWrite(LED_RED, HIGH);

  TIM_TypeDef *Instance = TIM1;
  HardwareTimer *timerBase = new HardwareTimer(Instance);
  timerBase->setOverflow(50, HERTZ_FORMAT);
  timerBase->attachInterrupt(timer_callback);
  timerBase->resume();
}

void loop()
{
}

void timer_callback(HardwareTimer *)
{
  digitalWrite(LED_RED, !digitalRead(LED_RED));
}
I have no activity on the pin - expected 25 Hz toggling.
The pin is working, because writing `HIGH` or `LOW` turns on and off the built-in led.
I also tried with different timers (`TIM1`, `TIM1`, `TIM3`, etc...) with no differences.

Am I missing something obvious?
fredbox
Posts: 125
Joined: Thu Dec 19, 2019 3:05 am
Answers: 2

Re: Use timer for precise interrupt

Post by fredbox »

Code: Select all

#define LED_RED LED_BUILTIN
add

Code: Select all

timerBase->setMode(2, TIMER_OUTPUT_COMPARE);
as the first timerBase line.

Change Hertz from 50 to 5 so you can see it blink clearly.

Code: Select all

timerBase->setOverflow(5, HERTZ_FORMAT);
fredbox
Posts: 125
Joined: Thu Dec 19, 2019 3:05 am
Answers: 2

Re: Use timer for precise interrupt

Post by fredbox »

Here is the simplest way that I know to blink an LED using an interrupt:

Code: Select all

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
}
// blink the led once per second using 1 millisec systick interrupt
void HAL_SYSTICK_Callback(void) {
  static volatile uint32_t ledCount = 0;
  if (++ledCount == 500) {
    ledCount = 0;
    digitalToggleFast(digitalPinToPinName(LED_BUILTIN));
  }
}
For 50 Hz you would use a count of 10.
Last edited by fredbox on Wed Jan 15, 2020 2:38 am, edited 1 time in total.
User avatar
Bakisha
Posts: 139
Joined: Fri Dec 20, 2019 6:50 pm
Answers: 5
Contact:

Re: Use timer for precise interrupt

Post by Bakisha »

You also need

Code: Select all

  timerBase->setMode(1, TIMER_OUTPUT_COMPARE); // 1 is channel number 1, can be 1,2,3 or 4 
in your setup.
Post Reply

Return to “General discussion”