;giokino.asm
;Stefano Salvi - 17/8/02
;
;Questo programma e' un gioco che aumenta il punteggio nei led gialli ogni volta
;che si preme
;il pulsante e e' contemporaneamente acceso l'ultimo led rosso. Quando vinco
;lampeggiano tutti i led per 3 volte.
;Imposto la porta di controllo con la porta a e c bassa di output e c alta di
;input.
;inizializzo un contatore e guardo se quando premo il tasto il mio contatore e' a
;p1 e allora faccio illuminare 3 volte i led e intanto faccio incrementare il
;contatore giallo.
;
; I LED rossi sono connessi alla porta A del PPI.
; I LED gialli sono connessi alla porta C 0..3 del PPI
; I Bottoni verdi sono connessi alla porta C 4..7 del PPI
; Il port A del PPI e' all'indirizzo 0FA00H nella memoria XDATA.
; Il port C del PPI e' all'indirizzo 0FA02H nella memoria XDATA.
; Il port di Controllo del PPI e' all'indirizzo 0FA03H nella memoria XDATA.
; La programmazione del PPI sara' la seguente:
; 1xxx xxxx Programmo port
; x00x xxxx Port A -> modo 0
; xxx0 xxxx Port A -> output
; xxxx 1xxx Port C Hi -> input
; xxxx x0xx Port B -> modo 0
; xxxx xx1x Port B -> input
; xxxx xxx0 Port C Lo -> output
; ---------
; 1000 0010
;
.org 8050h
; Definisco alcune costanti utili:
.equ PPIPORTA, 0FA00h ; Port A del PPI
.equ PPIPORTC, 0FA02h ; Port C del PPI
.equ PPICTL, 0FA03h ; Port di controllo del PPI
.equ novince, 0 ; Variabile BIT che indica stato vecchio tasto
sjmp main ; salta le subroutine e va al programma principale
;----------------------- routine di ritardo ------------------------------------
; Ritardo di circa 0,2 secondi
; Con il quarzo a 1059200 Hz, l'8051 esegue 921600 cicli al secondo
; Se voglio 5 lampeggi al secondo, devo avere un ritardo di 184320 cicli.
; Ipotizzando di avere un' 'operazione base' di 4 cicli, 240 ripetizioni di
; questa operazione porteranno ad impiegare 240*4 = 960 cicli totali.
; Se ora ripeteremo qesto ritardo base per 192 volte, otterremo 960*192=184320
; cicli int otale (non contando i 4 cicli aggiuntivi per ripetere il ritardo
; base, pari a 192*4=768)
; Ingresso:
; nessuno
; Uscita:
; nessuna
; Usa:
; r0,r1
delay:
mov R1,#192 ; 192 ripetizioni di un ritardo base
lp2: ; Ciclo Esterno
mov R0,#240 ; 200 ripetizioni di piccolo ritardo (2 nop)
lp3: ; Ciclo Interno
nop ; operazione nulla - circa un micorsecondo (uS)
djnz R0,lp3 ; Ripete 'nop' (ci mette circa altri 2 uS)
djnz R1,lp2 ; ripete il ritardo precedente (200 * 3 -> 600 uS)
;
ret
;---------------------------------------------------------------------------
; main program
;---------------------------------------------------------------------------
main:
;----------------------inizializzazioni----------------------------------------
mov sp,#8Fh ; Imposta lo stack per la chiamata a 'delay'
; Programmo port, Port A -> modo 0, Port A -> output, Port C Hi -> input,
; Port B -> modo 0, Port B -> input, Port C Lo -> output
mov a,#10001010b ;imposto porta di controllo
mov dptr,#PPICTL
movx @dptr,a
mov a,#1111b ;imposta porta led gialli-verdi
mov dptr,#PPIPORTC
movx @dptr,a
mov r2,#01111111b ; Configurazione dei LED - 0 -> Acceso, 1 -> Spento
mov dptr,#PPIPORTA ; Porta LED rossi
mov a,r2 ; recupera configurazione LED
movx @dptr,a ; La invia ai LED
mov r5,#0 ; Contatore Punteggi
;
mainlp:
;
; Attende il ritardo necessario ed aggiorna la configurazione dei LED
;
acall delay ; chiama routine di ritardo
;
; Elaborazione alla fine, prima di cambiare visualizzazione
;
; Test del tasto di 'reset Gioco'
;
mov dptr,#PPIPORTC ; bit 4-7 -> tasti
movx a,@dptr ; Legge porta
jnb acc.6,main ; Settimo tasto premuto -> reset gioco
;
;
;----------------------------------------------------------------------------
; Il tasto deve essere premuto quando l'ultimo LED rosso e' acceso.
; Per evitare che, tenendo il tasto premuto, si vinca, quando e' acceso il
; penultimo LED rosso, controllo che il tasto sia rialsciato.
; Solo se il tasto era rilasciato, trovandolo premuto con l'ultimo LED, conto il punto
;
cjne r2,#11111101b,testLed7
;
; E' acceso il penultimo LED:
; Se il tasto e' gia' premuto, setta il FLAG
;
mov dptr,#PPIPORTC ; porta pulsanti
movx a,@dptr ; legge il pulsante
clr novince ; azzera il 'flag'
jb acc.7,fineMain ; bit7=1 -> pulsante rialsciato
setb novince ; pulsante gia premuto -> setto flag
sjmp fineMain ; prosegue
;
testLed7:
cjne r2,#11111110b,fineMain
;
; E' acceso l'ultimo LED
;
jb novince,fineMain; pulsante premuto da prima: risultato non valido
mov dptr,#PPIPORTC ; porta pulsanti
movx a,@dptr ; legge il pulsante
jb acc.7,fineMain ; Pulsante del gioco non premuto, nessun punto
;
; pulsante premuto -> vincita!!
;
inc r5 ; contatore vittorie
mov dptr,#PPIPORTC ; Port LED gialli
mov a,r5 ; copia la configurazione
anl a,#0fh ; Elimina i bit in eccesso (4 LED)
cpl a ; Inverte configurazione (0 -> Acceso, 1 -> spento)
movx @dptr,a ; Manda sui LED
mov dptr,#PPIPORTA ; porta led rossi
mov a,#00000000
mov r3,#6 ; sei inversioni -> tre lampeggi
vinciloop:
movx @dptr,a ; manda codice sui LED
acall delay ; Pausa per visualizzare i LED
cpl a ; cambia da acceso (0) a spento (1) o viceversa tutti i LED
djnz r3,vinciloop
;
; Fine codice vincita
;
fineMain:
;
; Calcola la nuova configurazione e la visualizza
;
mov dptr,#PPIPORTA ; porta led rossi
mov a,r2 ; configurazione memorizzata
rr a ; Ruota la configurazione (Bit 0 va in Bit 7)
movx @dptr,a ; la manda sui LED
mov r2,a ; Rimette nel registro la configurazione aggiornata
;
sjmp mainlp ; loop
.end
|