domenica 6 giugno 2010

Progr x PIC - Telestart lato arrivo

;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 20 maggio 2007

Odio il romanticismo?

No, non lo odio per niente, anzi l'adoro.

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".