David VanHorn wrote: > You're gonna have to get friendly with interrupts. And was chastised; and fought back. Fact is; there are three ways to do this and all work well. Top level: Use timer interrupts. The interrupt decrements one or more counters, re-initialising it/ them if necessary. For greatest flexibility, counter time-outs are used to set a flag and the IRQ routine does no more, but the main ("background") loop in its own good time looks at the flag(, resets it) and decides what to do with it. Presuming this loop is actually quite fast, minor variations in the time taken to look at the flag will cause no perceptible display flicker. For a multiplexed display, one counter can be used to initiate stepping from one digit to the next, and another to implement flashing. Mid-level: Use timer overflow. This method and the last can be and have for a long time been used on PICs with no interrupts. The main loop passes through the various tasks, and one such task is to check for timer overflow. When this occurs, it is processed exactly as described for an interrupt above. Both these timer-based methods are facilitated by the timer prescaler, making the timer "tick" correspond as closely as possible to the minimum period desired between events (such as a display multiplex step). This minimises the time spent updating the counters compared to all the other processing. Low-level: Use isosynchronous coding. This can be done on most processors, even without a timer function. Isosynchronous code is written so that each section of the program takes the same number of clock cycles no matter what branches are taken. This means that an "IF - THEN" section is implemented as an "IF - THEN - ELSE" where the "ELSE" contains a delay to make it equal to the "THEN" in execution time. The PIC actually makes this easy for small decisions involving a single operation as the "Skip" instructions take two cycles whether the skip is taken or not. Longer decision sequences are coded as: .. where the second part code must be exactly one cycle longer in execution than the first (both encounter a GOTO, but the first part is delayed one cycle in skipping the first GOTO). The flow of execution is now such that functions which must be fastest are executed in tighter loops. The loop counter for these becomes the "clock". Because these procedures may not branch out or call one another to execute consequential functions, they must instead set flags to each other or to "outer" routines (State Machine operation). The multiplex stepping is timed by a certain number of executions of "inner" loops and is itself an isosynchronous process. Part of the display routine reads the "blink" flag and zeroes the display data if required, but the display is written in the same amount of time either way. A loop counter outside this then toggles the "blink" flag, and another counter outside this again can be used to count seconds, minutes, hours etc. to keep clock time. I don't recommend trying *this* in "C" however! The execution time of each of these loop routines is not important in itself as long as the loop always makes the same number of iterations and the time of these in cycles can be tallied. Does all of this make sense, Andre? Cheers, Paul B.