I'd like to supplement Charles' fine example with an interrupt driven version of the "parallel switch state logic" example I posted earlier.
This example uses a 1-msec timer driven interrupt "heart beat" which is perfect for toggling a piezo speaker at 500-Hz and it uses a simple counter to produce a 32-msec debounce/sample interval.
Using a momentary switch to emulate a "toggle" switch (press to toggle from on-to-off or from off-to-on) can be accomplished directly by the driver by exclusive-or'ing the debounced "new press" bits with the "flags" switch flag bits variable. Main should test the switch flag bit and then clear it for "momentary" switches or simply test the switch flag bit for an emulated "toggle" switch.
Code:
void interrupt() // 1-msec Timer 2 interrupts
{
pir1.TMR2IF = 0; // clear TMR2 interrupt flag
//
// beep task (32-msec 500-Hz tone using 1-msec interrupts)
//
if(beep) // if beep task running
{ spkrpin ^= 1; // toggle speaker pin and
beep--; // decrement beep msec counter
}
//
// switch state management (multi-switch "parallel" logic)
//
if(--dbcount == 0) // if 32-msec debounce interval
{ dbcount = 32; // reset debounce timer and
swnew = ~porta; // sample active low switches
swnew &= 0x0F; // on RA3..RA0 pins
swnew ^= swold; // changes, press or release
swold ^= swnew; // update switch state latch
swnew &= swold; // filter out "new release" bits
flags ^= swnew; // toggle flag bits for 'main'
if(swnew) // if any "new press" bits
beep = 32; // task a "new press" beep
}
}
Code:
// in "main"
while(flags.0) // while sw0 (RA0) "on" (toggle), do this block
{ // until new sw0 press toggles flags.0 to "off"
if(flags.1) // if sw1 (RA1) "new press" (momentary)
{ flags.1 = 0; // turn off flag and
... // do something
}
}
Bookmarks