Corso introduttivo sui microcontrollori - mrscuole.net · Programmare i microcontrollori in...

45
NA – L16 1 Corso introduttivo sui microcontrollori Programmare i PIC in C Richiami fondamentali sulla programmazione in C: Puntatori Strutture Unioni Nicola Amoroso [email protected] http://www.mrscuole.net/anxapic/ http://www.mrscuole.net/anxapic/ http://www.mrscuole.net/anxapic/

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/