Programmare in mikroBasic
 
  Box
Variabili e costanti

 

Per le informazioni riferite a questo argomento e per compilare i programmi è stata usata la vers. 7.0.0.2 di mikroBasic.
Altre versioni del compilatore potrebbero avere comportamenti diversi o non funzionare.

Nei programmi in mikroBasic, dobbiamo fare attenzione a come usiamo le variabili. Se non stiamo attenti, potremmo trovarci con un messaggio di "RAM esaurita".

Cos'è una variabile?

La variabile è un oggetto il cui valore può essere cambiato durante l'esecuzione del programma.
Le variabili sono il corrispondente dei registri del microcontrollore e sono collocate nella RAM, memoria dati di lettura/scrittura, che distrugge i dati quando viene tolta l'alimentazione.
La RAM contiene due serie di registri, gli SFR - Special Function Register (Registri per funzioni speciali) ed i GPR - General Purpose Register (Registri per uso generale).
Per i PIC della serie 12/16, la RAM è organizzata a blocchi di 128 locazioni(caselle) di memoria da 8 bit, chiamati bank. A seconda della quantità di RAM, ci possono essere 2 o 4 bank. Nel bank0 le locazioni vanno da 00h a 7Fh, nel bank1 da 80h a FFh, nel bank2 da 100h a 17Fh, nel bank3 da 180h a 1FFh. In ogni bank troviamo, sia SFR che GPR. (Leggere, sempre, il datasheet del PIC che si sta usando).
Mentre in assembly, per saltare da un bank all'altro, bisogna settare dei bit nel registro STATUS, in mikroBasic, è il compilatore che si occupa della gestione dei bank e della collocazione delle variabili.
In mikroBasic ci sono delle variabili predefinite, che corrispondono ai registri SFR dai quali prendono lo stesso nome (esempio: TMR0, PORTB, ecc.). Le variabili definite dall'utente, invece, saranno collocate nello spazio GPR.
Le 16 locazioni GPR che vanno da 70h a 7Fh, sono "mangiate" da mikroBasic per uso proprio, perciò non utilizzabili dall'utente. Ogni variabile è intesa come una casella della memoria RAM, con un proprio indirizzo univoco ed ha una dimensione di 1 byte(8 bit).
Nella figura si vede come sono collocati alcuni SFR e GPR nella RAM del PIC16F877A.

   

Ogni variabile è dichiarata sotto un'identificatore valido unico, che è usato per accedere alla locazione di memoria occupata dalla variabile.
Per identificatore valido, si intende un nome che può avere qualunque lunghezza e può contenere solo le lettere da a a z, da A a Z, il carattere di sottolineatura '_' e le cifre da 0 a 9.
L'unica restrizione è che il primo carattere deve essere una lettera o una sottolineatura e, quindi, non può cominciare con un numero.
Come identificatore, non si possono usare i nomi delle parole chiave e delle variabili predefinite di mikroBasic.
Il mikroBasic non ha la sensibilità dei caratteri (come nel linguaggio C), perciò Pluto, pluTO, e pLuTo, rappresentano lo stesso identificatore.
(Ho provato a scrivere un nome di variabile di 280 caratteri ed il compilatore non ha protestato.)
Le variabili sono dichiarate nella parte di dichiarazione del modulo o della procedura. Ciascuna variabile deve essere dichiarata sempre, prima che possa essere usata.

Variabili globali

Le variabili globali sono quelle che non appartengono ad alcun blocco chiuso; sono dichiarate dopo la riga con la parola chiave include (se esistente) e sempre prima della riga con l'etichetta main. Esse sono "viste", dal punto del modulo in cui sono dichiarate, fino alla fine del file. Queste variabili occupano un posto fisso, nella RAM, per tutta la durata di esecuzione del programma.

Variabili locali

Le variabili locali sono quelle che sono dichiarate dentro una procedura o funzione e sono "viste" dal punto in cui sono dichiarate fino alla fine della procedura. Queste variabili occupano un posto, nella RAM, per la sola durata di esecuzione della procedura, dopodichè, mikroBasic ricicla lo spazio di memoria. Le variabili locali dichiarate in funzioni e procedure diverse, dividono lo stesso spazio in memoria, se possibile.

I Tipi di dati

E' obbligatorio specificare un tipo di dati per ogni variabile.
Il tipo di dati della variabile determina, non solo la gamma permessa di valori, ma anche lo spazio, che la variabile occupa nella memoria RAM. Teniamo presente che, operazioni che usano tipi diversi di variabili, impiegano tempo diverso per essere completate.

Ogni variabile e costante simbolica deve avere un tipo rigorosamente definito, conosciuto al momento della compilazione. Il tipo serve a:
 - determinare la corretta richiesta di allocazione della memoria,
 - interpretare le configurazioni di bit trovate nell'oggetto durante accessi susseguenti,
 - in molte situazioni di verifica-tipo, assicurare che assegnazioni illegali siano individuate e bloccate.


Categorie di Tipi

I tipi possono essere suddivisi in:
 - tipi semplici
 - matrici (arrays)
 - stringhe
 - puntatori
 - strutture (tipi personalizzati)

Tipo Dimensione Gamma
byte 1 byte 0 .. 255
char 1 byte 0 .. 255
word 2 bytes 0 .. 65535
short 1 byte - 128 .. 127
integer 2 bytes -32768 .. 32767
longint 4 bytes -2147483648 .. 2147483647
float 4 bytes ±1.17549435082 * 10^-38
±6.80564774407 * 10^38

Tipi semplici

I tipi semplici rappresentano i tipi che non possono essere divisi negli elementi più fondamentali e sono il modello per rappresentare i dati elementari a livello macchina.

In tabella, una veduta d'insieme dei tipi semplici in mikroBasic, con la dimensione occupata in RAM.

(Il tipo char può essere trattato come tipo byte in ogni aspetto.)

Non possiamo mescolare oggetti, con segno e senza segno, nelle espressioni con aritmetica od operatori logici. Possiamo assegnarne uno con segno ad uno senza segno, o viceversa, soltanto usando la conversione esplicita.

dim i as byte
dim kaPpa, _L_5 as byte
dim conta_tempo, tempo as word
dim testo as string[5]
dim num as longint
dim lista as byte[5]
dim caratt as char
dim bEdu as float

Dichiarare una variabile

La sintassi di mikroBasic per la dichiarazione di una variabile è:

dim lista_identificatori as tipo

lista_identificatori è una lista di identificatori validi, delimitata da virgole.

tipo può essere qualunque tipo di dati.

Costanti letterali (literals)

Le costanti letterali rappresentano valori fissi, numerici o di caratteri, che si assegnano a variabili, costanti simboliche ed espressioni.
Il tipo di dati di una costante è dedotto dal compilatore, usando come indizi, il valore numerico ed il formato usato nel codice sorgente.

dim alfa as byte
dim beta as word

' notazione decimale
alfa = 255
beta = 33000

' notazione esadecimale
alfa = $FF    opp.  alfa = 0xFF
beta = $80E8  opp.  beta = 0x80E8

' notazione binaria
alfa = %11111111
beta = %1000000011101000

Literals Interi

I valori interi possono essere rappresentati in notazione decimale, esadecimale o binaria.
In notazione decimale, i numeri sono rappresentati come sequenza di cifre (senza virgole, spazi o punti), con prefisso facoltativo (l'operatore + o -) per indicare il segno. Il valore predefinito è positivo (6258 è equivalente a +6258).

Il prefisso "dollaro" ($) o il prefisso 0x indicano un numero esadecimale.

Il prefisso "percento" (%) indica un numero binario.

La gamma di valori permessa, è imposta dal tipo di dati più grande dentro mikroBasic, il longint. Il compilatore segnalerà un errore, se la costante letterale eccede 2147483647 ($7FFFFFFF).

Literals a virgola mobile (float)

0.       ' = 0.0
-2.15    ' = -2.15
25.95e7  ' = 25.95 * 10^7
4e-4     ' = 4.0 * 10^-4
7E+10    ' = 7.0 * 10^10
.08E24   ' = 0.08 * 10^24

dim alfa, beta as float
...
alfa = -2.25
beta = .09E32

Literals a Virgola mobile (float)

Un valore a virgola mobile consiste di:
- Intero Decimale
- Punto Decimale
- Frazione Decimale
- e oppure E ed un esponente intero con segno (opzionale)

Possiamo omettere il numero intero decimale o la frazione decimale (ma non entrambi). Le costanti float negative sono prese come costanti positive con il prefisso costituito dall'operatore meno (-) unario.

Le costanti a virgola mobile in mikroBasic sono limitate nella gamma da ±1.17549435082E-38 .. ±6.80564774407E38.

Literals carattere

dim alfa as byte
dim beta as char
...
alfa = "W"
beta = "7"

Literals Carattere

La costante letterale carattere è un carattere del set di caratteri ASCII esteso, chiusa tra virgolette. La costante letterale carattere può essere assegnata alle variabili di tipo byte e di tipo char alle quali sarà assegnato il valore ASCII del carattere. Inoltre, possiamo assegnare la costante letterale carattere ad una variabile di tipo stringa.

Literals stringa

"Ciao Mondo!" 'messaggio,
              'lung. 11 caratteri
			   
"  "          'due spazi,
              'lung. 2 caratteri
			   
"H"           'lettera,
              'lung. 1 carattere
			   
""            'stringa nulla,
              'lung. 0 caratteri

Literals Stringa

La costante letterale stringa è una sequenza di max 255 caratteri del set ASCII esteso, chiuso dalle virgolette.
La lunghezza della costante letterale stringa è il numero di caratteri che essa consiste. La stringa è immagazzinata internamente come sequenza di caratteri più un carattere null finale (ASCII zero). Questo carattere finale non conta per la lunghezza totale della stringa. La costante letterale stringa con niente fra le virgolette (stringa nulla) è immagazzinata come singolo carattere nullo. Possiamo assegnare la costante letterale stringa ad una variabile stringa o ad una matrice di char.

La virgoletta non può essere una parte della costante letterale stringa.
Possiamo usare la funzione incorporata Chr per stampare una virgoletta: Chr (34).

Matrici o tabelle

'matrice 50 elementi di tipo word
dim campioni as word[50]

...
'Assegnamo un valore all'elemento
'con indice 4
campioni[4] = 305

'se l'elemento con indice 27
'è uguale a 67 allora...
if campioni[27] = 67 then
 ... 

Matrici o tabelle (arrays)

Una matrice rappresenta una raccolta indicizzata di elementi dello stesso tipo (chiamato il tipo base). Poichè ogni elemento ha un indice unico, le matrici possono contenere significativamente lo stesso valore più di una volta.
I tipi di matrice sono denotati tramite la costruzione della forma:
tipo [ lunghezza_matrice ]
Ognuno degli elementi di una matrice è numerato da 0 a lunghezza_matrice - 1. Ogni elemento di una matrice è di tipo tipo e vi si può accedere specificando il nome di matrice seguito dall'indice di elemento all'interno di parentesi quadre.

Stringhe

'Esempio
dim msg1 as string[21]
dim msg2 as string[18]

msg1 = "Questo è un messaggio"
msg2 = "Un'altro messaggio"
msg1 = msg2 ' questo è ok
msg2 = msg1 ' questo è illegale

'Esempio elemento per elemento
dim s as string[5]
...
s = "pak"
' s[0] è un literal char "p"
' s[1] è un literal char "a"
' s[2] è un literal char "k"
' s[3] è zero (carattere NULL)
' s[4] è indefinito
' s[5] è indefinito

Stringhe

Una stringa rappresenta una sequenza di caratteri, ed è equivalente ad una matrice di char più un carattere null finale (ASCII zero). Essa è dichiarata come:
string [ lunghezza_stringa ]
Lo specificatore lunghezza_stringa è il numero di caratteri della stringa. La stringa è immagazzinata internamente come sequenza di caratteri più un carattere null finale (ASCII zero). Questo carattere finale non conta per la lunghezza totale della stringa.
Una stringa nulla ("") è immagazzinata come un singolo carattere null.
Possiamo assegnare costanti letterali stringa od altre stringhe a variabili stringa. La stringa sul lato destro di un operatore di assegnazione deve essere la più corta delle due, o di lunghezza uguale.

Alternativamente, possiamo trattare le stringhe elemento per elemento.
Mettiamo attenzione, quando trattiamo le stringhe in questo modo, perchè sovrascrivendo la fine di una stringa si può causare violazione di accesso della RAM.

Costanti simboliche

'costante con tipo
const MAX as longint = 10000

'costante senza tipo,
'verrà assegnato un tipo word
const MIN = 1000

'verrà assegnato un tipo char
const ENNE = "n"

'verrà assegnato un tipo string
const MSG = "Ciao"

'indicazione tipo obbligatoria
const LATO as byte[3] = (21,58,4)

Costanti simboliche

La costante è un dato il cui valore non può essere cambiato durante l'esecuzione del programma. Usando una costante in un programma, non si consuma memoria RAM. Le costanti possono essere usate in ogni espressione, ma non possono essere assegnate ad un nuovo valore.
Le costanti sono dichiarate nella parte di dichiarazione del programma o procedura. Possiamo dichiarare qualunque numero di costanti dopo la parola chiave const:
const nome_costante [ as tipo ] = valore
Ogni costante è dichiarata sotto un unico nome_costante il quale deve essere un identificatore valido. E' tradizione scrivere i nomi di costanti in maiuscolo. La costante richiede di specificare un valore, che è una costante letterale adatta per il tipo di dato. Il tipo è opzionale; in assenza di tipo, il compilatore assegna "il più piccolo" dei tipi che può accomodare valore.

Nota: Non possiamo omettere il tipo, se dichiariamo una costante matrice (array).

Matrici di costanti

' Dichiara una matrice costante
' con i giorni di ogni mese
const MESE as byte[12] = (31,28,
                          31,30,
                          31,30,
                          31,31,
                          30,31,
                          30,31)

Matrici di costanti

La matrice di costanti è inizializzata assegnandogli una sequenza di valori, delimitata da virgole, all'interno di parentesi tonde.
Le matrici di costanti vengono situate nella memoria di programma (ROM).

Notare che l'indicizzazione è su base zero; nell'esempio, il numero di giorni di gennaio è MESE[0] ed il numero di giorni di dicembre è MESE[11].
Il numero di valori assegnati non deve eccedere la lunghezza specificata. E' invece possibile assegnare meno elementi, poichè agli elementi finali, in "eccesso", saranno assegnati zeri.

Accesso a bit individuali

' tipo longint (32 bit)
' (peppo.0 ... peppo.31)
dim peppo as longint 
'...

' Se RB0 è settato,
' setta il 28° bit di peppo
if PORTB.0 = 1 then
peppo.27 = 1
end if



' Azzera bit TMR0F
INTCON.TMR0F = 0

Accesso ai Bit Individuali delle variabili

mikroBasic permette di accedere ai diversi bit delle variabili.
Basta usare semplicemente il punto (.) con una variabile, seguita da un numero.

Questo genere di accesso selettivo, è la caratteristica intrinseca di mikroBasic e può essere usata dovunque, nel codice.

Assicuriamoci, sempre, di non eccedere la dimensione del tipo di formato.
Per esempio, PORTB.12 restituirebbe un errore poichè PORTB è una variabile di 8 bit (valori permessi 0...7).

Se conosciamo bene le funzioni del chip, possiamo accedere ai bit dal loro nome, come indicato nel datasheet.

program Prova

dim beta as byte

main:
    trisB = 0
    portB = 0
    beta = %10000001 '129 decimale
    portB = beta     'portB = %10000001
    delay_ms(1000)   'ritardo 1 sec.
    portB = TRUE     'portB = %11111111
    beta = portB     'beta = %11111111
    delay_ms(1000)
    portB = FALSE    'portB = %00000000
    delay_ms(1000)
    portB.7 = beta.3 'portB = %10000000
    delay_ms(1000)
    goto main
End.

Programmino di prova

mikroBasic contiene le costanti predefinite TRUE e FALSE.

Contrariamente a quello che si potrebbe pensare, la costante TRUE non vale 1, bensì 255 (%11111111).

La costante FALSE vale 0 (%00000000).

Questo semplice programmino visualizzerà su portB, tramite 8 LED, il valore di TRUE e di FALSE.
Potete fare copia/incolla e provarlo.

Vedremo il passaggio di valori tra SFR e GPR (portB, beta).

Si potrà anche vedere il passaggio di semplici bit tra variabili (portB.7, beta.3). PortB.7 corrisponde a RB7 nel PIC.

Nella figura sottostante si può vedere una animazione della simulazione del programmino.
L'istruzione evidenziata in blu, è quella che verrà eseguita subito dopo.

   

Bibliografia

Manuale mikroBasic
Datasheet PIC16F877A Microchip

Ultima modifica  

 
Privacy Policy Cookie Policy