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