3.3.2.2 The Implementation

The implementation of debouncing varies from very clumsy hard coding, to flexible schemes that is easy to extend.

At the core of a flexible scheme, we need to maintain a circular queue to track the previous $n$ readings. Let us assume the const int db_n represents this $n$. We can write a quick-and-dirty subroutine to maintain the circular queue:

void db_tick(void)
{
  const int db_n = 5; // or whatever
  static unsigned char db_buffer[db_n] = { 
    0xff,0xff,0xff,0xff,0xff };
  static int db_cursor = 0;

  db_buf[db_cursor] = PINA;
  if (++db_cursor >= db_n) db_cursor -= db_n;
}

I called this quick-and-dirty because a circular queue should have been implemented as a struct with associated functions to initialize and maintain its state.

Every time we call db_tick, it reads from the input pins, and update the circular buffer. However, it does not track the debounced states of each pin. We can add to the function to do this:

void db_tick(void)
{
  const int db_n = 5; // or whatever
  static unsigned char db_buffer[db_n] = { 
    0xff,0xff,0xff,0xff,0xff };
  static int db_cursor = 0;
  static unsigned char db_state = 0xff; // default state
  unsigned char db_and, db_or;
  int i;

  db_buf[db_cursor] = PINA;
  if (++db_cursor >= db_n) db_cursor -= db_n;
  db_or = 0x00;
  db_and = 0xff;
  for (i = 0; i < db_n; ++i)
  {
    db_or |= db_buffer[i];
    db_and &= db_buffer[i];
  }

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

}



Copyright © 2006-02-15 by Tak Auyeung