|
|
In queste pagine verranno fornite alcune informazioni base utili per
chi vuole iniziare a programmare i micro ST6, ma non sa da dove cominicare....
Verrà descritto come va impostato un programma, come vanno scritte le
istruzioni e verranno descritti alcuni semplicissimi programmi di esempio.
Questo sicuramente non e' sufficiente... ci vuole anche tanta pazienza e tanta
pratica, ma quella dovete metterla voi....
Impostare un programma
Formato delle istruzioni 232b18c
Assemblare un programma
Set di istruzioni dei micro ST6
Un piccolo programma di esempio (comando LED)
In questo capitolo verra' descritto dettagliatamente il programma START. Questo programma e' un esempio tipico di come va impostato un programma per micro ST6. L'esempio si riferisce ai micro ST621x e 2x, ma e' valido anche per altri modelli.
Tutte queste righe sono dei COMMENTI, perche' iniziano con il segno di punto e virgola ; e quindi verranno ignorate dall'assemblatore. E' molto utile inserire questi commenti in tutte le parti del programma, per descrivere il funzionamento delle singole parti e anche delle singole istruzioni. In questo caso, all'inizio del programma viene inserito il titolo, l'autore e una breve descrizione. E' utilissimo anche descrivere qui le connessioni delle porte di I/O del micro, le varie modifiche e aggiunte apportare durante lo sviluppo del programma e tutte le informazioni che ritenete utili per rendere piu' facile una comprensione e una lettura del programma anche a distanza di tempo.
Le direttive .title e .vers permettono di specificare il titolo del programma e la vesione di micro da usare. In questa parte di programma si possono inserire anche altre direttive come ad esempio .w_on per usare la DRW. Notate che la scritta "TIPO DI MICROPROCESSORE USATO" e' un commento perche' e' preceduto dal punto e virgola.
Qui vengono definiti tutti i registri interni del micro che sono indispensabili in qualsiasi programma. Poiche' i registri sono sempre uguali per qualsiasi programma, sono stati definiti all'interno di un altro file chiamato st62reg.inc che viene incluso nel nostro programma tramite la direttiva .input. Per i micro ST626x c'e' un altro file chiamato invece st626reg.inc. Questi files possono essere prelevati nella pagina degli esempi, oppure alla pagina https://www.geocities.com/SiliconValley/Way/7521/st6/files/st62reg.zip
Le variabili sono delle celle di memoria RAM contenenti i dati che vengono elaborati e manipolati all'interno del programma. In questo esempio la variabile "prova" corrisponde alla cella di memoria RAM con indirizzo 084h. Non si possono usare due variabili con lo stesso nome.
La direttiva .org specifica l'indirizzo di partenza del programma all'interno della ROM/EPROM del micro a va modificata a seconda della dimensione della memoria del micro usato. Quando il micro ST6 viene resettato o viene alimentato, il programma salta automaticamente all'etichetta "inizio" per cui le successive istruzioni servono ad inizializzare il microprocessore. Vengono definite le configurazioni delle porte di I/O in funzione dell'uso che poi dovrete farne all'interno del programma. Andate alla pagina "Porte di I/O" per maggiori informazioni. Le successive istruzioni servono a disabilitare tutti gli interrupt. L'istruzione "jp main" serve poi per saltare al programma principale.
Quando si verifica un interrupt durante l'esecuzione del programma, il micro salta ad una di queste subroutine in funzione del tipo di interrupt. Notate che tutte queste subroutine devono terminare con l'istruzione "reti".
Le subroutine sono dei pezzi di programma che vengono richiamati dal programma principale o da altre subroutine tramite l'istruzione "call". Tutte le subroutine devono sempre iniziare con una etichetta (esempio "clock") e terminare con l'istruzione "ret". E' bene suddidere tutto il programma in subroutine, ognuna con una specifica funzione, in modo da rendere piu' facile la lettura e la correzione del programma e permettendo di riutilizzare alcune parti del programma anche in altre future applicazioni. Inoltre e' consigliabile inserire all'interno delle subroutine delle parti di programma che devono essere richiamate frequentemente durante il funzionamento in modo da non riscrivere piu' volte le stesse istruzioni.
Questo e' il programma principale che deve iniziare sempre con l'etichetta "main".
Queste istruzioni vanno inserire alla fine del programma MAIN per definire tutti i vettori di interrupt. In pratica queste righe specificano a quali etichette il micro deve saltare in corrispondenza di un interrupt. Notate la presenza dell'etichetta "inizio" che corrisponde al vettore di RESET (quando il micro viene resettato o alimentato salta a "inizio").
La direttiva .end specifica la fine del programma, per cui questa e' sempre l'ultima riga da inserire.
Alcune note su come va scritta una tipica riga di un programma per micro ST6.
Esempio di una riga con etichetta e commento:
In questa riga:
pippo e' l'etichetta
ldi e' l'istruzione
wdog,0ffh e' l'operando
; RICARICA IL WATCH DOG e' il commento Se la
riga non ha etichetta, e' necessario comunque lasciare lo spazio vuoto usando
il tasto TAB:
L'etichetta puo' anche essere scritta da sola, senza nessuna istruzione:
I programmi scritti per i micro ST6
vengono salvati su disco in files di testo con estensione .ASM. Questi
programmi non possono essere inseriti direttamente nel micro, in quanto è
necessario ASSEMBLARLI, cioè trasformarli in un file .HEX contentente tutte le
istruzioni in formato esadecimale che possono essere lette dal programmatore e
inserite nella memoria programma dell'ST6.
Per questa conversione, è necessario usare un programma fornito dalla ST che si
chiama AST6.EXE, funzionante sotto DOS.
Se abbiamo un file CLOCK.ASM contentente il nostro programma, per assemblarlo è sufficiente aprire una finestra di MS-DOS e scrivere:
AST6 CLOCK.ASMSe il programma non contiene errori, l'AST6 crea il files CLOCK.HEX da inserire nel micro. Ovviamente in questo esempio è sottointeso che ci troviamo nella directory in cui è presente il file AST6.EXE e che il programma CLOCK.ASM si trovi nella stessa directory. Inoltre viene automaticamente creato anche un file CLOCK.DSD, contenente le informazioni di debug che vengono usate durante l'eventuale simulazione del programma. Se l'assemblatore non trova errori e completa l'operazione, ci visualizza questo messaggio:
ST6 MACRO-ASSEMBLER version 4.20 - September 1994Altrimenti, in caso di errore, ci segnala il tipo di errore e la riga del programma in cui si trova:
ST6 MACRO-ASSEMBLER version 4.20 - September 1994In questo esempio c'è errore di overflow su una istruzione di salto alla riga 155.
In realtà l'AST6 è un programma potente che dispone di molte altre funzioni attivabili sempre dalla linea di comando. Riprendendo come esempio il file CLOCK.ASM, ecco un elenco delle funzioni disponibili con una breve descrizione:
AST6 -L CLOCK.ASMCrea anche un file .LIS contenente tutto il listato del programma
AST6 -E CLOCK.ASMCrea un file .ERR contentente la descrizione degli errori eventualmente presenti nel programma
AST6 -X CLOCK.ASMCrea un file .X contenente l'elenco delle etichette e delle variabili del programma con indicazione delle righe in cui queste vengono usate.
AST6 -M -L CLOCK.ASMGenera una mappa di memoria del programma e la colloca alla fine del file .LIS. Infatti l'opzione -M va usata sempre insieme a -L. La mappa di memoria indica il numero di locazioni usate nelle varie pagine di memoria programma.
AST6 -S CLOCK.ASMGenera un file .SYM contenente l'elenco delle etichette e delle costanti utilizzate nel programma. Anche questo file è utile principalmente durante la simulazione del programma
AST6 -O CLOCK.ASMGenera un programma rilocabile in formato -OBJ, e non genera i files .HEX e .DSD. Questi files .OBJ possono essere incorporati in altri programmi usando il linker LST6.EXE creando un unico programma eseguibile.
Quando si compila un programma, i bytes di memora non usati vengono riempiti con un valore 0FFh. L'istruzione -D seguita da un valore numerico, permette di riempire queste locazioni inutilizzate con un determinato valore esadecimale (xx).
Usando questo comando, in presenza di errori nel programma, nel messaggio di errore viene specificato l'intero perrcorso (path) nel quale si trova il programma ASM.
Gli
errori di un programma si dividono in due tipi: WARNING (meno gravi, che in
molti casi non compromettono il funzionamento del programma) e ERROR (piu'
gravi che non permettono il funzionamento del programma). Il comando W seguito
da un numero da 0 a 2 specifica quale tipo di WARNING deve essere segnalato
dall'AST6.
ADD |
ADDI |
AND |
ANDI |
CALL |
CLR |
COM |
CP |
CPI |
DEC |
INC |
JP |
JRC |
JRNC |
JRNZ |
JRR |
JRS |
JRZ |
LD |
LDI |
NON |
RES |
RET |
RETI |
RLC |
SET |
|
STOP |
SUB |
SUBI |
WAIT |
|
|
|
|
Il contenuto di una variabile viene sommato al contenuto dell'accumulaore ed il risultato e' memorizzato nell'accumulatore. Formati possibili:
ADD A,A
ADD A,X
ADD A,Y
ADD A,V
ADD A,W
ADD A,(X)
ADD A,(Y)
ADD A,rr
A = registro accumulatore
X,Y,V,W = registri del micro
rr = indirizzo della variabile (1 byte)
Cicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C e' settato se l'operazione da un riporto, cioe' se e' maggiore di 255
(FFh)
Un numero viene sommato al contenuto dell'accumulatore ed il risultato e' memorizzato nell'accumulatore. Formati possibili:
A = registro accumulatore
nn = numero da 0 a 255 (FFh)
Cicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C e' settato se l'operazione da un riporto, cioe' se e' maggiore di 255
(FFh)
Funzione logica AND tra l'accumulatore ed una variabile. Il risultato e' memorizzato nell'accumulatore. Formati possibili:
A = registro accumulatore
X,Y,V,W = registri del micro
rr = indirizzo della variabile (1 byte)
Cicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C non e' influenzato
Funzione logica AND tra l'accumulatore ed un numero. Il risultato e' memorizzato nell'accumulatore. Formati possibili:
A = registro accumulatore
nn = numero da 0 a 255 (FFh)
Cicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C non e' influenzato
Richiama una subroutine. Formati possibili:
nomesub = etichetta della subroutine da eseguire
Cicli macchina = 4
I flag Z e C non sono influenzati
Resetta l'accumulatore, un registro o una variabile. Formati possibili:
A = registro accumulatore
X,Y,V,W = registri del micro
rr = indirizzo della variabile (1 byte)
Cicli macchina = 4
Il flag Z e' settato
Il flag C e' resettato
Calcola il complemento del contenuto dell'accumulatore e memorizza il risultato nell'accumulatore. Formati possibili:
A = registro accumulatore
Cicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C e' settato se prima della funzione COM il bit 7 di A e' 1
Compara il contenuto di un registro o di una variabile con l'accumulatore. Formati possibili:
A = registro accumulatore
X,Y,V,W = registri del micro
rr = indirizzo della variabile (1 byte)
Cicli macchina = 4
Il flag Z e' settato se i numeri sono uguali, resettato se diversi
Il flag C e' settato se l'accumulatore e' minore del registro o della
variabile, resettato se maggiore o uguale
Compara il contenuto dell'accumulatore con un numero. Formati possibili:
A = registro accumulatore
nn = numero da 0 a 255 (FFh)
Cicli macchina = 4
Il flag Z e' settato se i numeri sono uguali, resettato se diversi
Il flag C e' settato se l'accumulatore e' minore del numero, resettato se
maggiore o uguale
Decrementa di 1 il contenuto dell'accumulatore, di un registro o di una variabile. Formati possibili:
A = registro accumulatore
X,Y,V,W = registri del micro
rr = indirizzo della variabile (1 byte)
Cicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C non e' influenzato
Incrementa di 1 il contenuto dell'accumulatore, di un registro o di una variabile. Formati possibili:
A = registro accumulatore
X,Y,V,W = registri del micro
rr = indirizzo della variabile (1 byte)
Cicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C non e' influenzato
Effettua un salto incondizionato ad una etichetta. Formati possibili:
abc = etichetta
Cicli macchina = 4
I flag Z e C non sono influenzati
Salta ad una etichetta se il Flag Carry e' settato. Formati possibili:
e = numero che rappresenta la distanza in byte dell'etichetta di salto
rispetto all'istruzione JRC
Cicli macchina = 2
I flag Z e C non sono influenzati
Salta ad una etichetta se il Flag Carry e' resettato. Formati possibili:
e = numero che rappresenta la distanza in byte dell'etichetta di salto
rispetto all'istruzione JRNC
Cicli macchina = 2
I flag Z e C non sono influenzati
Salta ad una etichetta se il Flag Zero e' resettato. Formati possibili:
e = numero che rappresenta la distanza in byte dell'etichetta di salto
rispetto all'istruzione JRNZ
Cicli macchina = 2
I flag Z e C non sono influenzati
Salta ad una etichetta se un determinato bit di una variabile e' resettato. Formati possibili:
b = numero del bit da testare (da 0 a 7)
rr = byte di indirizzo della variabile
ee = numero che rappresenta la distanza in byte dell'etichetta di salto
rispetto all'istruzione JRR
Cicli macchina = 5
Il flag Z non e' influenzato Il flag C contiene il valore del bit testato
Salta ad una etichetta se un determinato bit di una variabile e' settato. Formati possibili:
b = numero del bit da testare (da 0 a 7)
rr = byte di indirizzo della variabile
ee = numero che rappresenta la distanza in byte dell'etichetta di salto
rispetto all'istruzione JRS
Cicli macchina = 5
Il flag Z non e' influenzato Il flag C contiene il valore del bit testato
Salta ad una etichetta se il Flag Zero e' settato. Formati possibili:
e = numero che rappresenta la distanza in byte dell'etichetta di salto
rispetto all'istruzione JRZ
Cicli macchina = 2
I flag Z e C non sono influenzati
Serve per caricare il valore contenuto in una variabile, in un registro o nell'accumulatore. Per questa istruzione va sempre usato l'accumulatore. Formati possibili:
A = registro accumulatore
X,Y,V,W = registri del micro
rr = indirizzo della variabile (1 byte)
Cicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C non e' influenzato
Serve per caricare un numero in una variabile, in un registro o nell'accumulatore. Formati possibili:
A = registro accumulatore
X,Y,V,W = registri del micro
rr = indirizzo della variabile (1 byte)
nn = numero di 1 byte
Cicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C non e' influenzato
Esegue 2 cicli macchina a vuoto. Viene usata per creare dei piccoli ritardi. Formati possibili:
Cicli macchina = 2
I flag Z e C non sono influenzati
Resetta uno degli 8 bit di una variabile o dell'accumulatore. Formati possibili:
A = registro accumulatore
rr = indirizzo della variabile (1 byte)
b = numero del bit da resettare (da 0 a 7)
Cicli macchina = 4
I flag Z e C non sono influenzati
Esce dalla subroutine e ritorna al punto della chiamata CALL. Formati possibili:
I flag Z e C non sono influenzati
Esce dalla subroutine di interrupt e ritorna al punto precedente all'evento di interrupt. Formati possibili:
I flag Z e C vengono riportati alla condizione in cui si trovavano prima dell'interrupt
Ruota a sinistra i bit dell'accumulatore. Trasferisce il bit 7 nel Carry, mentre il contenuto precedente del carry passa nel bit 0 dell'accumulatore. Formati possibili:
A = registro accumulatore
Clicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C riporta il valore del bit 7
Setta uno degli 8 bit di una variabile o dell'accumulatore. Formati possibili:
A = registro accumulatore
rr = indirizzo della variabile (1 byte)
b = numero del bit da settare (da 0 a 7)
Cicli macchina = 4
I flag Z e C non sono influenzati
Ruota a sinistra i bit dell'accumulatore. Trasferisce il bit 7 nel Carry cancellando il valore precedente. Equivale a una moltiplicazione per 2. Formati possibili:
A = registro accumulatore
Clicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C riporta il valore del bit 7
Blocca l'oscillatore di clock mettendo in standby tutto il microprocessore. Formati possibili:
Clicli macchina = 2
I flag Z e C non sono influenzati
Il contenuto di una variabile viene sottratto al contenuto dell'accumulatore ed il risultato e' memorizzato nell'accumulatore. Formati possibili:
A = registro accumulatore
X,Y,V,W = registri del micro
rr = indirizzo della variabile (1 byte)
Cicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C e' settato se il contenuto dell'accumulatore e' minore della
variabile o del registro, resettato se maggiore o uguale.
Un numero viene sottratto al contenuto dell'accumulatore ed il risultato e' memorizzato nell'accumulatore. Formati possibili:
A = registro accumulatore
nn = numero di 1 byte
Cicli macchina = 4
Il flag Z e' settato se il risultato e' 0, resettato se diverso da 0
Il flag C e' settato se il contenuto dell'accumulatore e' minore del numero,
resettato se maggiore o uguale.
Mette in standby il microprocessore, ma l'oscillatore di clock rimane attivo. Formati possibili:
Clicli macchina = 2
I flag Z e C non sono influenzati
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. E' possibile prelevare il programma di esempio alla pagina https://www.geocities.com/SiliconValley/Way/7521/st6/files/testled1.zip
Analizziamo le parti principali del programma TESTLED1
Qui viene solo definito il nome e il tipo di micro usato.
Definizione di tutti i registri interni del micro tramite un file esterno chiamato st62reg.inc
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).
Imposta le porte di I/O (PA0 ingresso e PB0 uscita) e disabilita tutti gli interrupt.
Questo programma non usa alcun interrupt, per cui le routine di interrupt non sono presenti.
Questa e' la subroutine pricipale che effettua tutte le funzioni del programma.
Analizziamo ora le singole righe di questa routine.
Questa e' l'etichetta che indentifica l'inizio della routine.
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").
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.
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:
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.
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".
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.
Queste sono righe standard per i micro ST621x e 2x e non vanno mai modificate.
Questa riga indentifica la fine del programma.
Privacy |
Articolo informazione
Commentare questo articolo:Non sei registratoDevi essere registrato per commentare ISCRIVITI |
Copiare il codice nella pagina web del tuo sito. |
Copyright InfTub.com 2024