Programma di esempio LED1

Viene qui descritto un semplicissimo programma che permette di accendere un LED collegato alla porta PB0 del micro quando viene premuto un pulsante collegato alla porta PA0 del micro.

Prelevate qui il programma di esempio

Descrizione del programma

Analizziamo le parti principali del programma TESTLED1
	.title  "COMANDOLED"

	.vers   "ST62E20"       ; Funziona su qualsiasi ST6
Qui 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 B
Viene 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 PRINCIPALE
Imposta 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
	reti
Questo 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 routine
Questa e' la subroutine pricipale che effettua tutte le funzioni del programma. Analizziamo ora le singole righe di questa routine.
led
Questa 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 led
L'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 routine
Queste 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.
La seconda riga trasferisce il contenuto della variabile "copia_b" nell'accumulatore A del micro usando l'istruzione ld (load).
La successiva istruzione "ld" trasferisce il contenuto dell'accumulatore (che e' uguale a copia_b) nel registro dati della porta b (port_b) andando quindi a spegnere il led collegato a PB0.
L'istruzione "jp" serve per saltare direttamente all'etichetta "fine" per cui il micro non eseguira' le istruzioni contenute nelle righe successive, ma saltera' direttamente all'etichetta specificata.
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
Queste 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 led
In 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 routine
L'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 continuo
Il programma principale in questo caso e' semplicissimo, in quanto tutte le funzioni del programma si trovano nella subroutine appena vista.
La prima riga ricarica il WATCH DOG. Si tratta di un timer particolare che serve per resettare il micro nel caso in cui il programma si blocca per qualche disturbo esterno. Questa riga deve essree inserita frequentemente all'interno del programma per evitare un reset indesiderato del micro. In pratica e' consigliabile metterla ogni 20-30 istruzioni del programma.
La riga successiva come sappiamo serve a richiamare la subroutine "led". In corrispondenza di questa istruzione il micro salta all'etichetta "led" ed esegue tutte le istruzioni della subroutine.
Quando all'interno della subroutine il micro trova l'istruzione "ret", ritorna al programma principale eseguendo l'istruzione successiva a "call".
In questo caso l'istruzione successiva e' "jp main" che salta nuovamente all'etichetta main e riesegue tutto il ciclo in modo continuo.


.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 INIZIALE
Queste sono righe standard per i micro ST621x e 2x e non vanno mai modificate.

	.end                    ; Termine del programma
Questa riga indentifica la fine del programma.


© Giuseppe Di Paolo '98
Aggiornato giovedě 6 agosto 1998