3.3.2.3 Explanations

The key to the previous code is the loop. Let take a look at the initialization, the loop itself, and its results.

db_or = 0x00;
db_and = 0xff;

This initializes the two variables we track in the loop. db_or is a cumulative bitwise-or ``sum'' (disjunction is somewhat analogous to addition in boolean algebra). The reason why each bit is initialized to 0 is simple: if any bit is initialized to 1, it will always be a 1, making the loop useless!

Likewise, db_and is a cumulative bitwise-and ``product''. All bits in this variable are initialized to 1 because if any were initialized to 0, it will always remain 0.

for (i = 0; i < db_n; ++i)
  {
    db_or |= db_buffer[i];
    db_and &= db_buffer[i];
  }

In the loop, both db_or and db_and are getting updated by the elements of db_buffer. Recall that db_buffer is a history of previous states of a port.

Let us think for a second here, not that I think you are starting to zone out. After the loop exits, how do we interpret each of the following?

Here is the answer.

Isn't this fantastic? Afterall, we were looking for consistent samples for the entire history buffer!

db_state |= (db_and);
  db_state &= (db_or);

Marks the end of this logic. db_state is the ``debounced state''. Each bit in this variable represents a filtered state of the corresponding pin of the port. If a pin has consistently read 1 for the whole history, it is safe to update db_state and make the corresponding bit a 1. This is done by a bitwise-or with db_and.

Similarly, if a pin has consistently read 0 for the whole history, it is safe to update db_state and make the corresponding bit a 0. This is done by a bitwise-and with db_or.

Q.E.D., quod erat demonstrandum (which was to be demonstrated, or in plain English, end of proof).

Copyright © 2006-02-15 by Tak Auyeung