Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere...

29
Scuola Politecnica e delle Scienze di Base Corso di Laurea in Ingegneria Informatica Elaborato finale in Misure per l’automazione e produzione industriale Programmazione di microcontrollori STM32: Protocollo I2C e comunicazione con sensore Anno Accademico 2015/2016 Relatore Candidato Ch.mo prof. Rosario Schiano Lo Moriello Maria Concetta Turco matr. N46001685

Transcript of Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere...

Page 1: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Scuola Politecnica e delle Scienze di Base Corso di Laurea in Ingegneria Informatica Elaborato finale in Misure per l’automazione e produzione industriale

Programmazione di microcontrollori STM32: Protocollo I2C e comunicazione con sensore Anno Accademico 2015/2016 Relatore Candidato Ch.mo prof. Rosario Schiano Lo Moriello Maria Concetta Turco matr. N46001685

Page 2: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

“Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente quel che vogliamo e siamo decisi ad ottenerlo”

Page 3: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Indice

Introduzione ........................................................................................................ 4

Capitolo 1: Microcontrollore STM32 ................................................................. 5

1.1 Board STM32F4Discovery ................................................................... 6

Capitolo 2: I2C (Inter-Integrated Circuit) ........................................................... 7

2.1 Realizzazione bus I2C .......................................................................... 9

2.2 I2C (STM32F4xx) .............................................................................. 12

2.3 Caratteristiche principali I2C .............................................................. 12

Capitolo 3: Il sensore ........................................................................................ 14

3.1 Interfaccia digitale di accelerazione lineare ............................................ 15

3.2 Interfaccia digitale campo magnetico ..................................................... 15

Capitolo 4: Registri ed implementazione .......................................................... 17

4.1 Trasmettitore master................................................................................ 19

4.2 Ricevitore master .................................................................................... 19

4.3 Trasmettitore slave .................................................................................. 20

4.4 Ricevitore slave ....................................................................................... 20

4.5 Implementazione ..................................................................................... 21

Conclusioni ....................................................................................................... 28

Bibliografia ....................................................................................................... 29

Page 4: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Introduzione

I primi microcontrollori sono nati negli anni ’70 come alternativa ai

microprocessori. Tuttavia, mentre il primo era utilizzato per applicazioni a scopo

più generale, il secondo, essendo un dispositivo elettronico digitale integrato che

integra in uno stesso chip il processore, la memoria permanente, la memoria

volatile e i pin di I/O oltre ad altri eventuali blocchi specializzati, viene utilizzato

nei sistemi per applicazioni specifiche di controllo digitale detti sistemi

embedded.

I microcontrollori della famiglia STM32 sono tra i più diffusi: li troviamo nelle

stampanti, negli scanner, nelle attrezzature mediche, nei sistemi di allarme, nei

video citofoni…

Infatti, essi sono stati progettati per interagire direttamente con il mondo esterno

tramite un programma residente nella propria memoria interna e mediante

l’utilizzo di pin specializzati o configurabili dal programmatore. Essi sono

disponibili in tre capacità elaborative: 8bit, 16 bit e 32 bit.

In questo elaborato verrà utilizzato il microcontrollore STM32F401xC per

analizzare e mostrare un esempio pratico di uno dei protocolli principali di

comunicazione tra i dispositivi: il protocollo Inter-Integrate Circuit (I2C).

4

Page 5: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Capitolo 1: Microcontrollore STM32

L’STM32 è un microcontrollore della STMicroeletronics, un‘azienda franco-

italiana, per la produzione di componenti elettronici a semiconduttore, a 32 bit

basato sul core ARM Cortex -M. Tale processore garantisce elevate prestazioni ed

offre numerosi vantaggi: eccellenti prestazioni di elaborazione con la gestione

dell’interrupt veloce, miglioramento del sistema di debug con l’introduzione di

ampie capacità di breakpoint, consumo di energia ultra-basso con modalità di

sospensione integrata, robustezza della security platform con unità di protezione

della memoria integrata(MPU).

Il Cortex riduce l’area del processore in quanto adopera componenti di sistema

fortemente accoppiati tra loro ed integra anche un controller delle interrupt

configurabile NVIC per interrupt non mascherabili.

L’insieme del core del processore e dell’NVIC fornisce una velocità di esecuzione

nell’ISR (Interrupt Service Routine) riducendo la latenza dell’interrupt stessa.

Il controllo del software può essere:

• PRIVILEGIATO: il software può utilizzare tutte le istruzioni e quindi ha

accesso a tutte le risorse;

• NON PRIVILEGIATO: non è possibile accedere al timer di sistema,

all’NVIC ed inoltre potrebbe anche essere limitato l’accesso alle memorie

e alle periferiche.

Il processore può operare nella modalità Thread, utilizzata per eseguire il software

applicativo, la quale può essere privilegiata e non; oppure in modalità Handler,

5

Page 6: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

utilizzata invece per gestire le eccezioni: in questo caso, l’esecuzione del software

è sempre privilegiato.

Il dispositivo presentato in questo elaborato è l’STM32F401xC che si basa

proprio sulle alte prestazioni dell’ARM Cortex M4 RISC a 32 bit.

Esso dispone di un’unità a virgola mobile (FPU) a singola precisione, implementa

le istruzioni DSP (Digital Signal Processor) e un’unità di protezione della

memoria MPU che migliora la sicurezza dell’applicazione.

1.1 Board STM32F4Discovery Nella board STM32Discovery si trova il microcontrollore

STM32F401VCT6 avente una memoria flash di 256 KB

e una memoria RAM di 64 KB in un pacchetto LQFP100.

Si alimenta attraverso il bus USB o attraverso un ingresso

esterno di 3V o 5 V. E’ dotato di alcuni sensori

appartenenti alla famiglia ST MEMS: un giroscopio

digitale a 3 assi L3GD20; un sistema-in-package dotato di

sensore di accelerazione lineare digitale 3D e di un

sensore magnetico digitale 3D LSM303DLHC; un

microfono digitale omnidirezionale MP45DT02. Presenta

inoltre un convertitore audio digitale-analogico DAC con

driver dell'altoparlante di classe D integrato CS43L22.

Su tale board sono integrati 8 LED: LD1 per la

comunicazione USB, che è rosso di default e verde nel

momento in cui le comunicazioni sono attive; LD2 di colore rosso che indica che

la board è attiva; quattro LED utente: LD3 (arancione), LD4 (verde), LD5 (rosso)

e LD6 (blu) connessi rispettivamente all’ I/O PD13, PD14, PD15, PD16

dell’STM32F401VCT6; due LED OTG USB: LD7 è di colore verde e indica

quando VBUS è presente su CN5 ed è connesso a PA9 dell’STM32F401VCT;

LD8, rosso, indica la sovracorrente da VBUS di CN5 ed è connesso all’I/O PD5

dell’STM32F401VCT.

Sono presenti inoltre due pulsanti, uno utente e uno di reset e un OTG USB con

micro-connettore AB.

6

Page 7: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Capitolo 2: I2C (Inter-Integrated Circuit)

La comunicazione tra due o più dispositivi elettronici avviene attraverso un

insieme di linee dette bus. Affinché tali elementi interagiscano tra di loro

correttamente, è necessario andare a stabilire delle specifiche di comunicazione

che vanno sotto il nome di protocollo.

L' I2C, Inter-Integrated Circuit, è un protocollo di trasmissione seriale: regola la

comunicazione tra due dispositivi in cui le informazioni, i bit, vengono inviati al

dispositivo che li riceve in modo sequenziale.

Questo tipo di comunicazione, detta half-duplex1, ha preso il sopravvento sulla

trasmissione parallela, perché più economica, richiede un minor numero di fili ed

è più robusta alle interferenze e agli errori di trasmissione.

Con il passare degli anni sono stati sviluppati vari standard che si differenziano

soprattutto per le diverse modalità di sincronizzazione.

Vi sono infatti 3 diversi tipi di comunicazione:

• SINCRONA: il trasmettitore invia i dati con una frequenza costante. Oltre

alla linea dati seriale SDA ve ne è anche un’altra seriale clock SCL.

Quindi, grazie al segnale di clock il ricevitore sa quando finisce ed inizia

l’invio di un nuovo bit.

• ASINCRONO: in questo tipo di comunicazione non vi è alcun tipo di

sincronizzazione tra il trasmettitore e il ricevitore. Il trasmettitore quando

è pronto invia prima un bit di START che segnala l’inizio della

7

Page 8: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

trasmissione, poi i dati effettivi, un bit di parità opzionale che controlla se

si sono verificati errori durante la trasmissione, ed infine un bit di STOP

per indicare la fine della trasmissione direttamente al ricevitore.

• ISOCRONA: questo tipo di tecnica di trasmissione si ottiene quando si

vuole far comunicare un dispositivo di tipo sincrono con uno di tipo

asincrono.

Si evince, dunque, che l’I2C è un sistema di comunicazione seriale sincrona

bifilare, proprio perché l’interfaccia I2C è collegata al bus fisico attraverso due

segnali bidirezionali, uno dati, SDA, e uno clock, SCL.

La periferica I2C presente nell’STM32 funge da interfaccia tra il microcontrollore

e il bus I2C seriale. Esso supporta la modalità standard fino a 100kHz e la

modalità FM fino a 400kHz, ma la frequenza dell’I2C può essere aumentata fino a

1MHz.

Per quanto riguarda le caratteristiche dell’interfaccia I2C, essa soddisfa i requisiti

del protocollo di comunicazione I2C standard ma ha delle limitazioni: i pin I/O,

SDA e SCL sono mappati per non essere dei veri Open-Drain2, però quando sono

configurati come tali, il PMOS3 collegato tra il pin di I/O e VDD è disabilitato.

1 Comunicazione in entrambe le direzioni ma non simultaneamente. 2 Un terminale viene connesso a massa quando un valore di tensione alto viene applicato al gate mentre presenta un’alta impedenza quando viene applicato al gate un valore basso di tensione. 3 Particolare tipo di transistori MOS che si “accendono” solo se il transistore presente al loro gate è minore della loro soglia di transizione.

8

Page 9: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

2.1 Realizzazione bus I2C Per realizzare un bus I2C occorrono due resistenze di pull-up collegate

all’alimentatore standard VDD, una per ciascuno dei due segnali SDA e SCL.

Nell’I2C la comunicazione avviene tra due dispositivi, detti MASTER e SLAVE,

dove il master controlla il bus ed emette il segnale di clock, mentre lo slave si

limita a ricevere e a sincronizzarsi sul segnale di clock senza poterlo, però

controllare.

Il numero di dispositivi che possono essere collegati dipende dalla massima

capacità parassita del bus.

9

Page 10: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Il master inizia la comunicazione con la generazione di un segnale di START,

transizione dal livello logico alto verso il basso dell’SDA, mentre l’SCL è alto.

Invio segnale di START

In seguito invia l’indirizzo dello slave che può essere di lunghezza pari a 7 o 10

bit con il quale vuole comunicare ed un altro bit per indicare se vuole inviare o

ricevere dati dallo slave.

Quando viene inviato un indirizzo, ogni dispositivo verifica se tale indirizzo

coincide con il proprio; se così fosse allora esso stesso si considererebbe

indirizzato dal master. Una volta riconosciuto lo slave indirizzato esso prende il

controllo dalla linea SDA sul successivo impulso alto di clock e la forza bassa

(ACK4). Il protocollo I2C richiede che ogni byte trasmesso deve essere concluso

con l’invio di un ACK o un NACK5, dove la condizione di ACK identifica la

corretta ricezione di un byte mentre il NACK indica di conseguenza un errore

nella ricezione dei dati.

Invio segnale di ACK

4 Acknowledge

10

Page 11: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Quando viene ricevuto il segnale NACK il master può generare una condizione di

STOP o una condizione di RESTART. Se il master invia un segnale di STOP,

vuole dire che non viene trovato nessun indirizzo slave corrispondente e dunque

quest’ultimo lascia l’SDA a valore logico alto così che il master può interrompere

il trasferimento; se invece il master invia un segnale di RESTART, esso senza

perdere il controllo del bus può riavviare un nuovo trasferimento dati.

.

Invio segnale di STOP

Quando lo slave, invece, è riconosciuto, viene trasmesso un sub-address a 8 bit

(SUB), dove i 7 bit meno significativi rappresentano l’indirizzo del registro

effettivo mentre il MSB6 consente l’incremento automatico dell’indirizzo.

Se il MSB nel campo SUB è pari a 1, l’indirizzo del registro viene

automaticamente incrementato per consentire letture o scritture multiple.

Invio e ricezione di un bit

5 Not Acknowledge

11

Page 12: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Il numero di byte per il trasferimento è illimitato, se però un ricevitore non può

ricevere un altro intero byte, esso può mantenere la linea SCL bassa così da

forzare il master in una condizione di attesa. Il trasferimento riprende solo quando

il ricevitore, lo slave, è pronto per ricevere un altro byte e rilascia la linea dati.

2.2 I2C (STM32F4xx) I microcontrollori STM32F4xx posseggono fino a 3 periferiche per l’utilizzo del

bus I2C: I2C1, I2C2, I2C3 che possono operare in modalità multimaster e slave.

Tutte e tre le periferiche sono connesse al bus APB1 a 42MHz. Attraverso

l’apposita interfaccia è possibile dunque la trasmissione dei dati.

2.3 Caratteristiche principali I2C L’I2C supporta la modalità multimaster, ovvero sullo stesso bus possono essere

presenti più master. Tale modalità comporta l’utilizzo di una procedura di

arbitraggio ottenuta attraverso il controllo delle linee SDA ed SCL.

L’interfaccia I2C può funzionare in modalità master o slave. Nel caso si trovi in

modalità master può generare segnali di clock, START e STOP, mentre se si trova

in modalità slave, rileva il bit di STOP generato dal master, rileva l’indirizzo I2C

e può riconoscere anche 2 indirizzi slave.

Essa supporta la generazione e l’individuazione di indirizzi a 7 o 10 bit ed anche

differenti velocità di comunicazione: fino a 100 kHz per la velocità standard e fino

a 400 kHz per l’alta velocità, ma la frequenza del bus I2C può essere aumentata

fino a 1MHz.

L’I2C possiede filtri sia analogico del rumore che digitale programmabile; flag di

stato per indicare la fine del byte di trasmissione, per specificare se il bus è

occupato o meno e se si tratta di un trasmettitore o un ricevitore; flag di errore per

indicare il mancato riconoscimento dopo la trasmissione dell’indirizzo o dei dati,

l’errato rilevamento della condizione di START o STOP e l’overrun6 o

l’underrun7 se il clock stretching8 è disattivato.

6 Superamento della dimensione massima del buffer andando a sovrascrivere spazi di memoria adiacenti 7 Condizione in cui la lettura o la scrittura del buffer è alimentato con dati ad una velocità più lenta di quanto richiesto

12

Page 13: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Un’altra caratteristica fondamentale dell’I2C è l’utilizzo di 2 condizioni di

interrupt: la prima serve per indicare che la trasmissione dell’indirizzo o dei dati è

andata a buon fine, la seconda per la condizione di errore. Infine possiede un

buffer di 1 byte con capacità di un DMA (Direct Memory Access).

8 Opzionale. Meccanismo preposto a rallentare la velocità di clock proposta dal master in quanto lo slave non riesce a cooperare con esso

13

Page 14: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Capitolo 3: Il sensore

L’accelerometro è un dispositivo in grado di misurare l’accelerazione mediante il

calcolo della forza rilevata rispetto alla massa dell’oggetto.

Lo possiamo immaginare come una

sfera posta al centro di un cubo

sospesa mediante l’utilizzo di 3 molle

ortogonali tra loro che sono a loro

volta agganciate al centro di ogni

faccia del cubo. Muovendo il cubo

nello spazio, la sfera al suo interno si

muoverà ed così possibile andare a

misurare il grado di compressione9

dovuto all’allungamento e alla

compressione delle molle.

L’accelerometro oggigiorno è utilizzato nella maggior parte delle applicazioni

tecnologiche come smartphone, tablet e può essere ad uno, due o tre assi.

Il system-in-package LSM303DLHC è un sistema che supporta l’accelerazione

lineare digitale 3D e un sensore di rilevamento del campo magnetico digitale 3D.

Infatti, grazie all’interfaccia I2C prima introdotta è possibile misurare sia

l’accelerazione lineare che il campo magnetico ad esso applicato per mostrare poi

l’output in formato digitale. L’LSM303DLHC è dotato di due segnali di dati

pronti (RDY) che indicano quando sono disponibili un nuovo set di dati di

9 Permette di stabilire se c’è stata un’accelerazione e in caso affermativo ci informa anche sulla relativa direzione

14

Page 15: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

accelerazione misurati e dati magnetici andando così a semplificare la

sincronizzazione dei dati nel sistema che usano il dispositivo.

La sensibilità dell’accelerazione lineare descrive il guadagno del sensore

accelerometro e può essere determinato applicando 1g di accelerazione ad esso.

La misurazione può essere effettuata puntando l’asse d’interesse verso il centro

della Terra, rilevare il valore di uscita, ruotare il sensore di 180° e rilevando di

nuovo il valore di uscita. Cosi facendo viene applicato ± 1 g di accelerazione al

sensore. Sottraendo il valore di uscita grande da quella più piccola e dividendo il

risultato per 2 porta alla effettiva sensibilità del sensore.

3.1 Interfaccia digitale di accelerazione lineare L’invio dell’indirizzo slave viene completato con un ulteriore bit per indicare il

tipo di operazione da effettuare, lettura o scrittura. Se il bit è 1 vi sarà una lettura,

quindi dopo i due sub-address byte deve essere inviata una condizione di START

ripetuta.

Se invece il bit è 0 vi sarà una scrittura e quindi il master trasmette allo slave ma

con direzione invariata.

Per leggere più byte è fondamentale il settaggio del bit più significativo del sub-

address. Ciò vuol dire che il MSB deve essere pari a 1 mentre i restanti bit

rappresentano l’indirizzo del primo indirizzo da leggere. L’LSM303DLHC

prevede due modalità di funzionamento, l’accelerazione in modalità normale che

garantisce un’elevata risoluzione e la modalità a basso consumo che invece riduce

ulteriormente il consumo di corrente.

3.2 Interfaccia digitale campo magnetico Come per l’interfaccia digitale di accelerazione lineare anche per l’interfaccia

digitale del campo magnetico l’invio dell’indirizzo slave viene completato con un

ulteriore bit per indicare il tipo di operazione da effettuare, lettura o scrittura. Se il

bit è 1 vi sarà una lettura, quindi dopo i due sub-address byte deve essere inviata

una condizione di START ripetuta.

Se invece il bit è 0 vi sarà una scrittura e quindi il master trasmette allo slave ma

con direzione invariata.

15

Page 16: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Tale interfaccia utilizza un puntatore di indirizzo per indicare la locazione dalla

quale leggere o nella quale scrivere. Tali locazioni sono inviati dal master al

dispositivo slave seguito dall’indirizzo di 7 bit più un bit per indicare una lettura o

scrittura.

L’LSM303DLHC permette l’incremento automatico del puntatore che porta

all’aggiunta di due caratteristiche molto importanti:

1. Quando si accede all’indirizzo 12 o superiore, il puntatore modifica l’indirizzo

a 00;

2. Quando si raggiunge l’indirizzo 08, il puntatore torna indietro all’indirizzo 03

16

Page 17: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Capitolo 4: Registri ed implementazione

L’interfaccia I2C può funzionare in 4 diverse modalità:

• Trasmettitore slave

• Ricevitore slave

• Trasmettitore master

• Ricevitore master

Tale interfaccia funziona per default in modalità slave.

Il passaggio da master -> slave avviene automaticamente se si verifica una

condizione di arresto, mentre il passaggio da slave -> master avviene dopo una

condizione di start.

Analizziamo quali sono i registri interessati e i relativi settaggi.

Sappiamo che l’I2C per default funziona in modalità slave andando ad impostare

il bit START nel registro I2C_CR1 alla modalità master dopo aver riportato a

zero il bit BUSY del registro I2C_SR2.

Il bit BUSY vale 0 se non vi sono comunicazioni sul bus, altrimenti se il bus è già

occupato vale 1.

17

Page 18: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Esso viene settato via hardware sul rilevamento dell’SDA o SCL basso o tramite

una condizione di STOP.

Il bit SB (Start Bit) del registro I2C_SR1 quando è in modalità master e non vi è

nessuna condizione di start assume valore 0, altrimenti 1.

Può essere resettato via software da una lettura del registro SR1 seguita da una

lettura del registro DR o via hardware quando il bit PE, peripheral enable, del

registro I2C_CR1 è pari a 0 e quindi la periferica è disabilitata.

Successivamente il master attende una lettura del registro SR1 seguita da una

scrittura nel registro DR con l’indirizzo slave.

Viene poi inviato sulla linea SDA l’indirizzo slave.

Il bit ADDR del registro I2C_SR1 è impostato via hardware. Esso può

comportarsi sia da master che da slave e viene riportato a zero via software

leggendo il registro SR1 seguito da una scrittura di SR2 o via hardware quando

PE è pari a 0.

Per la modalità slave se tale bit è pari a 1 è stato trovato un indirizzo

corrispondente a quello ricevuto, in caso contrario vale 0; mentre per la modalità

master se il trasferimento dell’indirizzo non è ancora terminato il bit ADDR sarà

pari a 0, altrimenti vale 1.

Per azzerare i flag associati all’indirizzo, il master esegue una lettura del registro

SR1 seguita da una lettura del registro SR2. Arrivati a questo punto il master può

decidere se mettersi in modalità trasmettitore o ricevitore a seconda dell’LSB10

dell’indirizzo slave inviato. Se esso è pari a 0 il master sarà in modalità

trasmettitore altrimenti ricevitore con bit pari a 1.

10 Least Significant Bit

18

Page 19: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

4.1 Trasmettitore master A questo punto il master invia il byte dal registro DR all’SDA tramite il registro

di scorrimento interno. Il master attende finché viene scritto il primo byte nel

registro I2C_DR. Quando viene ricevuto l’impulso di riconoscimento, il bit TxE

del registro I2C_SR1 è settato.

Se TxE è configurato e il byte di dati trasmesso non è stato scritto nel registro

prima dell’ultima trasmissione dati, il bit BTF del registro I2C_SR1 viene portato

a livello logico alto e l’interfaccia attende finché BTF non viene riportato a zero

da una scrittura I2C_DR che porta SCL a livello logico basso.

TxE vale 0 quando il Data Register non è vuoto altrimenti vale 1.

Tale bit viene azzerato via software da una scrittura nel registro DR o via

hardware dopo una condizione di START o STOP o quando PE è pari a 0.

Il bit BTF vale 0 nel caso in cui il trasferimento byte non è terminato, in caso

contrario vale 1. Esso viene impostato a zero via hardware sia in ricezione,

quando viene ricevuto un nuovo byte, includendo anche l’impulso ACK, e il DR

non è stato ancora letto (RxNE=1), che in trasmissione quando deve essere inviato

un nuovo byte e non è stato ancora scritto nel DR (TxE=1).

BTF può essere azzerato via software da una lettura o una scrittura nel registro

DR oppure via hardware in seguito ad una condizione di START o STOP.

Al termine della scrittura dell’ultimo byte nel registro DR occorre impostare via

software il bit STOP nel registro I2C_CR1 per generare una condizione di arresto.

Una volta fatto ciò l’interfaccia torna automaticamente alla modalità slave.

4.2 Ricevitore master Se invece il master si comporta come un ricevitore, dopo l’invio dell’indirizzo e

dopo aver portato a zero il bit ADDR, l’I2C si mette in modalità ricevitore master

acquisendo così byte dall’SDA nel registro DR. Dopo ogni byte viene

riconosciuto l’impulso se il bit ACK e il bit RxNE sono impostati a 1.

Se il bit RxNE del registro I2C_SR1 è impostato a 1 e i dati nel registro DR non

sono stati letti prima dell’ultima ricezione dei dati, il bit BTF viene impostato a

valore logico alto e l’interfaccia attende finché esso non viene riportato a zero da

una lettura nel registro DR che porta SCL a livello logico basso.

19

Page 20: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Il bit RxNE è configurato a livello logico alto quando il DR non è vuoto in

modalità ricevitore ed è riportato a zero via software da una lettura o scrittura del

registro DR o via hardware quando PE è pari 0.

Infine per chiudere la comunicazione il master invia un NACK per l’ultimo byte

ricevuto dallo slave.

Lo slave, ricevuto il NACK, rilascia il controllo dell’SDA e dell’SCL così che il

master può inviare una condizione di STOP o RESTART.

Come per il master, anche lo slave può trovarsi in modalità ricevitore e

trasmettitore. Ciò viene indicato dal bit TRA nel registro I2C_SR2, il quale se è 0

sono stati ricevuti i byte dati, se è 1 i byte dati sono stati trasmessi.

4.3 Trasmettitore slave Dopo la ricezione dell’indirizzo e dopo aver pulito il bit ADDR, lo slave invia il

byte dal registro DR sull’SDA tramite il registro a scorrimento interno. Lo slave

tiene basso l’SCL fino a quando l’ADDR non viene portato a zero e il DR non

viene riempito con i dati da trasmettere. Quando viene ricevuto l’impulso di

riconoscimento, se il bit TxE si trova a livello logico alto e i dati non sono stati

ancora scritti nel registro I2C_DR prima della fine della trasmissione, il bit BTF

viene settato e l’interfaccia attende finché quest’ultimo non viene controllato da

una lettura di I2C_SR1 seguita da una scrittura nel registro I2C_DR che porta

SCL basso.

4.4 Ricevitore slave Dopo aver ricevuto l’indirizzo e dopo aver riportato a zero il bit ADDR, lo slave

riceve il byte dall’SDA nel registro DR tramite il registro a scorrimento interno.

Dopo ogni byte ricevuto, l’interfaccia genera un impulso di riconoscimento se il

bit ACK è a livello logico alto e imposta il bit RxNE a 1.

Se il bit RxNE è impostato a 1 e i dati del registro DR non vengono letti prima

della fine della prossima ricezione dati, il bit BTF è portato a livello logico alto e

aspetta finché esso non viene portato a zero da una lettura del registro I2C_DR

che tiene SCL basso.

20

Page 21: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Al termine dell’ultimo trasferimento, viene generata una condizione di STOP dal

master. L’interfaccia rileva questa condizione e setta il bit STOPF del registro

I2C_SR1 così da generare un interrupt quando il bit ITEVTEN è abilitato. Il bit

STOPF assume valore 0 se non viene rilevata nessuna condizione di arresto

altrimenti sarà pari a 1.

Tale bit viene portato a valore logico alto dall’hardware quando viene rilevata la

condizione di stop sul bus dallo slave dopo un ACK, e viene invece portato a 0 via

software leggendo il registro SR1 seguito da una scrittura nel registro CR1 o via

hardware quando PE è pari a 0.

4.5 Implementazione Vediamo adesso un esempio di utilizzo del protocollo I2C e la comunicazione con

il sensore nel microcontrollore STM32F4xx. Il seguente codice mostra la

configurazione dell’accelerometro e la lettura degli assi x, y, z.

#include "stm32f4xx.h"

#define SB 0x1

#define ADDR 0x2

#define BUSY 0x2

#define BTF 0x4

#define RxNE 0x40

#define TxE 0x80

#define N 6

short int x,y,z;

short int dummy;

short int buffer[N]={0};

int main(){

RCC->APB1ENR |= 1<<21; //Abilito I2C1

RCC->AHB1ENR |= 1<<1; //Abilito GPIOB

//Configurazione PB6 e PB9

GPIOB->MODER |= (1<<13 | 1<<19); //Setto PB6 e PB9 in modalità

//Alternate Function

21

Page 22: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

GPIOB->OTYPER |= (1<<6 | 1<<9); //Setto PB6 e PB9 in modalità

// Open-Drain

GPIOB->PUPDR |= (1<<12 | 1<<18); //Setto P6 e P9 in Pull-Up ->

//comunicazione basso-alto più

//veloce

GPIOB->AFR[0] |= 1<<26; //AF4 per PB6

GPIOB->AFR[1] |= 1<<6; //AF4 per PB9

//Configurazione I2C1

//L'accelerometro lavora ad una frequenza di 100 KHz

//Le seguenti istruzioni servono per impostare I2C1 affinché

//lavori a tale frequenza

I2C1->CR1 |= 1; //Abilito la periferica I2C attraverso il bit PE

I2C1->CR1 &= ~(0x2); //Abilito il bus in modalità I2C

I2C1->CR2 |= 1<<3; //Metto la frequenza di clock della

//periferica a fclock = 8 MHz

I2C1->CCR &= (0<<15 | 0<<14); //Metto DUTY=0 perché non voglio

//il duty cycle. Metto FS=0 perché

//voglio lavorare in STANDARD MODE

I2C1->CCR |= 0x28; //Mettiamo la CCR = 5us * fclock

I2C1->TRISE |= 9; //Perché è pari a fclock+1

//Configurazione accelerometro

//SCRITTURA MULTIPLA

while ((I2C1->SR2 & (uint16_t)BUSY) ==1); //Aspetto che il bus

// sia libero

I2C1->CR1 |= 1<<8; //Genero Start Condition attraverso il bit

//START

while((I2C1->SR1 & (uint16_t)SB)==0); //Aspetto che la Start

//Condition sia stata

//generata

dummy = I2C1->SR1; //Pulisco il bit SB(leggo il registro SR1)

//Invio Slave Address

I2C1->DR = 0x32; //Modalità scrittura

while ((I2C1->SR1 & (uint16_t)ADDR)==0); //Aspetto che

//l'indirizzo venga

//matchato

22

Page 23: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

//Pulisco il bit ADDR attraverso una lettura dei registri SR1 ed

//SR2

dummy = I2C1->SR1;

dummy = I2C1->SR2;

//Invio configurazione(SUB Address)

while((I2C1->SR1 & (uint16_t)TxE) == 0); //Aspetto che il buffer

//di trasmissione sia

//vuoto (TxE=1)

I2C1-> DR =0x20; //Pulisco il bit TxE inviando al registro DR il

//registro nel quale voglio scrivere

//CTRL_REG1_A (20h)

while((I2C1->SR1 & (uint16_t)TxE) == 0); //Aspetto che il buffer

//di trasmissione sia

//vuoto (TxE=1)

I2C1-> DR = 0x17; //Pulisco il bit Txe inviando al registro DR

//la configurazione del registro CTRL_REG1_A:

//0x17=00100111 , dove:

//0010(Normal/low-power mode(10 Hz))

//0111(abilito gli assi x,y,z)

//Visto che è l'ultima trasmissione controllo oltre al bit TxE

//anche il bit BTF, attendo quindi che il buffer di trasmissione

//sia vuoto e che il trasferimento sia terminato

while(((I2C1->SR1 & (uint16_t)TxE) == 0) && (I2C1->SR1 &

(uint16_t)BTF) == 0);

I2C1->CR1 |= 1<<9; //Genero Stop Condition attraverso il bit

//STOP

//LETTURA MULTIPLA DEI VALORI DEI 3 ASSI

while(1){

while((I2C1->SR2 & (uint16_t)BUSY) == 1); //Attendo che il bus è

//libero

I2C1->CR1 |= 1<<8; //Genero Start Condition attraverso il bit

//START

while((I2C1->SR1 & (uint16_t)SB) == 0); //Attendo che la Start

//Condition sia stata

//generata

dummy = I2C1->SR1; //Pulisco il bit SB(leggo il registro SR1)

23

Page 24: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

//Invio Slave Address

I2C1->DR = 0x32; //Modalità scrittura

while ((I2C1->SR1 & (uint16_t)ADDR) == 0); //Attendo che

//l'indirizzo venga

//matchato

//Pulisco il bit ADDR attraverso una lettura dei registri SR1 ed

//SR2

dummy = I2C1->SR1;

dummy = I2C1->SR2;

//Invio registro da cui voglio leggere (SUB Address)

while((I2C1->SR1 & (uint16_t)TxE) == 0); //Attendo che il buffer

//di trasmissione sia

//vuoto

I2C1->DR = (0x28)|(0x80); //Invio il registro OUT_X_L_A e sommo

//anche 1 al primo bit così dopo ogni

//lettura il registro si

//incrementerà

//Visto che è l'ultima trasmissione controllo oltre al bit TxE

//anche il bit BTF, attendo quindi che il buffer di trasmissione

//sia vuoto e che il trasferimento sia terminato

//Verifico che l'indirizzo sia completamente inviato e BTF è

//basso

while(((I2C1->SR1 & (uint16_t)TxE)==0) && ((I2C1->SR1

&(uint16_t)BTF)==0));

I2C1->CR1 |= 1<<8; //Genero Start(Restart)Condition attraverso

//il bit START

while((I2C1->SR1 & (uint16_t)SB) == 0); //Attendo che la Start

//Condition sia stata

//generata

dummy = I2C1->SR1; //Pulisco il bit SB (leggo il registro SR1)

I2C1->CR1 |= 1<<10; //Setto il bit ACK(per inviare una conferma

//di ricezione dopo la ricezione di un byte

//Invio Slave Address

I2C1->DR = 0x33; //Modalità lettura

while ((I2C1->SR1 & (uint16_t)ADDR) == 0); //Attendo che

//l'indirizzo venga

//matchato

24

Page 25: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

//Pulisco il bit ADDR attraverso una lettura dei registri SR1 ed

//SR2

dummy = I2C1->SR1;

dummy = I2C1->SR2;

//Trasmissioni multiple

for (int i=0; i<6; i++){

while((I2C1->SR1 & (uint16_t)RxNE) == 0); //Attendo che il

//buffer di

//ricezione sia

//pieno(RxNE=1)

buffer[i] = I2C1->DR; //Ricevo il dato

if(i==4) //Se siamo alla penultima ricezione

I2C1->CR1 &=0xFBFF; //Setto il bit ACK a 0, cosicché

//all'ultimo ciclo verrà inviato il NACK

}

I2C1->CR1 |= 1<<9; //Genero Stop Condition attraverso il bit

//STOP

x = ((int16_t)((uint16_t)buffer[1]<<8) + buffer[0])/16;

y = ((int16_t)((uint16_t)buffer[3]<<8) + buffer[2])/16;

z = ((int16_t)((uint16_t)buffer[5]<<8) + buffer[4])/16;

}

}

25

Page 26: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Se invece vogliamo effettuare una singola lettura il codice è il seguente:

//LETTURA SINGOLA

while((I2C1->SR2 & (uint16_t)BUSY) == 1); //Aspetto che il bus sia

//libero

I2C1->CR1 |= 1<<8; //Genero Start Condition attraverso il bit

//START

while((I2C1->SR1 & (uint16_t)SB) == 0); //Aspetto che la Start

//Condition sia /stata

//generata

dummy=I2C1->SR1; //Pulisco il bit SB (leggo il registro SR1)

//Invio Slave Address

I2C1->DR = 0x32; //Modalità scrittura

while((I2C1->SR1 & (uint16_t)ADDR) == 0); //Aspetto che

//l’indirizzo venga

//matchato

//Pulisco il bit ADDR attraverso una lettura dei registri SR1 ed

//SR2

dummy=I2C1->SR1;

dummy=I2C1->SR2;

//Invio configurazione (SUB Address)

while((I2C1->SR1 & (uint16_t)TxE) == 0); //Aspetto che il buffer

//di trasmissione sia

//vuoto(TxE=1)

I2C1->DR = 0x20; //Pulisco il bit TxE inviando al registro DR il

//registro nel quale voglio scrivere

//CTRL_REG_A(20h)

//Controllo il bit TxE ed il bit BTF. Attendo quindi che il buffer

//di trasmissione sia vuoto e che il //trasferimento sia terminato

while(((I2C1->SR1 & (uint16_t)TxE) == 0) && ((I2C1->SR1 &

(uint16_t)BTF) == 0));

I2C1->CR1 |= 1<<8; //Genero Start (Restart) Condition attraverso

//il bit START

26

Page 27: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

while((I2C1->SR1 & (uint16_t)SB) == 0); //Attendo che la Start

//Condition sia stata

//generata

//Invio Slave Address

I2C1->DR = 0x33; //Modalità lettura

while((I2C1->SR1 & (uint16_t)ADDR) == 0); //Attendo che

//l’indirizzo venga

//matchato

//Pulisco il bit ADDR attraverso una lettura dei registri SR1 ed

//SR2

dummy=I2C1->SR1;

dummy=I2C1->SR2

while((I2C1->SR1 & (uint16_t)RxNE) == 0); //Attendo che il buffer

//di ricezione sia

//pieno(RxNE=1)

data=I2C1->DR; //Ricevo il dato

I2C1->CR1 |=1<<9; //Genero Stop Condition attraverso il bit STOP

27

Page 28: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Conclusioni

In questo elaborato è stato utilizzato il microcontrollore STM32F401xC, basato su

ARM Cortex M4 per offrire prodotti dalle prestazioni molto elevate, dal

funzionamento a bassa tensione e dalla bassa potenza pur garantendo un elevata

efficienza, e l’utilizzo per piccoli e per grandi progetti.

In particolare, è stato analizzato e mostrato un esempio pratico di uno dei

protocolli principali di comunicazione tra i dispositivi: il protocollo Inter-Integrate

Circuit (I2C).

Dopo aver descritto l’accelerometro, si è analizzato come il protocollo regola la

trasmissione tra un dispositivo master e uno slave, la sua realizzazione, le

caratteristiche principali, l’insieme dei registri e i relativi settaggi che ne

permettono un’implementazione pulita nell’STM32F4xC.

I microcontrollori oggigiorno sono in continua evoluzione. Nonostante essi non

siano idonei per utilizzi generici ma più specifici, utilizzabili quindi in campi più

limitati, possiamo dire che nello specifico campo, svolgono il lavoro nel modo più

efficiente possibile.

28

Page 29: Programmazione di microcontrollori STM32: Protocollo I2C e ... · “Sono i sogni a far vivere l'uomo. Il destino è in buona parte nelle nostre mani, sempre che sappiamo chiaramente

Bibliografia

[1] STMicroeletronics group, RM0368 Reference Manual, 2014, 835

[2] STMicroeletronics grouop, Ultra-compact high-performance

eCompass module: 3D accelerometer and 3D magnetometer , 2013, 42

[3] STMicroeletronic group, ARM Cortex –M4 32b MCU+FPU, 150

DMIPS, 256 KB Flash/64KB RAM, 11 TIMs, 1 ADC, 11 comm.

interfaces, 2014, 134

[4] STMicroeletronics, http://www.st.com

29