.title "COMANDOLED" .vers "ST62E20" ; Funziona su qualsiasi ST6Qui viene solo definito il nome e il tipo di micro usato.
.input "st62reg.inc"Definizione di tutti i registri interni del micro tramite un file esterno chiamato st62reg.inc (vedi pagina esempi).
copia_b .def 084h ;COPIA DEL REGISTRO DATI PORTA BViene usata solo una variabile chiamata copia_b che corrisponde alla cella di memoria RAM con indirizzo 084h. Questa variabile serve per comandare correttamente le uscite senza usare le istruzioni SET e RES direttamente sui registri delle porte (port_b).
.org 0880h inizio ldi wdog,0ffh ; RICARICA IL WATCH DOG ldi pdir_a,00000000b ;PA0 E' UN INGRESSO PULL-UP ldi popt_a,00000000b ;LE LINEE NON USATE SONO INGRESSI ldi port_a,00000000b ldi pdir_b,00000001b ;PB0 E' UN'USCITA PUSH-PULL ldi popt_b,00000001b ldi port_b,00000000b ldi pdir_c,00000000b ;NON USATA ldi popt_c,00000000b ldi port_c,00000000b ldi adcr,0 ;DISABLE A/D INTERRUPT ldi tscr,0 ;DISABLE TIMER INTERRUPT ldi ior,0 ;DISABLE ALL INTERRUPT reti ;RIPRISTINA I FLAG PRINCIPALI jp main ;SALTA AL PROGRAMMA PRINCIPALEImposta le porte di I/O (PA0 ingresso e PB0 uscita) e disabilita tutti gli interrupt.
ad_int ;INTERRUPT DEL CONVERTITORE A/D reti tim_int ;INTERRUPT DEL TIMER reti BC_int ;INTERRUPT DELLE PORTE A e B reti A_int ;INTERRUPT DELLA PORTA A reti nmi_int ;INTERRUPT NON MASCHERABILE retiQuesto programma non usa alcun interrupt, per cui le routine di interrupt non sono presenti.
led jrr 0,port_a,ledon ; se PA0=0 allora tasto premuto ; salta a ledon e accendi led ledoff res 0,copia_b ; resetta bit 0 di copia_b ld a,copia_b ; trasferisce copia_b in A ld port_b,a ; trasferisce A in port_b ; e comanda led jp fine ; esce dalla routine ledon set 0,copia_b ; setta bit 0 di copia_b ld a,copia_b ; trasferisce copia_b in A ld port_b,a ; trasferisce A in port_b ; e comanda led fine ret ; esce dalla routineQuesta e' la subroutine pricipale che effettua tutte le funzioni del programma. Analizziamo ora le singole righe di questa routine.
ledQuesta e' l'etichetta che indentifica l'inizio della routine.
jrr 0,port_a,ledon ; se PA0=0 allora tasto premuto ; salta a ledon e accendi ledL'istruzione jrr (jump relative if reset) controlla lo stato della linea PA0 cioe' del BIT 0 del registo port_a e salta all'etichetta "ledon" solo se questo bit e' 0, cioe' se PA0 e' a massa. Questa condizione corrisponde alla pressione del tasto. Se invece il tasto non e' premuto e quindi PA0 e' a livello 1 questa istruzione non compie nessuna azione e quindi il programma prosegue con la prossima riga (etichetta "ledoff").
ledoff res 0,copia_b ; resetta bit 0 di copia_b ld a,copia_b ; trasferisce copia_b in A ld port_b,a ; trasferisce A in port_b ; e comanda led jp fine ; esce dalla routineQueste righe servono per spegnere il led. La prima riga resetta, cioe' pone a livello logico 0 il bit 0 (LSB) della variabile "copia_b" che come sappiamo e' la copia del registro port_b.
ledon set 0,copia_b ; setta bit 0 di copia_b ld a,copia_b ; trasferisce copia_b in A ld port_b,a ; trasferisce A in port_b ; e comanda ledQueste istruzioni sono identiche a quelle commentate qui sopra. L'unica cosa che cambia e' la prima riga dove c'e' una istruzione "set" al posto dell'istruzione "res". Questa istruzione pone a livello logico 1 il bit 0 della variabile copia_b. Le successive 2 rige come sappiamo servono per trasferire il contenuto della variabile copia_b nel registro della porta b (port_b) andando in questo caso ad accendere il LED. Notate che non si possono sostituire le ultime 2 righe con una singola istruzione del tipo:
ld port_b,copia_b ; trasferisce copia_b in port_b ; e comanda ledIn teoria potrebbe funzionare, ma in realta' questo e' un grave errore, perche' il trasferimento di dati tra variabili deve avvenire sempre passando per l'accumulatore A. Assemblando una istruzione di questo tipo l'assemblatore segnala un errore.
fine ret ; esce dalla routineL'istruzione "ret" permette di uscire dalla subroutine "led" e di tornare al programma principale, cioe' al punto in cui questa subroutine e' stata richiamata tramite il comando "call".
main ;IDENTIFICA L'INIZIO DEL PROGRAMMA PRINCIPALE ldi wdog,0feh ;RICARICA IL WATCH DOG call led ; RICHIAMA SUBROUTINE LED jp main ; ripete a ciclo continuoIl programma principale in questo caso e' semplicissimo, in quanto tutte le funzioni del programma si trovano nella subroutine appena vista.
.org 0ff0h jp ad_int ;INTERRUPT DEL CONV. A/D vector #4 jp tim_int ;INTERRUPT DEL TIMER vector #3 jp BC_int ;INTERRUPT PORTE A e B vector #2 jp A_int ;INTERRUPT PORTA A vector #1 .org 0ffch jp nmi_int ;INTERRUPT NON MASCHERABILE vector #0 jp inizio ;INTERRUZIONE PER IL SETTAGGIO INIZIALEQueste sono righe standard per i micro ST621x e 2x e non vanno mai modificate.
.end ; Termine del programmaQuesta riga indentifica la fine del programma.
© Giuseppe Di Paolo '98
Aggiornato giovedě 6 agosto 1998