Corso introduttivo sui microcontrollori - mrscuole.net · Programmare i microcontrollori in...
Transcript of Corso introduttivo sui microcontrollori - mrscuole.net · Programmare i microcontrollori in...
NA – L16 1
Corso introduttivo sui microcontrollori
Programmare i PIC in CRichiami fondamentali sulla programmazione in C:
Puntatori – Strutture – Unioni
Nicola [email protected]
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 2
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Nota: oltre a essere tra gli strumenti più potenti del C, i puntatorisono anche tra i più pericolosi perché se usati impropriamente possonointrodurre errori nei programmi, difficilmente identificabili. Quandosi considerano questi strumenti si raccomanda la massima attenzione.
Un puntatore è una variabile che contiene un indirizzo di
memoria di un’altra locazione di memoria
Supponiamo di definire una variabile int b = 100 e suppponiamo che la variabile b sia memorizza nella cella di
memoria il cui indirizzo è pari a 200 , supponiamo ancora di assegnare questo indirizzo alla variabile intera
ptrb. Si ha la situazione seguente: b = 100 ptrb = 200
ptrb contiene l’indirizzo della cella di memoria nella quale è contenuto il valore della variabile b
ptrb viene definito come puntatore alla variabile b
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 3
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Come tutte le altre variabili, anche le variabili puntatore, prima del loro utilizzo, devono essere dichiarate
Il formato generale della dichiarazione di una variabile di tipo puntatore è il seguente:
tipo *nome_variabiletipo è uno dei tipi di dati validi in C (es. Int, int16, char, ...)
esso specifica il tipo di variabile a cui puntare
nome_variabile è il nome della variabile puntatore
Int *ptra dichiara ptra come puntatore a una variabile di tipo int
Double *ptrclass dichiara ptrclass come puntatore a una variabile di tipo
double
Nella dichiarazione di una variabile puntatore bisogna sempre precedere il nome
della variabile con l’operatore *; la sua presenza (indispensabile) avverte il
compilatore che la variabile che si stà dichiarando è una variabile di tipo
puntatore
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 4
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
1.Operatori sui puntatori
Esistono due operatori per la manipolazione dei puntatori: & e *
Il primo è un operatore unario che restituisce l’indirizzo di memoria
dell’operando su cui è applicato.
.........
Int *ptrv, b = 10; //ptrv variabile puntatore a int – b variabile int
ptrv = &b; //ptrv contiene l’indirizzo della locazione di memoria in cui
......... //è memorizzato il valore di b
Il secondo è un operatore unario che restituisce il valore contenuto nella
locazione di memoria che si trova all’indirizzo indicato dalla variabile
puntatore.
.........
//Mostra su display il contenuto della locazione di memoria il cui indirizzo è contenuto in ptrv
printf(lcd_putc,”%d”, *ptrv); //(*ptrv = b = 10)
.........
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 5
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
1.Operatori sui puntatori
Esempio: #include <16F877A.h> //HardWare di sistema
..................
void main(void) {
int *ptra, b, c; //ptra variabile puntatore di tipo int8 – b, c variabili int8
ptra = &b; //ptra contiene l’indirizzo della locazione di memoria di b
*ptra = 20; //Assegno 20 alla loc di memoria indirizzata da ptra b=20
c = *ptra //C = *ptra = b = 20
//Mostra su display il contenuto della locazione di memoria il cui indirizzo è contenuto in ptra
printf(lcd_putc,”%d”, *ptra,b,c); //(*ptra = b = C = 20)
...................
}
Riferimento indiretto è il nome del processo che permette didefinire un valore attraverso un puntatore
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 6
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Per Default il CCS Pic-C compiler impiega un solo byte per le
variabili puntatore; questo significa che solo 256 locazioni della
memoria disponibile (RAM) può essere indirizzata.
Per componenti con disponibilità di maggior memoria (es, PIC18Fxxx,
etc...) per utilizzare variabili puntatore a 16 bit (2 byte)
bisogna introdurre la seguente direttiva in testa al programma:
#device *=16
L’utilizzo di questa direttiva permette l’impiego di puntatori a 16
bit però può generare inefficienza sul codice prodotto. Per
maggiori dettagli sull’impiego di questa direttiva consultare il
manuale del compilatore.
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 7
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
2. Aritmetica dei puntatori
Il C consente l’uso di due (quattro) soli operatori aritmetici suipuntatori: il + (++) e il – (--) Solo quantità intere possonoessere addizionate o sottratte a una variabile puntatore.
Consideriamo le seguenti dichiarazioni di 4 diversi tipi di puntatori:
int16 *ptrp1; int8 *ptrp2; char *ptrp3; double *ptrp4
Supponiamo inoltre di avere la seguente situazione:
ptrp1=100; ptrp2=150; ptrp3=180; ptrp4=200;
In seguito all’istruzione ptrp1++ avremo ora che ptrp1=102 in quanto
l’incremento fà puntare ptrp1 all’intero successivo e non alla cella
successiva (ptrp1 è una variabile puntatore che punta a una locazione
contenente un int16 [2 byte], l’intero successivo sarà memorizzato due
locazioni dopo quella attuale)
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 8
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
2. Aritmetica dei puntatori
Consideriamo le seguenti dichiarazioni di 4 diversi tipi di puntatori:
int16 *ptrp1; int8 *ptrp2; char *ptrp3; double *ptrp4
Supponiamo inoltre di avere la seguente situazione:
ptrp1=100; ptrp2=150; ptrp3=180; ptrp4=200;
In seguito all’istruzione ptrp2=ptrp2-1 avremo ora che ptrp2=149 in
quanto il decremento fà puntare ptrp2 all’intero precedente (ptrp2 è una
variabile puntatore che punta a una locazione contenente un int8 [1 byte],
l’intero precedente sarà memorizzato una locazione prima di quella attuale)
Ancora ptrp3=ptrp3+15 Avremo in questo caso ptrp3=195 [char 1 byte]
Ancora ptrp4++ Avremo in questo caso ptrp4=204 [double 4 byte]
Ogni volta che un puntatore viene incrementato passa a puntare alla variabile successiva che
appartiene al suo tipo base, mentre a ogni decremento passa alla variabile precedente dello
stesso tipo base.
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 9
2. Aritmetica dei puntatori
Consideriamo la seguente dichiarazione:
int8 *ptra, b = 20; //ptra puntatore a un int8 – b variabile int8
Analizziamo ora due possibili situazioni, una sbagliata e l’altra corretta
ptra=&b; //ptra contiene l’indirizzo della variabile int8 b
*ptra++; //Errato Viene prima prelevato il contenuto dell’oggetto
//puntato da ptra e successivamente viene incrementato ptra
.......
(*ptra)++; //Corretto l’oggetto puntato da ptra viene incrementato
//di 1 b = *ptra = 20 + 1 = 21
L’operatore unario “*” ha verso di precedenza superiore rispettoall’operatore unario “++” L’uso appropriato delle parentesiristabilisce la condizione corretta
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 10
3. Confronti ed espressioni con puntatori
I puntatori possono essere utilizzati in operazioni relazionali:
int8 *ptrp1, *ptrp2;.........if(ptrp1<ptrp2);
Oppureif(ptrp1==ptrp2);
Oppureif(ptrp1>ptrp2);
Ed anche in espressioni di assegnazioneprtp1 = ptrp2;
Il confromto e l’assegnamento tra variabili puntatori ha senso se esiste
una relazione logica tra gli stessi; queste operazioni sono alquanto delicate
e possono facilmente introdurre errori nei programmi
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Nelle espressioni e neiconfronti le variabili
puntatore seguono le stesseregole di tutte le altre
variabili in C
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 11
4. Puntatori e array
Esiste una stretta relazione tra puntatori e array, se usiamo il nome di un
array senza alcun indice si stà in realtà usando un puntatore al primo
elemento dell’array. Consideriamo le seguenti istruzioni:
int8 arr[10], *ptrarr; //arr array di 10 elementi int8 – ptrarr puntatore int8
ptrarr = arr; //ptrarr contiene l’indirizzo del primo elemento dell’array arr
// Ricorda il primo elemento di un array ha indice 0
arr[4] = 5; //assegna 5 al 5° elemento dell’array
*(ptrarr+5) = 8; //assegna 8 al 6° elemento dell’array
N.B. => Solo nel caso degli array per definire l’indirizzo del primo elemento basta utilizzare il
nome dell’array stesso, abbiamo visto in precedenza che l’indirizzo di una qualsiasi altra
variabile può essere individuata mediante l’operatore “&”.
Il nome di un array è un puntatore all’array
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 12
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
4. Puntatori e array
Consideriamo il seguente esempio:
int8 a[]={1, 2, 3, 4, 5};
void main(void) {
int8 *p, i;
p=a; //p contiene l’indirizzo del primo elemento dell’array
for(i=0; i<5; i++)
printf(lcd_putc,“%d”, *(p+i)); //mostra su display i 5 elementi dell’array
}
Per accedere agli elementi di un array viene utilizzata l’aritmetica dei puntatori, si incrementa
di i il valore della variabile puntatore p
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 13
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
4. Puntatori e array
Consideriamo il seguente esempio:
int8 a[]={1, 2, 3, 4, 5};
void main(void) {
int8 *p, i;
p=a; //p contiene l’indirizzo del primo elemento dell’array
for(i=0; i<5; i++)
printf(lcd_putc,“%d”, p[i]); //mostra su display i 5 elementi dell’array
}
Un altro metodo per accedere agli elementi di un array, i viene utilizzato come indice
dell’array il cui primo elemento è indirizzato dal puntatore p
Per accedere agli elementi di un array l’uso dell’aritmetica di puntatori può essere più veloce di
quello degli indici e spesso nei programmi la velocità di esecuzione è un requisito importante!
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 14
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
5. Puntatori come argomento di funzioni
Nelle lezioni 10 e 14 abbiamo introdotto una modalità per passare valori a una
funzione durante una ”chiamata a funzione”; abbiamo considerato il passaggio
di parametri per valore.
Esiste un altro metodo per passare un parametro ad una funzione Possibilità di passare un
puntatore ad una funzione, cioè passare l’indirizzo della locazione di memoria in cui è
immagazzinata la variabile Passaggio di un puntatore come parametro
• Passaggio dei parametri per valore
Durante la chiamata di una funzione nel passaggio dei parametri per valore, il valore del
parametro attuale viene ricopiato nella variabile che costituisce il parametro formale,
modifiche eseguite sul parametro formale non ha effetto sul parametro attuale (il
parametro formale è una variabile locale).
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 15
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
5. Puntatori come argomento di funzioni
Quando viene passato un puntatore come parametro a una funzione, qualsiasi
cambiamento fatto sulla variabile, usando il puntatore come riferimento,
cambia effettivamente il valore della variabile originale.
Una variabile puntatore può essere passata a una funzione come qualsiasi altra
variabile.
//Esempio Stampa su display la scritta “Studiare fà bene”
#include <16f88>
void puts(char *p); //Dichiarazione prototipo funzione – p è una variabile puntatore
void main(void) {
puts(“Studiare fà bene!”); //Questa funzione stampa la stringa il cui riferimento (elem 0)
} //viene passato come parametro puntatore
void puts(char *p) {
while(*p != “\0”) { //Sino a quando non incontri il carattere nullo fine stringa
printf(lcd_putc,”%c”, *p); //mostra il carattere indirizzato dal puntatore p
p++ //incrementa l’indirizzo della locazione puntata da p
}
}
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 16
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
5. Puntatori come argomento di funzioni
//Un altro esempio Incremento del valore di una variabile
#include <16f88>
.................
void inc_di_5(int8 *p) { //incrementa di 5 il contenuto della locazione puntata da p
*p += 5; //*p = *p + 5
}
void main(void) {
int8 val = 10, *ptr; //ptr puntatore a variabile int8
ptr = &val; //ptr contiene l’indirizzo di memoria della variabile val
printf(lcd_putc,”%d”, val, *ptr); //Mostra su display val = 10 *ptr = 10
inc_di_5(ptr);
printf(lcd_putc,”%d”, val, *ptr); //Mostra su display val = 15 *ptr = 15
}
Con questo esempio vediamo come modificare il contenuto di una locazione di memoria mediante l’uso di puntatori; in
questo caso i valori originali vengono passati mediante l’uso di puntatori; nessuna copia di parametri è necessaria
Potenza del C
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 17
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Quanto proposto sull’uso dei puntatori sono le basi fondamentali
per poter lavorare con strumenti molto potenti ma anche difficili
nel loro impiego. Prestare la massima attenzione sull’uso di questi
strumenti in quanto si possono commettere facilmente errori di
programmazione e riferimenti sui dati.
Naturalmente abbiano considerato gli argomenti più semplici e più
indicati per un nostro uso, per chi volesse approfondire questo
argomento raccomandiamo di consultare un classico libro sul
linguaggio C, ne esistono di ottimi a prezzi accessibilissimi.
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 18
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente
Oltre ai tipi di dati principali che conosciamo (int8, int16, char,double, ...), il C consente di creare cinque diversi tipi di datisecondo le proprie personali necessità.
La struttura E’ un insieme di dati di base (anche di tipodiverso), raggruppati sotto un unico nome e interpretato dalcompilatore come un unico riferimento. In altri linguaggi unastruttura viene spesso denominato con il nome di record.Campo di bit E’ una variazione della struttura e consente diaccedere ai singoli bit.Unione Consente di associare le stesse locazioni di memoria a dueo più variabili.Enum (Enumerativo) Consiste in una lista di simboli.Typedef E’ una parola chiave del C che consente di dare un nuovonome (rinominare) uno dei tipi di dati già esistenti.
Per le nostre necessità richiameremo brevemente le strutture e leunioni, naturalmente rimandiamo a testi specializzati per maggioriapprofondimenti
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 19
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: le strutture
La struttura è un insieme di variabili cui si fà riferimento con ununico nome, mantenendo unite delle informazioni che sonologicamente correlate. Le variabili che definiscono la struttura,vengono individuati come “elementi (membri-campi) della struttura”.Ogni variabile è di un tipo-base ben definito e può essere diversoda ogni altro.
Supponiamo di voler definire una struttura in cui memorizzare leinformazioni tecniche di una automobile (dati relativi a: marca,modello, cilindrata, tipo di combustibile). La dichiarazione dellastruttura è la seguente:
struct automobile {
char marca[20};
char modello[20];
int16 cilindrata;
char combustibile[10];
} auto, vettura;
struct parola chiave per definire una strutturaautomobile nome della struttura
marca, modello, cilindrata, combustibile elementi (membri) della struttura
auto, vettura variabili di tipo automobile
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 20
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: le strutture
“automobile” è solo un nuovo tipo di dato composto dall’insieme dipiù tipi di dati-base (anche diversi tra loro).
Per poter utilizzare questo nuovo tipo di dato, bisogna dichiararedelle variabili dello stesso tipo della struttura (automobile nelnostro esempio), come abbiamo sempre fatto per qualsiasi altro tipodi dato in precedenza. Nel nostro esempio precedente vengonodefinite le variabili auto e modello di tipo automobile.
Si possono definire ulteriori variabili dello stesso tipo nel solito modo:automobile car, models;
car e models sono anch’esse due variabili di tipo automobile
Notiamo che nella definizione precedente, ogni variabile di tipoautomobile occupa ben 52 byte di memoria (50 byte per marca,modello, combustibile e 2 byte per cilindrata).
Quando si sviluppa software per microcontrollori, nei quali lamemoria disponibile è limitata, fare sempre attenzione alle risorseoccupate. Le strutture sono molto potenti però occupano ancherisorse di sistema.
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 21
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: le strutture
1. Accesso agli elementi (membri-campi) della struttura
Per poter accedere a un membro (campo) della struttura bisognaindicare il nome della variabile e del membro separatidall’operatore “.” (punto).
auto.marca = ‘Fiat’; auto.cilindrata = 2000;Le due istruzioni precedenti assegnano i valori “Fiat” e “2000” airispettivi campi marca e cilindrata della variabile auto di tipoautomobile.
Per visualizzare su display il modello e la cilindrata della nostraauto:..........lcd_gotoxy(1,1);printf(lcd_putc,”%s”, auto.modello);lcd_gotoxy(1,2);printf(lcd_putc,”%lu”, auto.cilindrata);..........
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 22
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: le strutture
1. Accesso agli elementi (membri-campi) della struttura
Il campo modello della struttura automobile è un array di 20caratteri, se volessomo accedere al 4° elemento di questo array:
auto.modello[3];ricordiamo che il primo elemento di un array ha indice 0.Come vistro per i puntatori, se volessimo conoscere l’indirizzodella locazione di memoria in cui è immagazzinato il valore delmembro modello della struttura automobile:
&auto.modello;-----------------------------------
E’ anche possibile dichiarare un array di strutture come qualsiasialtro tipo di dati-base.Dichiariamo un array di 10 elementi della struttura “automobile”
struct automobile year08[10];Ogni elemento dell’array sarà composto da una struttura tipoautomobile (52 byte ogni elemento l’array year08 occuperà 520byte).Per accedere al membro modello del 5° elemento dell’array:
year08[4].modello;
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 23
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: le strutture
2. Strutture come parametri di funzioni
Quando un elemento di una struttura viene passata come argomento diuna funzione, viene passato solo il valore a meno che non si trattidi una variabile tipo array o array di caratteri.
struct my {char c;int8 x;char s[20];
} pers;
Si può passare ogni elemento della struttura a una funzione nelseguente modo:
funz(pers.c); //Passo il valore del carattere cfunz(pers.x); //Passo il valore dell’intero xfunz(pers.s); //Passo l’indirizzo della stringa sfunz(pers.s[3]); //Passo il valore del carattere s[3]
Se si desidera passare l’indirizzo di uno degli elementi dellastruttura my:
funz(&pers.c); //Passo l’indirizzo del carattere cfunz(&pers.x); //Passo l’indirizzo dell’intero x
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 24
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: le strutture
2. Strutture come parametri di funzioni
Quando l’argomento con cui viene chiamata una funzione è un’interastruttura, il compilatore passa tutta la struttura per valore,questo significa che modifiche, ai membri della struttura, fatteall’interno della funzione non si riflettono sulla strutturaoriginale usata al momento della chiamata. E’ frequente utilizzare,con questa tecnica, dichiarazioni globali della struttura, di cuivengono successivamente attivate le variabili e gli argomentinecessari.
/* Struttura visibilità globale */struct mio {
int8 x,y;char c;
}
Void main (void) {mio patt; // Var tipo miopatt.x=100;f1(patt);
}
Void f1(pform) {mio pform; // Var tipo mioprintf(lcd_putc”%d”,form.x);
}
Viene mostrato su display ilvalore dell’elemento x della
struttura mio.
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 25
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: le strutture
3. Puntatori a strutture
A volte è molto utile accedere a strutture attraverso un puntatore.Un puntatore a una struttura viene dichiarato ponendo un asteriscoprima del nome di una variabile struttura. Ad esempio dichiariamola struttura temp con la variabile struttura p e la variabilepuntatore q:
struct temp {int8 i;char ch;
} p, *q; //q puntatore a una strutturaCon questa definizione, l’istruzione q=&p; è perfettamente lecita.; diciamo q è un puntatore alla variabile struttura, di tipo temp,p.
Con i puntatori a struttura per poter accedere a un elemento dellastruttura si utilizza l’operatore “->” (- e >) e non l’operatore“.” come visto in precedenza,
q->i=10; //assegna 10 all’elemento i della strutturaAnalogamente (*q).i=10 //assegna 10 all’elemento i della struttura
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 26
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: le strutture
3. Puntatori a strutture
Nota Quando come parametro di una funzione viene passato l’interastruttura, viene fatta una copia “locale” della struttura stessa equesto occupa risorse e tempo specialmente per le strutture grandi.Quando viene passato, invece, un puntatore alla struttura vengonoridotti i tempi di esecuzione e le risorse di sistema impiegate; inquesto secondo caso modifiche in “locale” sulla struttura,modificano anche la struttura stessa, nel primo caso questo nonaccade.
3. Puntatori a strutture
Ricorda Quando si accede a unmembro della struttura usandouna variabile struttura si usal’operatore “.”, quando si usauna variabile puntatore allastruttura si usa l’operatore“->”.
#include <16f88.h>#include <string.h>Struct s_scuola {int8 i;char str[40];
} s, *p;
Void main(void) {p=&s;s,i=10;printf(lcd_putc”%d ”, s.i) //stampa 10p->i=20printf(lcd_putc”%d ”, p->i) //stampa 20
}
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 27
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: le strutture
4. Una struttura particolare; campo di bit
Il C consente di accedere ai singoli bit che si trovano in un byte.Sebbene sia possibile eseguire queste operazioni con gli operatorisu bit, in alcuni casi è bene usare il tipo “campo di bit” che puòportare a una migliore strutturazione ed efficienza del programma.La dichiarazione di un campo di bit è simile a quello di qualsiasialtra struttura, i memmbri della struttura sono i singoli bit delbyte considerato. Ad esempio se analizziamo il driver (lcd_4x20.c)del text-display della nostra demo-Board troviamo la dichiarazionedella seguente struttura:
struct lcd_pin_map { // This structure is overlayedboolean enable; // on to an I/O port to gainboolean rs; // access to the LCD pins.boolean unused; // The bits are allocated fromboolean unused; // low order up. ENABLE willint data : 4; // be pin D0.
} lcd;#byte lcd = 0xF83 // Control on PORTD per Pic serie 18F
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 28
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: le strutture
4. Una struttura particolare; campo di bit
struct lcd_pin_map { // This structure is overlayedboolean enable; // on to an I/O port to gainboolean rs; // access to the LCD pins.boolean unused; // The bits are allocated fromboolean unused; // low order up. ENABLE willint data : 4; // be pin D0.
} lcd;#byte lcd = 0xF83 // Control on PORTD per Pic serie 18F
La nostra struttura di controllo per il text-display è “mappato”all’indirizzo 0xF83 (PortD per i Pic della serie 18F. Per i Picdella serie 16F questo indirizzo è 0x08).
Il byte di controllo è composto da soli sei bit e precisamente:enable bit D0 .. rs bit D1 .. data bit D4-D7I bit D2 e D3 sono inutilizzati (sulla nostra scheda possonopilotare il buzzer e un led. Confronta lo schema elettrico dellaanxaPic demo-Board per maggiori ragguagli).
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 29
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: le strutture
4. Una struttura particolare; campo di bit
Siccome il data-bus è a 4 bit per inviare un byte si utilizzano duenibble consecutivi.
Un semplice esempio per l’invio di un nibble:void lcdSendNibble(byte n) {lcd.data=n;delay_cycles(1);lcd.enable=1;delay_us(2);lcd.enable=0;
}
Nota Gli esempi riportati sono puramente indicativi e del tuttogenerali. Per un uso più professionale documentarsi adeguatamente.
Un’ultima considerazione sulle struture Si possono avere anchestrutture annidate cioè strutture membri di altre strutture.Accenniamo solo a questa possibilità rimandando a testi opportuniper ulteriore documentazione.
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 30
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: unioni
In C, una unione (union) è una locazione di memoria che può essereusata da due o più variabili che possono essere anche di tipodifferente; durante l’utilizzo può essere impiegata una solavariabile per volta. La definizione di una unione è simile a quelladi una struttura. Un esempio di dichiarazione:
union tipo_u {int8 i;char c[3];double d;
} temp;
Lo spazio di memoria riservato alla nostra unione:
int8 1 byte char c[3] 3 byte double 4 byte
La differenza fondamentale tra una unione e una struttura
è che ogni elemento (membro) della unione condivide con
gli altri lo stesso spazio di memoria
1 byte 2 byte 3 byte 4byte
int8Char c[3]
double
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 31
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C
tipi di dati definiti dall’utente: unioni
Quando viene dichiarata una unione (union), il compilatore riservaspazio sufficiente per contenere la più grossa delle variabili chela costituiscono. Per il nostro precedente esempio verrebberoallocaty 4 byte di memoria.
l’accesso ad un membro della unione avviene tramite l’operatore “.”[(punto), es. temp.i, temp.d] oppure l’operatore “->” se siconsidera l’accesso mediante un puntatore a una variabile unione(valogono le stesse regole viste per le strutture).
Un esempio di uso di unioni per i micro si ha quando si connetteserialmente un A/D converter esterno a 12 bit. Si dichiara unaunione di questo tipo:
union AD_Sample {unsigned char bytes[2];signed short word;
}Per leggere A/D converter si fanno 2 letture a 8 bit e siimmagazzinano i dati nell’array. Quando si vuol utilizzare ilrisultato della conversione si legge l’elemento word della union.
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 32
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic
Per l'immissione dei dati ci
serviremo di un tastierino a matrice
4x4 con 16 tasti disposti su 4 righe
e 4 colonne.
L'interfacciamento del tastierino
con la nostra demoboard è
semplificato mediante l'utilizzo di
un opportuno encoder che gestisce
anche il processo di debouncer
(tempo di ritardo nella decodifica
del tasto premuto).
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 33
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic
1 2 3 A
4 5 6 B
7 8 9 C
* 0 # D
A >> [RC0]B >> [RE0]C >> [RE1]D >> [RE2]
Int >> [RB4]
ENCODER
Tasto D C B A Int1 0 0 0 0 L to H2 0 0 0 1 L to H3 0 0 1 0 L to HA 0 0 1 1 L to H4 0 1 0 0 L to H5 0 1 0 1 L to H6 0 1 1 0 L to HB 0 1 1 1 L to H7 1 0 0 0 L to H8 1 0 0 1 L to H9 1 0 1 0 L to HC 1 0 1 1 L to H* 1 1 0 0 L to H0 1 1 0 1 L to H# 1 1 1 0 L to HD 1 1 1 1 L to H
Quando si preme un tasto, l'encoder genera sulle uscite DCBA il codice relativo al tastopremuto, genera anche un segnale di interrupt (Int) e rende disponibili i dati sul bus per untempo di circa 40 ms (debouncer). I 4 bit generati verranno intercettati e decodificati dalmicrocontrollore; a tal proposito bisogna produrre opportuno software.
AnxaPic ConnPin
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 34
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Realizzeremo il nostro encoder con un microcontrollore Microchip a 18pin della serie 16F88. Questo è un microcontrollore compatibile con ilclassico e arcinoto 16F84 però con potenzialità molto superiori. Unadelle caratteristiche principali di questo micro è quello di avere ungeneratore di clock interno e quindi i 2 pin necessari al collegamentodi un quarzo esterno possono essere sfruttati come pin di I/O.Naturalmente vi sono altre caratteristiche importanti, per maggioriragguagli consultare gli opportuni Data-Sheets.
Questo esercizio viene presentato con il solo scopo di far conoscerel’uso di puntatori nella realizzazione di software per la gestione dimicrocontrollori.
Pr il nostro tastierino lo schema elettrico è molto semplice, ilcodice presentato richiede un minimo di attenzione, sono stateutilizzate routines, opportunamente riadattate per i nostri scopi,originariamente introdotte da P.H.Anderson (Pic C routines –Baltimore, MD, Jan ‘01).
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 35
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic – Schema elettrico
Il display a 7 segmenti è indispensabile solo
nella simulazione,. Sul circuito finale (PCB)
non sarà presente.
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 36
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic – Schema elettrico
Vediamo ora di capire lo schema e scoprire intuitivamente il funzionamento delsistema.
Dallo schema elettrico so nota che le 4 righe della Key sono connesse al nibblealto (RB4..RB7) di portB, inoltre questi 4 bit devono essere configurati comeinput e “allacciati” a livello logico alto mediante l’abilitazione del pull-upinterno del controllore. Le 4 colonne della key sono invece collegate al nibblebasso (RB0..RB3) di portB, questi 4 bit sono configurati come output e sonotenuti a livello logico basso.Quando nessun tasto è premuto, i 4 bit di input (B4..B7) sono tutti a livellologico alto (ricordiamoci del pull-up interno attivo).
Quando viene premuto un tasto (cortocircuitocolonna-riga), la riga corrispondente si porta alivello logico basso generando una condizione diinterrupt opportunamente rilevato dalmicrocontrollore (naturalmente la condizione diinterrupt, cambiamento del livello del segnale suRB4..RB7, è attivo).Il programma determina il corrispondente tastopremuto e invia l’opportuno codice sulle 4 lineedi uscita RA0..RA3, generando anche un opportunosegnale ad onda quadra di breve durata su RA4.
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 37
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic - Decodifica tasto
Per individuare il tasto premuto vengono portatesequenzialmente le colonne del tastierino alivello logico basso meediante l’invio diopportune maschere sul nibble basso della portB.Esempio: 0xE = 1110 (RB0=0, RB1=1, RB2=1, RB3=1;....... 0x7 = 0111 (RB0=1, RB1=1, RB2=1, RB3=0).
Per ogni colonna a livello basso si vanno a“scansionare” le 4 righe e quando il valore lettoè uguale a un valore di una delle quattromaschere inviate significa che il tasto premuto èuguale al tasto con indice di colonna e indice diriga opportune.
Supponiamo di aver inviato 0x07 (RB0=RB1=RB2=1, RB3=0) sulle 4 colonne e dileggere 0x0E (RB0=0, RB1=RB2=RB3=1) sulle 4 righe, significa che è stato premutoil tasto con indice di riga 0 e indice di colonna 3 (tasto T4).Il codice associato a questo tasto sarà pari a (4*iriga+icol) = (4*0+3) = 3 [T4]
Altro esempio Inviato su colonne 0x0B (RB0=RB1=RB3=1, RB2=0)Letto su righe 0x0D (RB0=RB2=RB3=1, RB1=0)
Tasto corrispondente Indice di riga 1, indice di colonna 2 (tasto T7) Tasto = 4*1+2=6 [T7]
N.B. Gli indici di riga e di collonna partono da zero!!!
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 38
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic - Flow-Chart Main
Y
N
Key_On è una variabile globale
attivata nella routine di Interrupt dopo
la decodifica del tasto
La main function è abbastanzasemplice. Il set del sistema e dellevariabili permette di impostare ilnibble basso di PORTB in scrittura eil nibble alto in lettura, inoltrevengono definite le variabiliglobali che possono esseremodificate da tutte le funzioni delprogramma.
Notiamo che quando viene mandato inuscita (su PortA) il codice deltasto premuto e il segnale su RA5,l’interrupt su RB4..RB7 vienedisabilitato in modo da nonintercettare eventuali tasti premutiin questa fase.
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 39
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic - Flow-Chart routine Intr
Quando viene premuto un tasto vienegenerato una condizione di interruptopportunamente rilevato dalmicrocontrollore (naturalmente lacondizione di interrupt, cambiamentodel livello del segnale su RB4..RB7,è attivo).
Una opportuna funzione (Decodetasto) determina l’indice di riga edi colonna per il tasto premuto, ilcorrispondente valore vieneimmagazzinato nella variabileglobale tasto. Viene anche abilitatala variabile globale “key_On” cheabilita l’invio del codice del tastonella funzione main.
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 40
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic - Flow-Chart Decode tasto
Per individuare il tasto premuto vengonoportate sequenzialmente le colonne deltastierino a livello logico basso mediantel’invio di opportune maschere sul nibblebasso della portB. Esempio: 0xE = 1110(RB0=0, RB1=1, RB2=1, RB3=1; ....... 0x7 =0111 (RB0=1, RB1=1, RB2=1, RB3=0).
Per ogni colonna a livello basso si vanno a“scansionare” le 4 righe. Ricordiamo chePortB ha abilitato il pull-Up internoquindi, in fase di lettura, se nessun tastoè stato premuto il corrispondente valoreletto è pari a 1111=0xFQuando il valore letto è diverso da 0xF ed
è uguale al valore di una delle quattromaschere inviate significa che il tastopremuto è uguale al tasto con indice dicolonna e indice di riga opportune.
Inviato su col 0x0B (RB0=RB1=RB3=1, RB2=0)Letto su righe 0x0D (RB0=RB2=RB3=1, RB1=0) Indice di riga=1, Indice di colonna=2
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 41
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic - Codice sorgente
Il codice sorgente è abbastanza documentato e facilmente comprensibile. In questa fasetralasciamo riportiamo solo alcuni commenti che possano meglio delucidare quantointrodotto in quasta lezione.
Definizione indirizzo registri per direzionalità e porte (PortB ePortA)
La funzione get_key(......) ha come parametri due variabili puntatore a int8. In questo caso qualsiasicambiamento al valore contenuto nella locazione di memoria indirizzata dalla variabile puntatore ,modifica il valore della variabile originale. La funzione ritorna un int8
Vengono passati gli indirizzidelle variabili rig e col
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 42
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic - Codice sorgente
Per individuare il tasto premuto vengono portate sequenzialmente le colonne del tastierino a livello logico basso mediante l’invio di opportunemaschere sul nibble basso della portB. Per ogni colonna a livello basso si vanno a “scansionare” le 4 righe. Ricordiamo che PortB haabilitato il pull-Up interno quindi, in fase di lettura, se nessun tasto è stato premuto il corrispondente valore letto è pari a 1111=0xFQuando il valore letto è diverso da 0xF ed è uguale al valore di una delle quattro maschere inviate significa che il tasto premuto è
uguale al tasto con indice di colonna e indice di riga opportune.
Maschere opportune
In uscita maschera per mandare a livello basso icol
Ristabilisco le condizioni iniziali per una nuova decodifica
Esci e return TRUE (condizione vera)
Esci e return FALSE (condizione non vera)
Ristabilisco le condizioni iniziali per una nuova decodifica
I contenuti delle locazioni indirizzatedalle variabili puntatore vengonomodificate con i nuovi valori degli
indici di riga e di colonna
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 43
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic - Codice sorgente
Main function Part1
In queste righe iniziali della main function abbiamo tutte le impostazioni hardware del sistema (Pull-Up attivo su PortB, abilitazioneoscillatore interno a 4 MHz, setup ADC, abilitazione interrupt su RB4..RB7, etc ..). Il Pic Wizard Tool ha agevolato il nostro lavoro!
Vengono anche definite i valori iniziali di alcune variabili globali (Es: key_ON=FALSE).
Set frequenza oscillatore interno a 4 MHz
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 44
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic - Codice sorgente
Main function Part2
Il codice è comprensibile e facile da seguire. Non merita necessari ulteriori commenti!
Per una efficace comprensione di questo esercizio si consiglia di leggere e verificare (anche manualmente) le varie fasi di scrittura dei valori sulle colonne
e lettura sulle righe Dedicateci un po’ del vostro tempo
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
NA – L16 45
Programmare i microcontrollori in linguaggio CRichiami fondamentali sulla programmazione in C: i puntatori
Un semplice esercizio
Colleghiamo un tastierino a matrice 4x4 alla nostra demo-Board Anxapic - Codice sorgente
Il file per l’impostazione e definizioni del sistema
Per Default il CCS Pic-C compiler impiega un solo byte per le variabili puntatore; questo significa che solo 256locazioni della memoria disponibile (RAM) può essere indirizzata.Per componenti con disponibilità di maggior memoria per utilizzare variabili puntatore a 16 bit (2 byte) bisognaintrodurre la seguente direttiva in testa al programma: #device *=16
Variabili puntatore a 16 bit
Abilitazione oscillatore interno
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/
http://www.mrscuole.net/anxapic/