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
|