SysTick, Timing & Non-Blocking Delays
Build a millisecond clock from SysTick, replace blocking delays with elapsed-time checks, and survive counter wrap-around.
for (volatile int i = 0; i < 100000; i++); is the first delay everyone writes, and the first one to remove: its duration depends on clock speed and optimisation, and the CPU can do nothing else meanwhile. Firmware keeps time with a hardware timer instead.
Non-blocking design
if (millis() >= start + 500) if ((uint32_t)(millis() - start) >= 500u) start + 500 can wrap to a small number, making the timeout fire instantly (or never). Subtraction of unsigned values is wrap-safe.
delay_ms(1000); // in the main loop Check elapsed() each pass and do other work meanwhile
A blocking delay freezes everything else — button handling, communication, watchdog kicks.
SysTick is clocked at 72 MHz. What reload value gives a 1 ms tick?
Why is (now − start) >= period correct even after the counter wraps?
Unsigned subtraction is performed modulo 2^32, so it yields the true number of ticks between start and now as long as less than 2^32 ticks have passed.