Timer ISR with variable period is fairly easy to achieve.
Variant 1. Timers usually have a countdown register, which can be updated by the code. The countdown initial value can be updated inside the ISR itself on a case by case basis. A state machine can be used to decide which initial value to assign to the counter.
Variant 2. Another option is to set up the timer for the shortest duration then count interrupts if you need longer duration. For example, you need to do 3 different things every 5ms, 10ms, 1s. Set the timer for 5ms, within the ISR increment a counter** every time ISR is called. In the main()
loop, compare the counter to thresholds. For 10ms duration the threshold would be 2, for 1s the threshold would be 200. Once the counter is equal to the threshold, the main()
does what needs to be done at that interval.
A good thing about this approach is that you can have one timer and one ISR, but multiple thresholds (multiple counters too, if needed). The variable timing would be implemented in the code, rather than in the hardware timer.
Note that, this approach requires a main()
loop, which always loops faster than the shortest interval. Accuracy of the timing should also be considered. If that becomes a problem, there are variations of this pattern, which can work with a slower main()
loop.
** counter and flags are global variables visible to both ISR and main()