SysTick interrupts are typically configured to occur on a 1ms boundary, but in some cases, due to clocking or power constraints, they can range from 5-20ms. If the interrupt is used merely for task scheduling, or for coarse grained delays, then the resolution is acceptable. However, sometimes finer resolution is called for.
Fine Grained Blocking
For example, after asserting the chip select line on a peripheral device, many require a delay before data can be accepted. You could insert a number of NOP() instructions to accommodate the wait, but that would result in highly application constrained (read: unportable) code — the number of NOPs must correspond the the clock speed of the MCU. For this particular use-case, the best approach would be a fine grained blocking wait:
The function accepts a wait at the microsecond scale (rather than the millisecond scale as would be possible using SysTick). Admittedly, the prescalar is hardcoded to a value of 60 — and it would be much better to get the speed of the peripheral bus in MHz. Simplistically, the timer has an update rate of 1us because the prescalar is set to the speed of the peripheral bus clock. All that remains is to set the reloadVal to the number of microseconds you wish to block for and then wait until the interrupt fires.
Fine Grained Timing
The method can be extended for other applications. Lets say that for some reason you designed your circuit board to use a very expensive SPI peripheral, but accidentally bought the I2C version. You could eat the cost and save the time, or square up to the challenge and bit bang it. Any time you’re going to be manually signalling a peripheral device, getting accurate timing is very important and the Time_delay function really helps in this task. Consider the following I2CBB (bit-banged) driver:
The static variable “sI2CBB.clockTimeUs” is set according to the I2C circuit specifications you are bound to. This will be affected by the device specification, the supply voltage and by the size of the pullup resistors you cleverly found a place for — remember I2C is open-collector!.