📄 buttons.asm
字号:
;Subroutine to detect state changes and debounce push buttons connected;to a port of an 8052 type microprocessor. Operates with up to 7 buttons,;which must all be on the same port.;This subroutine may be freely distributed and used. If it proves useful,;an email to dave_fletcher@bigfoot.com would be appreciated.;The subroutine is provided "as is" and no liability is accepted by the;author for any losses incurred due to its incorporation in any application.;David Fletcher, April 1999;Example of how to use:-; PUSH #0 ;Dummy byte to reserve a space on the stack; LCALL DEBOUNCE; POP DEBOUNCED_BUTTONS;The programmer needs to provide definitions for the values of:-;; BUTTON_MASK This is an 8 bit mask for reading the port; to which the push buttons are connected. For; each button, the corresponding bit must be; set to 1. Every other bit must be a 0.;; BUTTON_SAME This should have a single bit set to 1, with; all of the other 7 bits 0. It does not matter; which bit is the 1, so long as it is not the; same bit as any of the 1s in BUTTON_MASK. The; debounce subroutine uses the BUTTON_SAME value; to tell the calling routine that the state of; the push buttons has not changed.;;The programmer may also need to change the number of the port on line 80;The subroutine was designed to be called from the main loop of a real;time application. The author's original application is a radio time;code (Rugby MSF) synchronised digital clock.;;It is called during every pass through the main loop, and returns the;BUTTON_SAME value if none of the buttons has been pressed or released.;If a button has been pressed or released, a debounce timer is started;which decrements each time the subroutine is called with the buttons;in the same state as the last time. Until the timer reaches zero, the;subroutine keeps returning BUTTON_SAME at each call.;;When the debounce counter reaches zero, the subroutine returns the new;state of the push buttons. DSEGDB_COUNT: DS 1 ;Debounce timer. Counts how many times ;the push buttons have been in the same ;stateDB_PREV_STATE: DS 1 ;Previous state of the buttons CSEGDEBOUNCE: PUSH ACC ;Save all registers used by the routine MOV A, R0 PUSH ACC MOV A, R1 PUSH ACC PUSH B MOV R0, SP ;Set up a pointer to the return parameter on the stack DEC R0 ;which after the register saves is now six levels down DEC R0 DEC R0 DEC R0 DEC R0 DEC R0 ;R0 now points to the return parameter MOV A, P3 ;Sample the button state CPL A ;Buttons are active low ANL A, #BUTTON_MASK ;and delete non-button bits MOV R1, A ;Save a copy XRL A, DB_PREV_STATE ;Test to see if the buttons have ;changed since last time JZ DB_NO_CHANGE MOV DB_PREV_STATE, R1 ;If they have changed, MOV DB_COUNT, #100 ;restart the debounce count MOV R1, #BUTTON_SAME ;and tell the calling routine ;nothing has changed.... yet SJMP DB_DONEDB_NO_CHANGE: MOV A, DB_COUNT ;Test the debounce count JNZ DB_WAIT ;If it is not zero, go wait for ;it to count down MOV R1, #BUTTON_SAME ;If it is already zero, the calling ;routine had the button data last time SJMP DB_DONEDB_WAIT: MOV R1, #BUTTON_SAME ;Load this in case the count does not ;expire this time DJNZ DB_COUNT, DB_DONE ;Decrement and test the debounce count MOV A, DB_PREV_STATE ;If it has expired, get the current ;button state, MOV R1, A ;and pass it back to the calling ;routineDB_DONE: ;Put the return value in the stack MOV A, R1 MOV @R0, A POP B ;Restore the machine to the way it was found POP ACC MOV R1, A POP ACC MOV R0, A POP ACC RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -