;cronometro per gare di atletica
;26/05/08
;PIC16F648A
;clock 4 MHz INTOSC (oscillatore interno)
;
;stand-by: led rosso acceso
;
;RadioStart: riconoscimento con comparatori interni
;
;crono run: base dei tempi 1 millisecondo, no interrupt
; flash 0.5Hz su led verde
;
;crono stop: fotocellula
;
;crono reset: reset di sistema (pulsante)
;
;display LCD: formato h:mm:ss:dcm
; overflow a 2:00:00:000 (2 ore)
; risoluzione 1 millisecondo
;definizioni sfr
status equ 03h
trisa equ 85h
trisb equ 86h
porta equ 05h
portb equ 06h
cmcon equ 01fh
;definizione gpr
millesimi equ 20h
centesimi equ 21h
decimi equ 22h
secondi equ 23h
decsec equ 24h
min equ 25h
decmin equ 26h
ore equ 27h
ContaMicro equ 28h
millis equ 29h
org 2ah
tmpLcdRegister res 2
msDelayCounter res 2
;Linee di controllo dell'LCD
LCD_RS equ 2 ;Register Select
LCD_E equ 3 ;Lcd Enable
;LCD data line bus
LCD_DB4 equ 4 ;LCD data line DB4
LCD_DB5 equ 5 ;LCD data line DB5
LCD_DB6 equ 6 ;LCD data line DB6
LCD_DB7 equ 7 ;LCD data line DB7
;macro per LCD
SET_EN MACRO
bsf PORTB,LCD_E
ENDM
CLEAR_EN MACRO
bcf PORTB,LCD_E
ENDM
EN_STROBE MACRO
SET_EN
nop
CLEAR_EN
ENDM
errorlevel 2
org 0
;direzione pin: ra0, ra1, ra2 in input
; rb0, rb1 in output
resetta bsf status,5
bsf trisa,0 ;ra0 in input
bsf trisa,1 ;ra1 in input
bsf trisa,2 ;ra2 in input
clrf trisb
bcf status,5
;inizializzazione modulo comparatori
;comparatori connnessi con: RA2 = Vin+ in comune
; RA0 = Vin- comp1
; RA1 = Vin- comp2
movlw 03h
movwf cmcon
;inizializza variabili cronometro a zero
clrf millesimi
clrf centesimi
clrf decimi
clrf secondi
clrf decsec
clrf min
clrf decmin
clrf ore
;Inizializza il display LCD
call LcdInit
;Posiziona il cursore dell'LCD in posizione 0,0
movlw 0x00
call LcdLocate
;LCD, visualizza zero (reset)
call visualizzatempo
;entra stand-by: accendi rosso, spegni verde
bcf portb,1
bsf portb,0 ;rosso
;attesa di un radiostart
RxStart btfss cmcon,6 ;RxStart>VS1(3.1V)?
goto RxStart ;no, attendi per...
;radiostart rilevato, misura il semip. alto
treno1000Hz clrf ContaMicro
contaalto incf ContaMicro
btfsc cmcon,7 ;RxStart<VS2(1.9V)?
goto contaalto ;no, misura semip. alto
;semip. alto misurato, verifica se 1000 o 1500Hz
movlw .100
subwf ContaMicro
btfss status,0
goto cronostart ;è 1500, vai a gestire cronometro
;è 1000Hz,misura il semip. basso
clrf ContaMicro
contabasso incf ContaMicro
btfss cmcon,6 ;RxStart>VS1(3.1V)?
goto contabasso ;no, misura semip. basso
;semip. basso misurato, verifica se 1000 o 1500Hz
movlw .100
subwf ContaMicro
btfss status,0
goto cronostart ;è 1500, vai a gestire cronometro
goto treno1000Hz ;è 1000, ricomincia da capo
;CRONOSTART: precarica cronometro con 1 secondo
cronostart bsf secondi,0
;fine stand-by, modo RUN
bsf portb,1 ;modo RUN, accendi verde
bcf portb,0
;chiama base dei tempi da 1 millisecondo
cronorun call millisecondo
;polling fotocellula STOP
btfss porta,3
goto cronostop
;conta millesimi in bcd n.i.
incf millesimi
movlw .10
subwf millesimi,0
btfss status,2
goto cronorun
clrf millesimi
;conta centesimi in bcd n.i.
incf centesimi
movlw .10
subwf centesimi,0
btfss status,2
goto cronorun
clrf centesimi
;conta decimi in bcd n.i.
incf decimi
movlw .10
subwf decimi,0
btfss status,2
goto cronorun
clrf decimi
;conta secondi in BCD n.i.
incf secondi
;flash 0.5Hz su led verde
btfss secondi,0
goto spegni
bsf portb,1
goto BCD_sec
spegni bcf portb,1
BCD_sec movlw .10
subwf secondi,0
btfss status,2
goto cronorun
clrf secondi
;conta decsec in bcd n.i.
incf decsec
movlw .6
subwf decsec,0
btfss status,2
goto cronorun
clrf decsec
;conta minuti in bcd n.i.
incf min
movlw .10
subwf min,0
btfss status,2
goto cronorun
clrf min
;conta decmin in bcd n.i.
incf decmin
movlw .6
subwf decmin,0
btfss status,2
goto cronorun
clrf decmin
;conta ore in bcd n.i.
incf ore
movlw .2
subwf ore,0
btfss status,2
goto cronorun
clrf ore
;OVERFLOW, resetta il sistema
goto resetta
;STOP CRONOMETRO FOTOCELLULA
cronostop bsf portb,0 ;STAND-BY, accendi rosso
bcf portb,1
;Posiziona il cursore dell'LCD in posizione 0,0
movlw 0x00
call LcdLocate
;visualizza tempo finale su LCD
;converti variabili cronometro da BCD n.i. in ASCII --> LCD
call visualizzatempo
;loop infinito, attesa per un reset
loop goto loop
;FINE MAIN, inizio procedure
;routine millisecondo
millisecondo movlw .246
movwf millis
nop
nop
ciclo1 nop
decfsz millis
goto ciclo1
return
;*****************************************************************************
INCLUDE "P16F84.INC"
;procedura conversione BCD n.i. in ASCII e stampa tempo su LCD
visualizzatempo movfw ore
addlw 30h
call LcdSendData
movlw ':'
call LcdSendData
movfw decmin
addlw 30h
call LcdSendData
movfw min
addlw 30h
call LcdSendData
movlw ':'
call LcdSendData
movfw decsec
addlw 30h
call LcdSendData
movfw secondi
addlw 30h
call LcdSendData
movlw ':'
call LcdSendData
movfw decimi
addlw 30h
call LcdSendData
movfw centesimi
addlw 30h
call LcdSendData
movfw millesimi
addlw 30h
call LcdSendData
return
;**********************************************************************
; Routine di ritardo
;
; W = Ritardo richiesto in ms (con quarzo a 4MHz)
;**********************************************************************
msDelay
movwf msDelayCounter+1
clrf msDelayCounter+0
; Loop interno da circa 1 ms
msDelayLoop
nop
decfsz msDelayCounter+0
goto msDelayLoop
nop
decfsz msDelayCounter+1
goto msDelayLoop
return
;**********************************************************************
; Inizializza il display LCD
; Questa funzione deve essere chiamata prima di ogni altra funzione
; di gestione dell'LCD
;**********************************************************************
LcdInit
bcf portb,LCD_E ;Disabilita l'LCD
bcf portb,LCD_RS ;Mette l'LCD in modo comando
movlw 250
call msDelay
movlw 250
call msDelay
movlw 250
call msDelay
movlw 250
call msDelay
; Invia all'LCD la sequenza di reset
bsf portb,LCD_DB4
bsf portb,LCD_DB5
bcf portb,LCD_DB6
bcf portb,LCD_DB7
EN_STROBE
movlw 2
call msDelay
EN_STROBE
movlw 2
call msDelay
EN_STROBE
movlw 2
call msDelay
;--------------------------------
bcf portb,LCD_DB4
bsf portb,LCD_DB5
bcf portb,LCD_DB6
bcf portb,LCD_DB7
EN_STROBE
movlw 2
call msDelay
;Configura il bus dati a 4 bit
movlw 0x28
call LcdSendCommand
;Entry mode set, increment, no shift
movlw 0x06
call LcdSendCommand
;Display ON, Curson OFF, Blink OFF
movlw 0x0E
call LcdSendCommand
movlw 0x01
call LcdSendCommand
return
;**********************************************************************
; Clear LCD
;**********************************************************************
LcdClear
movlw 0x01
call LcdSendCommand
movlw 2
call msDelay
;DD RAM address set 1st digit
movlw 0x80
call LcdSendCommand
return
;**********************************************************************
; Locate cursor on LCD
; W = D7-D4 row, D3-D0 col
;**********************************************************************
LcdLocate
movwf tmpLcdRegister+0
movlw 0x80
movwf tmpLcdRegister+1
movf tmpLcdRegister+0,0
andlw 0x0F
iorwf tmpLcdRegister+1
btfsc tmpLcdRegister+0,4
bsf tmpLcdRegister+1,6
movf tmpLcdRegister+1,0
call LcdSendCommand
return
;**********************************************************************
; Send a data to LCD
;**********************************************************************
LcdSendData
bsf portb,LCD_RS
call LcdSendByte
return
;**********************************************************************
; Send a command to LCD
;**********************************************************************
LcdSendCommand
bcf portb,LCD_RS
call LcdSendByte
return
;**********************************************************************
; Send a byte to LCD by 4 bit data bus
;**********************************************************************
LcdSendByte
;Save value to send
movwf tmpLcdRegister
;Invia i quattro bit piu' significativi
bcf portb,LCD_DB4
bcf portb,LCD_DB5
bcf portb,LCD_DB6
bcf portb,LCD_DB7
btfsc tmpLcdRegister,4
bsf portb,LCD_DB4
btfsc tmpLcdRegister,5
bsf portb,LCD_DB5
btfsc tmpLcdRegister,6
bsf portb,LCD_DB6
btfsc tmpLcdRegister,7
bsf portb,LCD_DB7
EN_STROBE
movlw 2
call msDelay
;Send lower four bits
bcf portb,LCD_DB4
bcf portb,LCD_DB5
bcf portb,LCD_DB6
bcf portb,LCD_DB7
btfsc tmpLcdRegister,0
bsf portb,LCD_DB4
btfsc tmpLcdRegister,1
bsf portb,LCD_DB5
btfsc tmpLcdRegister,2
bsf portb,LCD_DB6
btfsc tmpLcdRegister,3
bsf portb,LCD_DB7
EN_STROBE
movlw 2
call msDelay
return
END
Iscriviti a:
Commenti sul post (Atom)

Nessun commento:
Posta un commento