Steve Smith wrote: > > Below is a section of code that reads 32 inputs into an '84 via hc244's I > wass origanally having trouble with bouncy switches but after adding Scott's > debounce chunk it wont work at all can sombody please help this is causing > lots of grey hairs and a severly short temper. DTA is port_b and the > information is saved in four consecutive registers. Sorry Steve if I caused your hair to gray prematurely. Mike hit the head right on the nail by pointing out the trashing of your temporary registers GP1-GP3. A little history: Mike is quite accurate in stating that it's sufficient to sample the inputs at a rate slower than the bouncing time interval to debounce a switch. However there are instances where you wish to find a very quick response in a perhaps noisy enviroment. Consider the application for which a variation of this routine was created: scanning relays. At one of my previous jobs we had to design a system that was capable of monitoring large banks of relays in a electrically noise enviroment. Furthermore, it was necessary to ascertain the relays' change of states to within 1ms resolution. This was part of a Sequence-Of-Events (SOE) subsystem of a data acquistion system. The original system debounced with an 8 sample window and also time-tagged the change of states. (It also ran on an NPMC = Non-Pic Micro Controller). There are good and bad features with my debounce routine. good: It's fast. The filtered or debounced state is always available. It can handle eight inputs in parallel. bad: Three permanent memory locations and one temporary memory location are required for each group of eight inputs. It's hard to understand. So for Steve's (and perhaps a few others') sake here is part of the solution: cblock START_OF_RAM ;change for your processor current_state0_7, clock_A0_7, clock_B0_7 current_state8_15, clock_A8_15, clock_B8_15 current_state16_23, clock_A16_23, clock_B16_23 current_state24_31, clock_A24_31, clock_B24_31 GP1 endc ;Macro-ize the debounce routine: macro DE_BOUNCE csa,cva,count_A,count_B ;Increment the vertical counter MOVF count_B,W XORWF count_A,F COMF count_B,F ;See if any changes occurred MOVF csa,W XORWF cva,W ;Reset the counter if no change has occurred ANDWF count_B,F ANDWF count_A,F ;Determine the counter's state MOVF count_B,W IORWF count_A,W ;Clear all bits that are filtered-or more accurately, save ;the state of those that are being filtered ANDWF cva,F XORLW 0xff ;Re-write the bits that haven't changed. ANDWF csa,W IORWF cva,F endm READ_1 ifdef read_ports_directly MOVLW CONTROL_TO_SELECT_0_7 MOVWF CON DE_BOUNCE current_state0_7,PORT_B,clock_A0_7,clock_B0_7 MOVLW CONTROL_TO_SELECT_8_15 MOVWF CON DE_BOUNCE current_state8_15,PORT_B,clock_A8_15,clock_B8_15 MOVLW CONTROL_TO_SELECT_16_23 MOVWF CON DE_BOUNCE current_state16_23,PORT_B,clock_A16_23,clock_B16_23 MOVLW CONTROL_TO_SELECT_24_31 MOVWF CON DE_BOUNCE current_state24_31,PORT_B,clock_A24_31,clock_B24_31 else ;The macro invocations can be rearranged to minimize the skew ;in which the data is read if that is important. The added cost ;would be three extra temporary memory registers. MOVLW CONTROL_TO_SELECT_0_7 MOVWF CON MOVFW PORTB MOVWF GP1 DE_BOUNCE current_state0_7,GP1,clock_A0_7,clock_B0_7 MOVLW CONTROL_TO_SELECT_8_15 MOVWF CON MOVFW PORTB MOVWF GP1 DE_BOUNCE current_state8_15,GP1,clock_A8_15,clock_B8_15 MOVLW CONTROL_TO_SELECT_16_23 MOVWF CON MOVFW PORTB MOVWF GP1 DE_BOUNCE current_state16_23,GP1,clock_A16_23,clock_B16_23 MOVLW CONTROL_TO_SELECT_24_31 MOVWF CON MOVFW PORTB MOVWF GP1 DE_BOUNCE current_state24_31,GP1,clock_A24_31,clock_B24_31 endif RETLW 0 Unfortunately, this is not tested... So let's hope that after his hair has turned all gray that Steve doesn't have to resort to pulling it out too. Scott -- __o I buy pizza instead of gas. \< (*)/(*) PS Steve, if you wish to continue with the discussion off-line then e-mail me directly.