I have a problem with the timer interrupts. My program always stops as soon as I try to initialize the interrupt as shown below.
When I comment out the line in which the function is passed, the program works again. What am I doing wrong? Thank you in advance!
void setup() {
…….
Timer3.setChannel1Mode(TIMER_OUTPUTCOMPARE);
Timer3.setPeriod(data_out_rate); // in microseconds
Timer3.setCompare1(1); // overflow might be small
//Timer3.attachCompare1Interrupt(data_out);
Timer3.pause();
}
void data_out(void) {
//empty function
}
The function is empty, I wonder if the compiler is just removing it, or some other optimization going on with it.
Try using an ISR that blinks a led, turning on in one call, and off in the next. Besides getting some content on the function, that will help you also see if the function is never called (led doesn’t turn on), or called but never returns (led turns on, but doesn’t turn off in the second call).
#define cu_update_rate 1500000 //1.5Hz
void data_out(void) {
digitalWrite(LED, HIGH);
Serial1.println(“Interrupt2”);
Serial1.flush();
}
delay(2000);
Timer3.pause();
Timer3.setPeriod(data_out_rate); // in microseconds
Timer3.setChannel1Mode(TIMER_OUTPUTCOMPARE);
Timer3.setCompare1(1); // overflow might be small
Timer3.attachCompare1Interrupt(data_out);
Timer3.refresh();
Timer3.resume();
It’s just a guess, but serial.flush() may depend on some usart interrupts that may have a lower priority than the timer interrupts and so will never complete waiting for a usart interrupt that will never be serviced because you are waiting within a higher priority ISR.
Check what’s involved in the serial1.println and serial.flush().
In your first post the timer is never stopped, so as soon as you attach the ISR, it can call it.
About how often the ISR is called is not relevant in this case, can you clarify why you mention that’s every 1.5 seconds?
As far as I understand from your posts, the ISR is called once, turn on the led, and never returns, so how frequently is called is irrelevant.
Take the serial calls out of the ISR and check, I bet the ISR will return and your loop will keep running.
Can I rate the priority of the timer interrupt?
[l0lhaxx – Tue Apr 03, 2018 7:02 am] –
thanks a lot for your quick help! You’re right, without the Serial.println the interrupt works as desired. The problem is, I want to call functions in the interrupt that contain Serial.print commands. How should I implement the whole otherwise? Is there a trick?Can I rate the priority of the timer interrupt?
I think you could try with:
nvic_irq_set_priority((Serial1.c_dev())->irq_num, 0xE); // default IRQ priority is 0xF (defined in nvic_init()), setting USART1 priority to 0xE makes it higher priority
[l0lhaxx – Tue Apr 03, 2018 4:20 pm] –
Thanks for the tip, I will try it out on occasion. I tried something else and found out something interesting. Serial.println works ….. but only 4-5 times in the interrupt. If I add more lines with the println command, I have again the effect that nothing is done (not even the loop). But why?!![]()
You are likely filling up the buffer. If the usart interrupt has a lower priority, the data get’s queued in the buffer, but not sent out, so at some point the buffer fills up and can’t take any more data, blocking forever.
If you plan to use the usart from within your timer ISR, is likely the best to adjust the priority as Edogaldo pointed out.
I would like to thank you very much. It actually works the way it should. Would never have come to it without your help. Thanks and keep it up!
EDIT: is it also possible to change the priority of external interrupts?
- All interrupts have associated configurable priority
- Priority values range from 0x0 (highest priority) to 0xF (lowest priority)
- In the Libmaple core an interrupt with higher priority (lower priority value) will preempt an interrupt with lower priority (this is because in the Libmaple core all priority bits are configured as “priority group”)
- The Libmaple core by default assigns priority 0xF (lowest) to all interrupts (in nvic_init())
For deeper details on F1 interrupt priority management, priority grouping, etc., you can refer to PM0056 (one of the bibles).
https://github.com/Naguissa/uTimerLib
You can see STM32 attachInterrupt procedure here: https://github.com/Naguissa/uTimerLib/b … b.cpp#L180
Also, I suggest reading this interesting issue about interrupts and internal timing functions: https://github.com/Naguissa/uTimerLib/issues/1


