I currently have a circuit which displays a count on 4 7-segment displays. Push the up button, count increments, push the down count decreases. I'm trying to add functionality so that a tap of the button counts once, but holding the button causes fast counting.
The press and hold works just fine, but the "tap" causes multiple counts (as if it were not debounced at all). By adjusting Delay and Rate I can get it to "count too much, a little less" but it's still not the clean tap = 1 count, hold = lots a count I am looking for. I've tried adding delays in the macro and in my program loop to no avail. Any ideas?
PIC running at 32.768 KHZ, so I know thats part of the issue with only an 8 bit counter, but isn't there a way to make this bad boy work with a delay somewhere?
The code I have found (that almost works) is as follows:
Button Port, Pin, Downstate, Delay, Rate, Variable, Targetstate, Address Where: Port, Pin - the Button Pin (ie "PORTA, 0") and can be defined with a "#define" Statement Downstate - The State When the Button is Pressed Delay - The number of iterations of the Macro code before the "address" is jumped to (to 127). If Set to 0, then Jump if "targetstate" met without any debouncing. If Bit 7 of "Delay" is set, then no auto-repeats Rate - After the Initial jump to "address", the number of cycles (to
127) before autorepeating. Targetstate - The state ("1" or "0") to respond to. Address - The Address to Jump to when the Button is pressed or Auto-repeatsThe Macro itself probably looks quite complex at first glance:
Button macro Port, Pin, Downstate, Delay, Rate, Variable, Targetstate, Address local ButtonEnd incf Variable, w ; Increment the Counter Variable if ((Downstate == 0) && (Targetstate == 0))||((Downstate == 1) && (Targetstate == 1)) btfsc Port, Pin ; If Low, then Valid Pin else btfss Port, Pin ; If High, then Valid Pin endif clrw ; Not Pressed, Clear the Counter movwf Variable ; Save the Counter Value movlw Delay & 0x07F subwf Variable, w ; Button Debounced? btfsc STATUS, Z goto Address ; If Equal, then "Yes" if ((Delay & 0x080) != 0) ; Is Autorepeat used? btfsc STATUS, C decf Variable ; No - Decrement if > "Delay" else btfss STATUS, C goto ButtonEnd ; Less than Expected - End xorlw Rate ; At the Autorepeat Point yet? btfsc STATUS, Z goto ButtonEnd ; No - Keep Incrementing movlw Delay ; Yes, Reset back to the Original Count and Repeat movwf Variable goto Address endif ButtonEnd ; Macro Finished endm