;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
domenica 6 giugno 2010
domenica 8 febbraio 2009
domenica 20 maggio 2007
Oddio, rispondermi da solo non è mica tanto bello, ma insomma!
Credo di avere intanto capito cosa è un post: è una e-mail senza indirizzo ed affidata al vento. Non sarebbe mica male se così fosse, no? Mi rivolgerò allora a una mia collega d'italiano.
Cara T. cosa possiamo inventare di nuovo per gli studenti di quinta dell'anno scolastico a venire? Questo ti chiedi, vero? Anni fa riuscii un giorno a interessare i miei studenti di quinta a una lezione di elettronica.
Tornavo in classe, dal laboratorio, seguito dai miei studenti di fine corso e percorrevo il lungo corridoio del piano rialzato, a un certo punto esclamai:
-Io solo contro tutti.-
Dopo di che mi gettai contro i miei circa venti studenti spingendo con gran forza come se volessi rovesciarli tutti a terra. Assurdo, no?, dato che le nuove generazioni sono più alte della mia e io non sono un colosso. Già, certo, solo che i pazzi il ciel li aiuta e infatti.
Come è e come non è persuasi praticamente di botto i miei studenti che o si davano da fare oppure, ad uno ad uno, sarei forse riuscito a stenderli per terra. Così quelli reagirono sul serio e nel giro di forse neanche tre secondi mi ritrovai sommerso sotto alcuni quintali di carne viva urlante e scalpitante. La preside, chissà come, sentì (forse era già fuori dal suo ufficio), si affacciò dalla balaustra, sovrastante la scala che porta al primo piano, e urlò dabbasso, rivolta agli studenti:
-Cosa fate per terra in corridoio? Chi è il vostro professore?-
E quelli pronti, ma veramente pronti e ben convinti, vale a dire con la dovuta dose di senso di colpa apparente:
-Scusi, ha ragione. Il nostro professore è M. e sta in classe.-
-E allora raggiungetelo, suvvia! Non si fa confusione in corridoio durante le lezioni!-
Già, sì. Quelli si rialzarono e si avviarono verso la classe e io gattonai in mezzo a loro in modo da non farmi vedere da nessun'altro, tranne che dagli studenti che avevo intorno. Sto infatti parlando del 1983 ed ero ancora giovane e scattante.
Raggiungemmo la nostra aula con loro che fecero attenzione a fare sì che io non venissi visto neppure dalla bidella davanti alla quale passammo e che stazionava a metà del corridoio. Naturalmente, però, una volta raggiunto l'interno della classe e chiusa la porta scoppiammo a ridere in maniera talmente fragorose da farci udire sia in corridoio e sia nelle aule attigue, ma tanto a noi non importava più niente di come sarebbe potuta finire la faccenda. Sì, perché avevamo intanto appreso qualcosa d'importante: probabilmente ci volevamo bene stupidamente, ma pure reciprocamente e questo fatto, assieme alla circostanza imprevista ed al bisogno di decidere in fretta sul da farsi, ci aveva aperto gli occhi su chi eravamo e su che cosa dovevamo forse imparare a difendere meglio che potevamo anche a costo di fare fatica o di assumerci dei rischi.
Ci sentimmo insomma cresciuti, e non di poco, quasi grandi, direi, e quindi, una volta tanto l'avere lavorato assieme a scuola ci aveva ripagato facendoci imparare una nozione importante. Già, sì, oramai sapevamo perché io avrei continuare a darmi da fare, per portare loro verso la soddisfazione di una promozione, e anche perché, dal canto loro, avrebbero a volte cercato di ricavare una gradevole sensazione di benessere impegnandosi a scuola e magari anche dopo, nella vita reale. Sì, perché per loro sarebbe stato probabilmente importante anche da grandi essere compatibili con le aspettative delle persone fra le quali avrebbero vissuto.
Che scemi, vero? O invece sbaglio? Chissà.
Se caspita sapessi cosa è un post, allora potrei fare sicuramente di meglio. Però tentiamo.
Non ci credo. Da sempre avrei voluto parlare solo per dire quel che mi passa per la testa e non per infastidire questo o quello, e penso che in un blog questo lo potrò fare. In special modo sapendo che difficilmente qualcuno visiterà queste pagine.
Oddio, dovrò non bestemmiare, nemmeno solo per vedere quali sensazioni ricaverei dal farlo. E devo evitare di fare apologia di reato, non devo quindi osannare né il terrorismo né il suicidio. Ma di tutto il resto potrò parlare liberamente, no? Troppo bello, non credi?
Bah, vediamo cosa succede cliccando "salva adesso".
Iscriviti a:
Post (Atom)

