Push buttons
Buttons are mechanical devices used to execute a break or make connection between two points. They come in different sizes and with different purposes. Buttons that are used here are also called "dip-buttons". They are soldered directly onto a printed board and are common in electronics. They have four pins (two for each contact) which give them mechanical stability.
Example of connecting buttons to microcontroller pins
Button function is simple. When we push a button, two contacts are joined together and connection is made. Still, it isn't all that simple. The problem lies in the nature of voltage as an electrical dimension, and in the imperfection of mechanical contacts. That is to say, before contact is made or cut off, there is a short time period when vibration (oscillation) can occur as a result of unevenness of mechanical contacts, or as a result of the different speed in pushing a button (this depends on person who pushes the button). The term given to this phenomena is called SWITCH (CONTACT) DEBOUNCE. If this is overlooked when program is written, an error can occur, or the program can produce more than one output pulse for a single button push. In order to avoid this, we can introduce a small delay when we detect the closing of a contact. This will ensure that the push of a button is interpreted as a single pulse. The debounce delay is produced in software and the length of the delay depends on the button, and the purpose of the button. The problem can be partially solved by adding a capacitor across the button, but a well-designed program is a much-better answer. The program can be adjusted until false detection is completely eliminated. Image below shows what actually happens when button is pushed.
As buttons are very common element in electronics, it would be smart to have a macro for detecting the button is pushed. Macro will be called button. Button has several parameters that deserve additional explanation.
button macro port, pin, hilo,
label
Port is a microcontroller's port to which a button is connected. In case of a PIC16F84 microcontroller, it can be PORTA or PORTB.
Pin is port's pin to which the button is connected.
HiLo can be '0' or '1' which represents
the state when the button is pushed.
Label is a destination address for jump to a service subprogram
which will handle the event (button pushed).
BUTTON MACRO PORT,PIN,HILO,LABEL
LOCAL PUSHEDL ;A11 labels used are local
LOCAL PUSHED2
LOCAL EXITL
LOCAL EXIT2
IFNDEF DEBOUNCEDELAY ;This enables to define a debounce
#DEFINE DEBOUNCEDELAY .10 ;delay in the main program
ENDIF
IF HILO==0 ;pull-up
IFBIT PORT,PIN,EXIT1 ;If one, button is not pushed
PAUSEMS DEBOUNCEDELAY ;10ms deb ounce delay
PUSHEDL
IFNOTBIT PORT,PIN,PUSHEDL
PAUSEMS DEBOUNCEDELAY ;Wait until released and
GOTO LABEL ;then jump to a specified label
EXIT1
ELSE ;pull-down
IFNOTBIT PORT,PIN,EXIT2 ;If zero, button is not pushed
PAUSEMS DEBOUNCEDELAY ;10ms deb ounce delay
PUSHED2
IFBIT PORT,PIN,PUSHED2
PAUSEMS DEBOUNCEDELAY ;Wait until released and
GOTO LABEL ;then jump to a specified label
EXIT2
ENDIF
ENDM
Example 1:
button PORTA, 3, 1, Button1
Button T1 is connected to pin RA3 and to the mass across a pull-down resistor, so it generates logical one upon push. When the button is released, program jumps to the label Button1.
Example 2:
button PORTA, 2, 0, Button2
Button T1 is connected to pin RA1 and to the mass across a pull-up resistor, so it generates logical zero upon push. When the button is released, program jumps to the label Button2.
The following example illustrates use of macro button in a program. Buttons are connected to the supply across pull-up resistors and connect to the mass when pushed. Variable cnt is displayed on port B LEDs; cnt is incremented by pushing the button RA0, and is decremented by pushing the button RA1.
PROCESSOR 16f84
#INCLUDE "P16F84. INC"
__CONFIG _CP_0FF & _WDT_0FF & _PWRTE_0N & _XT_0SC
CBLOCK 0X0C ;RAM starting address
HICNT
LOCNT
LOOPCNT
CNT
ENDC
ORG 0X00 ;Reset vector
GOTO MAIN
ORG 0x04 ;Interrupt vector
GOTO MAIN ;no interrupt routine
INCLUDE "ROMUX_LIB.INC"
INCLUDE "BUTTON.INC"
MAIN ;Main program
INPUT PORTA,0
INPUT PORTA,0
BANKSEL TRISB
CLRF TRISB
BANKSEL PORTS
CLRF CNT
LOOP
BUTTON PORTA,0,0,DECREASE
BUTTON PORTA,1,0,INCREASE
GOTO LOOP
INCREASE
INCF CNT,F
MOVF CNT,W
MOVWF PORTB
GOTO LOOP
DECREASE
DECF CNT,F
MOVF CNT,W
MOVWF PORTB
GOTO LOOP
END
It is important to note that this kind of debouncing has certain drawbacks, mainly concerning the idle periods of microcontroller. Namely, microcontroller is in the state of waiting from the moment the button is pushed until it is released, which can be a very long time period in certain applications. if you want the program to be attending to a number of things at the same time, different approach should be used from the start. Solution is to use the interrupt routine for each push of a button, which will occur periodically with pause adequate to compensate for repeated pushes of button.
The idea is simple. Every 10ms, button state will be checked upon and compared to the previous input state. This comparison can detect rising or falling edge of the signal. In case that states are same, there were apparently no changes. In case of change from 0 to a 1, rising edge occurred. If succeeding 3 or 4 checks yield the same result (logical one), we can be positive that the button is pushed.
User Comments
No Posts found !Login to Post a Comment.