Button

debounces input from a switch and jumps to a routine, optionally performing an autorepeat function if the switch is held down.

Mechanical contacts bounce, producing several milliseconds of on/off noise before they settle into a new position. This is a problem for controllers, because it can be hard to distinguish between a valid switch press and contact bounce.

Many applications can get by without debouncing a switch input, if they read the switch infrequently, or if the switch triggers a fairly long event. But switches that are used to scroll through a range of values or toggle an action definitely require debouncing. To use Button, your program must set the bit state equal to the state of the button when activated, set or clear rpt_sw to turn autorepeat on or off, put the desired pin and port into variables of the same names, and call btn_init. Then include call Button in the main program loop. Button will debounce the switch and jump to the routine named theAction when the switch is activated.

Unlike PBASIC's Button, this version does not permit changes to the delay and repeat values while the program is running. If you wish, you may use variables instead of constants to change these on the fly.

This Button routine also does not directly support multiple buttons, but can be modified to do so. The bit flags for a second button could be stored in the upper four bits of flags. A separate 16-bit db variable, accessed by a pointer, would also be necessary.

Demonstrating Button.

To see Button in operation, either run the program with the PSIM simulator, or connect the circuit below to an erasable PIC or PIC emulator, such as the Parallax downloader. Assemble and run BUTTON.SRC. When you press the switch, the LED will blink. Hold the switch down and, after a brief delay, the LED will blink rapidly.


;
; ***************************************************************************
; *** Bubble Software Parallax to PIC Source Converter. Copyright 1999. ***
; *** http://www.bubblesoftonline.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 


; 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. 
 org 8
dbH ds 1 ; MSB of 16-bit debounce counter. 
dbL ds 1 ; LSB of 16-bit debounce counter. 
pin ds 1 ; Pin no. (0-7). 
port ds 1 ; Port no. (0-2). 
flags ds 1 ; Bit flags for use by Button:
state = flags.3 ; Do action when button is in this state. 
rpt_sw = flags.2 ; Repeat switch: 0=off; 1=on. 
old = flags.1 ; Previous state of button. 
new = 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 = 150 ^0FFh ; Delay before autrepeat.
repeat = 10 ^0FFh ; Delay between repeats.
upval = 255 ^0FFh ; Debounce for button-up.
; Device data and reset vector
 device pic16c55,xt_osc,wdt_off,protect_off
 reset start
 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 jmp pc+w
 retw 1,2,4,8,16,32,64,128
start mov !rb, #0 ; Make RB output to drive LEDs. 
 mov !ra, #15 ; Make RA input for button. 
 clr rb ; Turn off LEDs. 
 clr flags ; Clear the bit flags. 
 clr dbL ; Clear the debounce counter. 
 clr dbH
 setb state ; Set up for active-high (1=pushed)
 setb rpt_sw ; Turn on autorepeat. 
 setb old ; Initialize old state of button. 
 mov pin,#2 ; Read button on pin 2
 mov port,#0 ; of port RA. 
 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. 
:loop call button
 goto :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 mov w,pin ; Look up pin value in table and
 call Pinz ; store it for use by Button. 
 mov pin,w
 ADD port,#ra ; Add offset to point to I/O ports. 
 ret
Button mov fsr,port ; Point to the port. 
 mov w,indirect ; Move port bits into w. 
 sb state ; IF state=0 THEN w = NOT(port bits).
 mov w,/indirect 
 AND w,pin ; IF w AND pin THEN new = 1
 movb new,z ; ELSE new = 0 (0 means button "on")
 mov w,#3 ; Move 0000011b to w to mask bits 
 AND w,flags ; other than old and new. 
 jmp pc+w ; Jump based on state of bits old, new. 
 jmp :held ; old = 0, new = 0 - button held down. 
 jmp :release ; old = 0, new = 1 - button just released. 
 jmp :push ; old = 1, new = 0 - button just pushed. 
 jmp :up ; old = 1, new = 1 - button left up. 
:push clrb old ; Copy new button state to old. 
 test dbL ; If dbL is not 0, then the last button-up
 sz ; period was short--probably a bounce--
 ret ; so don't do theAction. Else, load delay
 mov dbH,#delay ; and jump to theAction. 
 jmp theAction
:held incsz dbL ; Increment 16-bit db variable until it
 ret ; reaches 0. When it does, reload it with
 incsz dbH ; the repeat delay , and, if the repeat
 ret ; switch is on, do theAction. If repeat
 mov dbH,#repeat ; switch is off, skip theAction and return. 
 snb rpt_sw 
 jmp theAction
 ret
:release mov dbL,#upval ; Button released: put upval into
 setb old ; dbL and copy new state to old. This
 ret ; sets up the button-up debounce in :up. 
:up test dbL ; Increment dbL until it equals 0. 
 sz ; Since :push won't do theAction unless
 inc dBL ; dbL=0, this debounces button release. 
 ret 
; 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 XOR rb,#255
 ret

See also:


file: /Techref/microchip/seepicsrc/psbpix/button.htm, 18KB, , updated: 2010年11月1日 11:29, local time: 2025年9月3日 09:19,
40.74.122.252:LOG IN

©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://massmind.org/techref/microchip/seepicsrc/psbpix/button.htm"> The PIC Source Book - button</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here:
if you want a response, please enter your email address:
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

Welcome to massmind.org!

Welcome to massmind.org!

.

AltStyle によって変換されたページ (->オリジナル) /