; ; *************************************************************************** ; *** Bubble Software Parallax to PIC Source Converter. Copyright 1999. *** ; *** http://www.picnpoke.com email: sales@picnpoke.com *** ; *************************************************************************** ; ; BUTTON pin, port, state, delay, repeat_rate ; This routine debounces input from a pushbutton and jumps to an ; "action" routine. The pin (0-7), port (0-2 for RA through RC), ; action state of the input (0,1) are all specified at run time. ; The delay and repeat rate are constants. ; Device data and reset vector P = pic16c55 #include <16c55.inc> ; processor assembler definitions _CONFIG _xt_osc & _wdt_off & _protect_off reset start org 8 dbH Res d'1' ; MSB of 16-bit debounce counter. dbL Res d'1' ; LSB of 16-bit debounce counter. pin Res d'1' ; Pin no. (0-7). port Res d'1' ; Port no. (0-2). flags Res d'1' ; Bit flags for use by Button: state equ flags.3 ; Do action when button is in this state. rpt_sw equ flags.2 ; Repeat switch: 0=off; 1=on. old equ flags.1 ; Previous state of button. new equ flags.0 ; Current state of button. ; You can tune the constants assigned to delay, repeat, and upval below by ; substituting different numbers for 150, 10, and 255. The "^0FFh" inverts ; the values to simplify the program code by allowing loops to count up ; instead of down. If ^0FFh is removed, delays will be smaller when the ; numbers are larger. delay equ d'150'^0FFh ; Delay before autrepeat. repeat equ d'10' ^0FFh ; Delay between repeats. upval equ d'255'^0FFh ; Debounce for button-up. org 0 ; Table to convert numbers 0-7 into bytes with a 1 in the corresponding ; bit position. For example, 3 converts to 00001000b. Pinz ADDWF pcl RETLW d'1' RETLW d'2' RETLW d'4' RETLW d'8' RETLW d'16' RETLW d'32' RETLW d'64' RETLW d'128' start MOVLW d'0' ; Make RB output to drive LEDs. TRIS 6h MOVLW d'15' ; Make RA input for button. TRIS 5h CLRF 6h ; Turn off LEDs. CLRF flags ; Clear the bit flags. CLRF dbL ; Clear the debounce counter. CLRF 0xdb BSF flags,d'3' ; Set up for active-high (1=pushed) BSF flags,d'2' ; Turn on autorepeat. BSF flags,d'1' ; Initialize old state of button. MOVLW d'2' ; Read button on pin 2 MOVWF pin MOVLW d'0' ; of port RA. MOVWF port CALL btn_init ; Initialize button variables. ; This illustrates how button is used--the routine is called from a main ; loop that may or may not contain other instructions. The more instructions ; inside the loop, the smaller the button delay and repeat values should be. start_loop CALL button GOTO start_loop ; Since Button is called frequently from within a main program loop, it makes ; sense to move code that only needs to be executed once into a separate ; initialization routine. btn_init MOVF pin,w ; Look up pin value in table and CALL Pinz ; store it for use by Button. MOVWF pin MOVLW 5h ; Add offset to point to I/O ports. ADDWF port RETLW 0h Button MOVF port,w ; Point to the port. MOVWF fsr MOVF indirect,w ; Move port bits into w. BTFSS flags,d'3' ; IF state=0 THEN w = NOT(port bits). COMF indirect,w ANDWF pin,w ; IF w AND pin THEN new = 1 BTFSS status,z ; ELSE new = 0 (0 means button "on") BCF flags,d'0' BTFSC status,z BSF flags,d'0' MOVLW d'3' ; Move 0000011b to w to mask bits ANDWF flags,w ; other than old and new. ADDWF pcl ; Jump based on state of bits old, new. GOTO Button_held ; old = 0, new = 0 - button held down. GOTO Button_release ; old = 0, new = 1 - button just released. GOTO Button_push ; old = 1, new = 0 - button just pushed. GOTO Button_up ; old = 1, new = 1 - button left up. Button_push BCF flags,d'1' ; Copy new button state to old. MOVF dbL ; If dbL is not 0, then the last button-up BTFSS status,z ; period was short--probably a bounce-- RETLW 0h ; so don't do theAction. Else, load delay MOVLW delay ; and jump to theAction. MOVWF 0xdb GOTO theAction Button_held INCFSZ dbL ; Increment 16-bit db variable until it RETLW 0h ; reaches 0. When it does, reload it with INCFSZ 0xdb ; the repeat delay , and, if the repeat RETLW 0h ; switch is on, do theAction. If repeat MOVLW repeat ; switch is off, skip theAction and return. MOVWF 0xdb BTFSC flags,d'2' GOTO theAction RETLW 0h Button_release MOVLW upval ; Button released: put upval into MOVWF dbL BSF flags,d'1' ; dbL and copy new state to old. This RETLW 0h ; sets up the button-up debounce in :up. Button_up MOVF dbL,1 ; Increment dbL until it equals 0. BTFSS status,z ; Since :push won't do theAction unless INCF dBL ; dbL=0, this debounces button release. RETLW 0h ; This is the code activated by Button. Note that it ends with ret in order to get ; back to the code that called Button in the first place. theAction MOVLW d'255' XORWF 6h RETLW 0h end