DETECTING SWITCHES


One of the first things you have to do in any project is interface the outside to the microcontroller.
This includes things like LEDs, switches, piezos and microphones.
In the CODE PUZZLE project, two switches are placed on a single input. By adding a capacitor and resistors to each switch, we can detect if no-switch, either switch or both switches have been pressed.
This is done in software by discharging the capacitor and looking at the time it takes to charge via one of the resistors.

The circuit diagram is needed to see the component values:

The input line is looked at on a regular basis and since most of the time is taken up with delays in the switch routine, the chance of detecting the wrong switch will be small.
The sub-routine "Sw" discharges the capacitor via the 470R and the switch can be pressed at any during this part of the cycle and have no effect on the outcome.
If either switch is pressed after about 20% of the start of the next part of the cycle, no switch will be recognised, so the window for an incorrect reading does not exist.
If a switch is pressed at the wrong time, it will be picked up during the next cycle.
Once the 100n has been discharged, the detecting line is changed to an input and after a delay which is 20% longer than 100n takes to charge, a reading is made. If the line is HIGH, switch A has been pressed. A further reading is taken 20% after the time taken for switch B to charge the capacitor. The micro comes out of the sub-routine with one of three results.
If "A" is pressed, a LED blinks at 1Hz,  If "B" is pressed the LED blinks at 0.3Hz.
 


;PIC12F629.asm
;CODE PUZZLE - Detects buttons A and B


list p=12F629

include "p12f629.inc"

__CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;Internal osc.


; globals

fileA   equ   26h
fileB   equ   27h
fileC   equ   28h
fileD   equ   29h
fileE   equ   2Ah

;bits

rp0               equ    5


status         equ    03h
option_reg   equ    81h


Start    org 0x00            ;program starts at location 000
           nop
           nop
           nop
           nop                    ;NOPs to get past reset vector address
           nop
           nop


SetUp   bsf         status,rp0            ;Bank 1
            movlw    b'10000110'          ;Turn off T0CKI, prescaler for TMR0 = 1:128
            movwf    option_reg
            bcf        status,rp0             ;bank 0
            movlw    07h                      ;Set up W to turn off Comparator ports
            movwf    CMCON               ;must be placed in bank 0
            clrf         GPIO                  ;Clear GPIO of junk
            goto       Main


LED0    bsf        status,rp0            ;Bank 1
            movlw    b'00111111'         ;make all input
            movwf    TRISIO                ;turn off all LEDs
            bcf        status,rp0            ;bank 0
            retlw      00


LED1    bsf          status,rp0          ;Bank 1
            movlw     b'00111001'         ;make GP1,2 output
            movwf     TRISIO               ;enable outputs
            bcf          status,rp0          ;bank 0
            movlw     02h                    ;make GP1 HIGH, GP2 LOW
            movwf     GPIO                 ;turn on LED1
            retlw       00

                                                ;Delay 0.5 sec

Del_1     movlw    02h
             movwf    fileC
DelX      decfsz    fileA,1            ; ,1 denotes the result of the decrement
             goto       DelX
             decfsz    fileB,1             ; is placed in the file
             goto       DelX
             decfsz    fileC,1
             goto       DelX
             retlw      00

                   ;test program to detect switch A and switch B and tell them apart!!


Switch   bsf      status,rp0        ;Bank 1
             bcf      TRISIO,0          ;make GP0 output
             bcf      status,rp0        ;bank 0
             bcf      GPIO,0            ;make switch-line LOW
Sw1      decfsz  fileA,1             ; short delay while 100n discharges
            goto     Sw1
            bsf       status,rp0        ;Bank 1
            bsf       TRISIO,0         ;make GP0 input
            bcf       status,rp0        ;bank 0
            movlw   02
            movwf   fileB
Sw2      movlw   0A0h
            movwf   fileA
Sw3     decfsz   fileA,1               ; delay while 100n charges via switch
           goto      Sw3
           decfsz   fileB,1
           goto      Sw2
           btfsc     GPIO,0              ;is switch-line HIGH?
           retlw     01                      ;yes - switch A pressed
Sw4     decfsz  fileA,1                ; delay while 100n charges via switch
           goto      Sw4
           btfsc     GPIO,0              ;is switch-line HIGH?
           retlw     02                     ;yes - switch B pressed
           retlw     00                     ;no



Main    call       Switch               ;see if button A is pressed
           movwf   fileD                   ;put result of switch into file D
           btfss     fileD,0                ;see if Sw A is pressed
           goto      Main2
           call       LED1                  ;turn on LED 1
           call       Del_1
           call       LED0                 ;turn off LED 1
           call       Del_1
           goto     Main
Main2  btfss     fileD,1                ;see if Sw B is pressed
           goto     Main
           call      LED1                  ;turn on LED 1
           call      Del_1
           call      Del_1
           call      Del_1
           call      LED0                   ;turn off LED 1
           call      Del_1
           call      Del_1
           call      Del_1
           goto     Main


                                  ;Results: B is just at the point of detection
                                  ; with 2 x fileB and fileA = 0FFh.
                                  ; Use 1 x fileB and fileA = 0FFh
                                  ;Button A is not detected with fileA less than D0h
                                  ;and 1 x fileB
                                  ;Use 2 x fileB and fileA = 0Ah


end
 



 
28/8/07