Skip to content

Instantly share code, notes, and snippets.

@ajarmst
Created March 30, 2022 21:01
Show Gist options
  • Save ajarmst/e59847a2ee87883a314a0584802a2729 to your computer and use it in GitHub Desktop.
Save ajarmst/e59847a2ee87883a314a0584802a2729 to your computer and use it in GitHub Desktop.
Debounce and Edge Detection code from the demo.
//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