22 ISR_16_Timers_Array.ino
33 For STM32 boards
44 Written by Khoi Hoang
5-
5+
66 Built by Khoi Hoang https://github.com/khoih-prog/STM32_TimerInterrupt
77 Licensed under MIT license
8-
8+
99 Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
1010 unsigned long miliseconds), you just consume only one STM32 timer and avoid conflicting with other cores' tasks.
1111 The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
1212 Therefore, their executions are not blocked by bad-behaving functions / tasks.
1313 This important feature is absolutely necessary for mission-critical tasks.
14-
14+
1515 Based on SimpleTimer - A timer library for Arduino.
16161717 Copyright (c) 2010 OTTOTECNICA Italy
18-
18+
1919 Based on BlynkTimer.h
2020 Author: Volodymyr Shymanskyy
21-
22- Version: 1.2.0
23-
21+
22+ Version: 1.2.1
23+
2424 Version Modified By Date Comments
2525 ------- ----------- ---------- -----------
2626 1.0.0 K Hoang 30/10/2020 Initial coding
2727 1.0.1 K Hoang 06/11/2020 Add complicated example ISR_16_Timers_Array using all 16 independent ISR Timers.
2828 1.1.1 K.Hoang 06/12/2020 Add complex examples. Bump up version to sync with other TimerInterrupt Libraries
2929 1.2.0 K.Hoang 08/01/2021 Add better debug feature. Optimize code and examples to reduce RAM usage
30+ 1.2.1 K.Hoang 20/08/2021 Add support to STM32L5 (NUCLEO_L552ZE_Q). Verify OK with STM32H7 (NUCLEO_H743ZI2)
3031*****************************************************************************************************************************/
3132/*
3233 Notes:
5051
5152#if !( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) ||defined(STM32F4) || defined(STM32F7) || \
5253 defined (STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7) ||defined(STM32G0) || defined(STM32G4) || \
53- defined(STM32WB) || defined(STM32MP1) )
54+ defined(STM32WB) || defined(STM32MP1) || defined(STM32L5) )
5455 #error This code is designed to run on STM32F/L/H/G/WB/MP1 platform! Please check your Tools->Board setting.
5556#endif
5657
6768#include < SimpleTimer.h> // https://github.com/schinken/SimpleTimer
6869
6970#ifndef LED_BUILTIN
70- #define LED_BUILTIN 13
71+ #define LED_BUILTIN 13
7172#endif
7273
7374#ifndef LED_BLUE
74- #define LED_BLUE 2
75+ #define LED_BLUE 2
7576#endif
7677
7778#ifndef LED_RED
78- #define LED_RED 3
79+ #define LED_RED 3
7980#endif
8081
8182#define HW_TIMER_INTERVAL_US 10000L
@@ -85,7 +86,7 @@ volatile uint32_t startMillis = 0;
8586// Depending on the board, you can select STM32 Hardware Timer from TIM1-TIM22
8687// For example, F767ZI can select Timer from TIM1-TIM14
8788// If you select a Timer not correctly, you'll get a message from ci[ompiler
88- // 'TIMxx' was not declared in this scope; did you mean 'TIMyy'?
89+ // 'TIMxx' was not declared in this scope; did you mean 'TIMyy'?
8990
9091// Init STM32 timer TIM1
9192STM32Timer ITimer (TIM1);
@@ -127,39 +128,39 @@ typedef void (*irqCallback) ();
127128
128129#if USE_COMPLEX_STRUCT
129130
130- typedef struct
131- {
132- irqCallback irqCallbackFunc;
133- uint32_t TimerInterval;
134- unsigned long deltaMillis;
135- unsigned long previousMillis;
136- } ISRTimerData;
137-
138- // In NRF52, avoid doing something fancy in ISR, for example Serial.print()
139- // The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
140- // Or you can get this run-time error / crash
141-
142- void doingSomething (int index);
131+ typedef struct
132+ {
133+ irqCallback irqCallbackFunc;
134+ uint32_t TimerInterval;
135+ unsigned long deltaMillis;
136+ unsigned long previousMillis;
137+ } ISRTimerData;
138+
139+ // In NRF52, avoid doing something fancy in ISR, for example Serial.print()
140+ // The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
141+ // Or you can get this run-time error / crash
142+
143+ void doingSomething (int index);
143144
144145#else
145146
146- volatile unsigned long deltaMillis [NUMBER_ISR_TIMERS] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
147- volatile unsigned long previousMillis [NUMBER_ISR_TIMERS] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
148-
149- // You can assign any interval for any timer here, in milliseconds
150- uint32_t TimerInterval[NUMBER_ISR_TIMERS] =
151- {
152- 5000L , 10000L , 15000L , 20000L , 25000L , 30000L , 35000L , 40000L ,
153- 45000L , 50000L , 55000L , 60000L , 65000L , 70000L , 75000L , 80000L
154- };
155-
156- void doingSomething (int index)
157- {
158- unsigned long currentMillis = millis ();
159-
160- deltaMillis[index] = currentMillis - previousMillis[index];
161- previousMillis[index] = currentMillis;
162- }
147+ volatile unsigned long deltaMillis [NUMBER_ISR_TIMERS] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
148+ volatile unsigned long previousMillis [NUMBER_ISR_TIMERS] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
149+
150+ // You can assign any interval for any timer here, in milliseconds
151+ uint32_t TimerInterval[NUMBER_ISR_TIMERS] =
152+ {
153+ 5000L , 10000L , 15000L , 20000L , 25000L , 30000L , 35000L , 40000L ,
154+ 45000L , 50000L , 55000L , 60000L , 65000L , 70000L , 75000L , 80000L
155+ };
156+
157+ void doingSomething (int index)
158+ {
159+ unsigned long currentMillis = millis ();
160+
161+ deltaMillis[index] = currentMillis - previousMillis[index];
162+ previousMillis[index] = currentMillis;
163+ }
163164
164165#endif
165166
@@ -249,44 +250,44 @@ void doingSomething15()
249250
250251#if USE_COMPLEX_STRUCT
251252
252- ISRTimerData curISRTimerData[NUMBER_ISR_TIMERS] =
253- {
254- // irqCallbackFunc, TimerInterval, deltaMillis, previousMillis
255- { doingSomething0, 5000L , 0 , 0 },
256- { doingSomething1, 10000L , 0 , 0 },
257- { doingSomething2, 15000L , 0 , 0 },
258- { doingSomething3, 20000L , 0 , 0 },
259- { doingSomething4, 25000L , 0 , 0 },
260- { doingSomething5, 30000L , 0 , 0 },
261- { doingSomething6, 35000L , 0 , 0 },
262- { doingSomething7, 40000L , 0 , 0 },
263- { doingSomething8, 45000L , 0 , 0 },
264- { doingSomething9, 50000L , 0 , 0 },
265- { doingSomething10, 55000L , 0 , 0 },
266- { doingSomething11, 60000L , 0 , 0 },
267- { doingSomething12, 65000L , 0 , 0 },
268- { doingSomething13, 70000L , 0 , 0 },
269- { doingSomething14, 75000L , 0 , 0 },
270- { doingSomething15, 80000L , 0 , 0 }
271- };
272-
273- void doingSomething (int index)
274- {
275- unsigned long currentMillis = millis ();
276-
277- curISRTimerData[index].deltaMillis = currentMillis - curISRTimerData[index].previousMillis ;
278- curISRTimerData[index].previousMillis = currentMillis;
279- }
253+ ISRTimerData curISRTimerData[NUMBER_ISR_TIMERS] =
254+ {
255+ // irqCallbackFunc, TimerInterval, deltaMillis, previousMillis
256+ { doingSomething0, 5000L , 0 , 0 },
257+ { doingSomething1, 10000L , 0 , 0 },
258+ { doingSomething2, 15000L , 0 , 0 },
259+ { doingSomething3, 20000L , 0 , 0 },
260+ { doingSomething4, 25000L , 0 , 0 },
261+ { doingSomething5, 30000L , 0 , 0 },
262+ { doingSomething6, 35000L , 0 , 0 },
263+ { doingSomething7, 40000L , 0 , 0 },
264+ { doingSomething8, 45000L , 0 , 0 },
265+ { doingSomething9, 50000L , 0 , 0 },
266+ { doingSomething10, 55000L , 0 , 0 },
267+ { doingSomething11, 60000L , 0 , 0 },
268+ { doingSomething12, 65000L , 0 , 0 },
269+ { doingSomething13, 70000L , 0 , 0 },
270+ { doingSomething14, 75000L , 0 , 0 },
271+ { doingSomething15, 80000L , 0 , 0 }
272+ };
273+
274+ void doingSomething (int index)
275+ {
276+ unsigned long currentMillis = millis ();
277+
278+ curISRTimerData[index].deltaMillis = currentMillis - curISRTimerData[index].previousMillis ;
279+ curISRTimerData[index].previousMillis = currentMillis;
280+ }
280281
281282#else
282283
283- irqCallback irqCallbackFunc[NUMBER_ISR_TIMERS] =
284- {
285- doingSomething0, doingSomething1, doingSomething2, doingSomething3,
286- doingSomething4, doingSomething5, doingSomething6, doingSomething7,
287- doingSomething8, doingSomething9, doingSomething10, doingSomething11,
288- doingSomething12, doingSomething13, doingSomething14, doingSomething15
289- };
284+ irqCallback irqCallbackFunc[NUMBER_ISR_TIMERS] =
285+ {
286+ doingSomething0, doingSomething1, doingSomething2, doingSomething3,
287+ doingSomething4, doingSomething5, doingSomething6, doingSomething7,
288+ doingSomething8, doingSomething9, doingSomething10, doingSomething11,
289+ doingSomething12, doingSomething13, doingSomething14, doingSomething15
290+ };
290291
291292#endif
292293// /////////////////////////////////////////
@@ -306,21 +307,21 @@ void simpleTimerDoingSomething2s()
306307
307308 unsigned long currMillis = millis ();
308309
309- Serial.print (F (" SimpleTimer : " ));Serial.print (SIMPLE_TIMER_MS / 1000 );
310+ Serial.print (F (" SimpleTimer : " )); Serial.print (SIMPLE_TIMER_MS / 1000 );
310311 Serial.print (F (" , ms : " )); Serial.print (currMillis);
311312 Serial.print (F (" , Dms : " )); Serial.println (currMillis - previousMillis);
312313
313314 for (uint16_t i = 0 ; i < NUMBER_ISR_TIMERS; i++)
314315 {
315- #if USE_COMPLEX_STRUCT
316+ #if USE_COMPLEX_STRUCT
316317 Serial.print (F (" Timer : " )); Serial.print (i);
317318 Serial.print (F (" , programmed : " )); Serial.print (curISRTimerData[i].TimerInterval );
318319 Serial.print (F (" , actual : " )); Serial.println (curISRTimerData[i].deltaMillis );
319320#else
320321 Serial.print (F (" Timer : " )); Serial.print (i);
321322 Serial.print (F (" , programmed : " )); Serial.print (TimerInterval[i]);
322323 Serial.print (F (" , actual : " )); Serial.println (deltaMillis[i]);
323- #endif
324+ #endif
324325 }
325326
326327 previousMillis = currMillis;
@@ -358,7 +359,7 @@ void setup()
358359#else
359360 previousMillis[i] = startMillis;
360361 ISR_Timer.setInterval (TimerInterval[i], irqCallbackFunc[i]);
361- #endif
362+ #endif
362363 }
363364
364365 // You need this timer for non-critical tasks. Avoid abusing ISR if not absolutely necessary.
0 commit comments