Page 1 of 2
[Solved] Use timer for precise interrupt
Posted: Tue Jan 14, 2020 8:17 pm
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.
Re: Use timer for precise interrupt
Posted: Tue Jan 14, 2020 8:39 pm
by Step73
Re: Use timer for precise interrupt
Posted: Tue Jan 14, 2020 8:40 pm
by fpiSTM
You find the right example
Re: Use timer for precise interrupt
Posted: Tue Jan 14, 2020 8:44 pm
by fpiSTM
Here you will find further reading on the HardwareTimer API:
https://github.com/stm32duino/wiki/wiki ... er-library
Re: Use timer for precise interrupt
Posted: Tue Jan 14, 2020 9:03 pm
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?
Re: Use timer for precise interrupt
Posted: Tue Jan 14, 2020 9:24 pm
by fpiSTM
They are defined in the variant.h.
But If you do not use Servo, Tone and softwareSerial libraries then it is ok.
Re: Use timer for precise interrupt
Posted: Tue Jan 14, 2020 9:56 pm
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?
Re: Use timer for precise interrupt
Posted: Tue Jan 14, 2020 10:28 pm
by fredbox
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);
Re: Use timer for precise interrupt
Posted: Wed Jan 15, 2020 1:40 am
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.
Re: Use timer for precise interrupt
Posted: Wed Jan 15, 2020 1:41 am
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.