Created
March 30, 2022 21:01
-
-
Save ajarmst/e59847a2ee87883a314a0584802a2729 to your computer and use it in GitHub Desktop.
Debounce and Edge Detection code from the demo.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Return the current state of all 5 switches | |
byte SWL_GetSwitches(void) { | |
// return switch state, masked. | |
return PT1AD1 & 0x1F; //0b0001 1111 | |
} | |
//Return the current state of all 5 switches | |
//but a 1 requires that switch was high both at | |
//the call and after argument miLliseconds. | |
//Uses timer, assumes it is set up. | |
byte SWL_GetSwitchesDelay(byte ms) { | |
// return switch state, masked. | |
byte state = SWL_GetSwitches(); //initial read | |
//Wait for argument ms; | |
TMR_Sleep(ms); | |
return SWL_GetSwitches() & state; //Only switches that are 1 at beginning and after ms | |
} | |
//Return a byte with bits set only if a leading edge (up then down) | |
byte SWL_GetSwitchesEdge() | |
{ | |
//We need to track state. Could use a global variable, but best of both worlds | |
//if we use a static state tracker. | |
static byte lastState = 0; // What were the buttons last time? | |
byte retnState = 0; //Store my return value | |
byte currState = SWL_GetSwitchesDelay(10); // 10 ms debounce | |
//Want a one in the return state iff it was 0 and is now a 1. | |
//Easy peasy with bitwise ops: | |
retnState = ~lastState & currState; | |
//update state | |
lastState = currState; | |
//return results | |
return retnState; | |
} | |
///////////////////////////////////////////////////////////////////////////// | |
// Main Entry | |
///////////////////////////////////////////////////////////////////////////// | |
void main(void) | |
{ | |
// Variables | |
uint counter = 0; | |
// main entry point | |
_DISABLE_COP(); | |
EnableInterrupts; | |
///////////////////////////////////////////////////////////////////////////// | |
// one-time initializations | |
///////////////////////////////////////////////////////////////////////////// | |
PLL_To20MHz(); | |
SWL_Init(); | |
TMR_Init(eTMR_Prescale_128, 0, 0, eTMR_Pin_Toggle); | |
SEG_Init(); | |
///////////////////////////////////////////////////////////////////////////// | |
// main program loop | |
///////////////////////////////////////////////////////////////////////////// | |
SWL_ToggleLEDs(eRed | eYellow | eGreen); | |
TMR_Sleep(1000); | |
// clear pending flag (may or may not be set) | |
TFLG1 = 1; | |
// arm for event, now + 100ms | |
TC0 = (uint)(TCNT + 15625); // 15625; | |
// done! timer is armed to go off on chan0 100ms from now! | |
for (;;) | |
{ | |
// wait for TC0 event. Throttling my main to not run faster than 10 hz | |
while (!TFLG1_C0F) // this bit goes to 1 when flag triggers | |
; // Remember that while requires a semi | |
// clear pending OC0 flag (so the while loop above resets) | |
TFLG1 = 1; | |
// rearm for another 100ms | |
TC0 = TC0 + 15625; | |
// This routine Returns buttons as 1 iff debounced leading edge (button down) | |
// As set up, ignores cases where more than one button transitioned in slice | |
switch (SWL_GetSwitchesEdge()) | |
{ | |
case eMiddle: | |
counter = 0; | |
break; | |
case eLeft: | |
counter--; | |
break; | |
case eRight: | |
counter++; | |
break; | |
case eUp: | |
break; | |
case eDown: | |
break; | |
default: // do nothing | |
break; | |
} | |
// Use LEDs to display 3 lsb on count | |
SWL_SetLEDs((counter % 8)<<5); | |
// If there's a non-zero count; throw it to 7 segs: | |
if(counter) | |
SEG_16D(counter,0); | |
else | |
SEG_ClearAll(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment