Introduzione al linguaggio CData di pubblicazione: 17-10-2003 | Versione Italiana | (No English Version) Parole chiave: - How-To - Rabbit - |
|
Modulo Rabbit RCM2200
|
I concetti di programmazione C introdotti in questo corso sono validi per tutte
le versioni di Dynamic C ad eccezione di alcuni esempi, orientati alla gestione
delle reti, per i quali non sono presenti le librerie nelle versioni di kit di sviluppo
per Rabbit sprovvisti di connessione Ethernet.
Prerequisiti
In questa lezione, ed in quelle che verranno pubblicate sucessivamente, diamo per scontato che abbiate già
installato l'ambiente di sviluppo Dynamic C sul vostro PC e che abbiate collegato correttamente un
Rabbit Core + Scheda di sviluppo SX01 al programmatore seriale.
Chi non l'avesse fatto può accedere al seguente articolo:
- Installazione SDK Rabbit RCM2200
In questo articolo viene illustrata l'installazione e la prima prova di funzionamento del Kit di sviluppo per i moduli RCM2200 della Rabbit Semiconductor. L'articolo fà riferimento all'uso del Kit congiuntamente alla scheda per prototipi SX01
Scriviamo il nostro primo programma in C
Lanciamo il Dynamic C e creiamo un nuovo file sorgente in C selezionando la voce di menu:
File -> New
Scriviamo quindi il seguente codice:
main() {
printf("Ciao mondo !");
}
Lanciamo quindi in esecuzione il programma selezionando dal menu la voce:
Run -> Run
Il programma verrà compilato ed il codice binario ottenuto sarà inviato direttamente al micro
Rabbit presente sul core module tramite il programmatore connesso alla porta seriale del PC.
Terminato il trasferimento del codice il Rabbit verrà resettato ed il codice eseguito direttamente
sul micro.
Il risultato sarà il seguente:
Figura 1: La schermata standard output di un programma in esecuzione su Rabbit
Quella che abbiamo appena lanciato in esecuzione è probabilmente una
delle forme più semplici di programma scritte in C, ma in essa ci sono già
una serie di concetti importanti che vanno chiariti prima di proseguire.
La funzione main()
Qualsiasi parte di codice eseguibile scritta in C va inserita all'interno di una
funzione.
Una funzione consiste in una collezione di istruzioni che il micro deve eseguire.
Per poter iniziare ad eseguire qualcosa il C si aspetta di trovare un funzione di
partenza di nome "main" (dall'inglese "principale").
Per raccogliere delle istruzioni all'interno di una funzione dobbiamo specificare il
nome della funzione stessa seguito da una coppia di parentesi tonde:
main()
Quindi una coppia di parentesi graffe in cui inserire tutte le istruzioni che compongono
la funzione:
main() {
}
L'uso degli spazi a inizia riga (indentazione) semplifica la lettura di un programma in C, ma
sono solo fortemente consigliati, non obbligatori.
Lo stesso codice è assolutamente valido se scritto nelle seguenti forme:
main() {}
oppure
main()
{
}
e cosi via. In pratica in C non ha molta importanza, il più delle volte, la presenza di spazi
o carriage return tra le diverse istruzioni e direttive del linguaggio.
Una funzione può contenere a sua volta chiamate ad altre funzioni che a loro volta possono contenerne
delle altre.
Nel nostro caso con:
main() {
printf("Ciao mondo !");
}
Viene richiamata all'interno della funzione main(), la funzione print() il cui compito è
quello di inviare stringhe di caratteri sulla stdio ovvero sulla consolle predefinita
che corrisponde nel Dynamic C nella finestra stdio.c riportata in figura 1.
La funzione printf() accetta dei parametri che devono essere inseriti all'interno delle
parentesi tonde. In questo caso si tratta della stringa "Ciao mondo !" da inviare sulla
finestra standard stdio.
Le variabili
Proviamo ora a inserire delle variabili con cui fare due conti all'interno del nostro programma.
Premiamo il pulsante EDIT sotto la barra dei menu e modifichiamo il nostro programma così:
main() {
int i;
i=100;
printf("La variabile i vale %d",i);
}
Lanciamo in esecuzione il programma. Quello che otterremo è riportato nella figura seguente:
Figura 2: Visualizzazione del valore della variabile i
In pratica quello che abbiamo fatto è stato inserire un definizione per una
nuova variabile con la riga:
int i;
Dove int indica il tipo di variabile. In questo caso un intero con segno a 16 bit in grado quindi di
memorizzare valori numerici compresi nell'intervallo da -32768 a +32767.
L'intervallo minimo e massimo del valore numerico che è possibile inserire in una variabile di tipo int
deriva appunto dalla sua dimensione di 16 bit. Con 16 bit è possibile rappresentare valori a zero a 2 elevato
alla sedicesima ovvero 65535. Utilizando un bit di questi 16 per memorizzare il segno i numero minimi e massimi
diventano quelli indicati.
Se avessimo specificato la variabile come unsigned int avremmo rinunciato al segno (da cui il prefisso unsigned)
e quindi a tutti i valori negativi ma aumentato l'intervallo di valori positivi possibili da +32767 a +65535.
Esistono altri tipo di variabili in C che consentono di memorizzare valori diversi. Nella figura 4,
estratta dal manuale ufficiale del Dynamic C, riportiamo le tipologie di variabili possibili.
Tavola 1: Tipi di dati gestiti dal Dynamic C
La riga:
i=100;
Assegna il valore 100 alla variabile i.
La riga:
printf("La variabile i vale %d",i);
Visualizza il valore sulla consolle stdio. La funzione printf() in questo caso
accetta due parametri separati da una virgola. Il primo parametro è una stringa
in cui possono essere inserire delle parti di frase statiche e dei formattatori.
Per distinguere un formattatore dal resto del testo viene utilizzato il carattere %.
In questo caso %d significa: "Sostituisci %d con il valore decimale contenuto nella variabile i".
Il numero di variabili accettate dalla printf() oltre la stringa di formattazione
dipende dal numero di formattatori presenti.
Volendo rappresentare lo stesso numero sia come valore decimale che esadecimale potremo scrivere:
printf("La variabile i vale %d dec [%x hex]",i,i);
per ottenere in uscita:
La variabile i vale 100 dec [64 hex]
Di seguito viene riportato l'elenco dei possibili formattatori riconosciuti dalla printf():
%d intero decimale (si usa con le variabili di tipo int)
%u intero decimale senza segno (si usa con le variabili di tipo unsigned int)
%x intero esadecimale (si usa con le variabili int o unsigned int)
%s stringa (Si usa con le stringhe)
%f numeri con virgola (si usa con le variabili float)
Gli operatori condizionali
Il linguaggio C è un linguaggio di tipo procedurale, ovvero composto da una serie di
istruzioni eseguite in sequenza dal microprocessore al fine di effettuare, appunto, una
una procedura.
In molti casi, durante il regolare flusso del programma, è necessario poter scegliere tra diverse possibili
opzioni all'interno della procedura o ripetere, per un determinato numero di volte, la stessa serie di istruzioni
ciclicamente.
Per risolvere questo problema il programmatore ha a disposizione una serie di costrutti in grado di
deviare il normale flusso sequenziale del microprocessore, vediamo quali sono.
L'ISTRUZIONE IF
L'istruzione if è la più classica delle istruzioni condizionali ed esiste praticamente per qualsiasi
linguaggio di programmazione. Il suo formato più semplice è il seguente:
if (espressione) {
.. istruzioni da eseguire se l'espressione è vera
}
In pratica se il risultato dell'espressione all'interno delle parentesi è vero viene eseguito
il blocco di istruzioni tra parentesi graffe. In caso contrario se il risultato dell'espressione
è falso il blocco tra le parentesi non viene eseguito.
La distinzione tra un valore vero e falso viene effettuata in C nella seguente maniera:
- E' vero un valore diverso da zero
- E' falso un valore pari a zero
Vediamo un esempio pratico:
main() {
int a;
a=1;
if (a) {
printf("Vero\n");
}
if (!a) {
printf("Falso\n");
}
}
Se eseguiamo il codice così come lo abbiamo scritto otterremo sulla consolle
il messaggio "Vero" in quanto a vale 1 che viene considerato come un valore vero.
Se assegniamo alla variabile a uno dei seguenti valori -1, 10, -500, ecc.
otterremo sempre il messaggio "Vero".
Assegnando invece ad a il valore 0 otterremo il messaggio "Falso". L'operatore !
(punto esclamativo) è infatti un operatore che nega il risultato dell'espressione
alla sua destra per cui se a è falso !a è vero ed il codice tra la seconda coppia
di parantesi graffe viene eseguito.
Un modo molto più elegante di scrivere lo stesso programma è il seguente:
main() {
int a;
a=1;
if (a) {
printf("Vero\n");
} else {
printf("Falso\n");
}
}
Ovvero "se" a è vero, esegui il primo blocco di istruzioni, "altrimenti" esegui il secondo blocco.
Ovviamente l'espressione tra parentesi tonde può essere anche più complessa e prevedere un controllo
per uno specifico valore di a. Ad esempio:
main() {
int a;
a=54;
if (a==54) {
printf("Vero\n");
} else {
printf("Falso\n");
}
}
In questo caso abbiamo usato l'operatore == (doppio uguale) che genera appunto un valore vero o falso
dopo aver comparato due valori.
Da notare come sia diverso l'uso dell'operatore di comparazione == da quello di assegnazione = (singolo uguale).
= assegna alla variabile sulla sinistra il valore sulla destra
== compara il valore di sinistra con quello di destra ma non effettua alcuna assegnazione
La comparazione può essere effettuata naturalmente anche tra due variabili. Ad esempio:
main() {
int a;
int b;
a=54;
b=53;
if (a==b) {
printf("Vero\n");
} else {
printf("Falso\n");
}
}
Con questo esempio viene visualizzato il messaggio "Falso" in quanto a è diverso da b.
E' possibile effettuare più controlli in cascata per aumentare il numero di derivazioni del
programma. Ad esempio:
main() {
int a;
int b;
a=54;
b=54;
if (a==b) {
printf("A uguale a B\n");
} else if (a>b) {
printf("A maggiore di B\n");
} else if (a‹b) {
printf("A minore di B\n");
}
}
Esiste anche la possibilità di effettuare dei salti in punti diversi del
programma tramite l'istruzione goto. Questo metodo è assolutamente sconsigliato
in quanto potrebbe rendere un programma complesso assolutamente illeggibile,
ma spesso può rappresentare una valida soluzione per accellerare i tempi
di sviluppo di un programma. Vediamo come modificare l'esempio precedente
usando l'istruzione goto:
main() {
int a;
int b;
a=54;
b=54;
if (a==b) goto Uguale;
if (a>b) goto Maggiore;
if (a‹b) goto Minore;
Uguale:
printf("A uguale a B\n");
exit(0);
Maggiore:
printf("A maggiore di B\n");
exit(1);
Minore:
printf("A minore di B\n");
exit(2);
}
In questo esempio ci sono una serie di novità da comprendere. Anzitutto il formato della
funzione goto. La goto consente di far saltare il programma in un punto diverso
del sorgente. Il punto in cui andare è identificato da una label (etichetta) costituita
da un nome seguito da due punti (:). Nell'esempio le label sono Uguale:, Maggiore: e Minore: e
vanno specificate (senza i due punti) di seguito all'istruzione goto.
In ognuna delle if utilizzate non è stata inserita la coppia di parentesi graffe. Questo perché
l'istruzione da eseguire all'interno della if è una sola. Nel caso di debbano eseguire più istruzioni
è obbligatorio inserire le parentesi graffe.
La funzione exit(0) consente di uscire immediatamente dal programma e ridare il controllo
al Dynamic C. Il numero tra parentesi è un codice di errore che possiamo passare al Dynamic C
per indicare una eventuale condizione d'errore.
Il valore verrà visualizzato con una message box come riportato in figura 3.
Figura 3: Codice d'errore in uscita
L'ISTRUZIONE SWITCH
L'istruzione switch consente sempre di selezionare porzioni di codice da eseguire in base
al valore che assume una espressione in una forma leggermente diversa. Vediamo un esempio:
main() {
int a;
a=54;
switch(a) {
case 0:
printf("A uguale a zero\n");
break;
case 1:
printf("A uguale a uno\n");
break;
case 2:
printf("A uguale a due\n");
break;
default:
printf("Altro valore\n");
break;
}
}
La switch valuta il valore dell'espressione tra parantesi tonde (in questo caso il valore
della variabile a) e lo confronta con diverse costanti numeriche tramite l'istruzione
case. Quando trova una costante numerica uguale al risultato dell'espressione esegue
il codice che segue la case. L'istruzione break serve ad uscire dalla switch ed evitare
che venga eseguito il codice al di sotto delle case successive.
L'istruzione default è opzionale e il codice specificato dopo di essa viene eseguito solo
se l'espressione non è uguale a nessuno dei valori specificati.
Segnala questo articolo:
Parole chiave: - How-To - Rabbit -
|