• Non ci sono risultati.

6. Il Firmware

6.1.4 Utilizzo dell’interfaccia SPI

Con 10bit quindi si ha una rappresentazione con valori che vanno da 0 a 1024; mentre utilizzando 8bit (cioè utilizzando i valori del solo registro ADCL) è possibile rappresentare il risultato su 256 valori.

6.1.4 Utilizzo dell’interfaccia SPI

Nel prototipo realizzato il dispositivo configurato come master, capace quindi di generare il clock, è il microcontrollore mentre l’unico dispositivo slave presente nel sistema è il sensore d’accelerazione. I registri che permettono di configurare e monitorare il trasferimento tramite SPI sono SPCR e SPSR, i dati ricevuti o da trasmettere sono contenuti nel registro SPDR.

Figura 79

Tramite il bit7 si abilita l’interruzione mentre mettendo a 1 il bit6 si abilita la porta l’SPI. Quando il bit5 (DORS) è posto a uno il primo bit della trasmissione è il bit LSB se posto a 0 il primo bit trasmesso è MSB; il bit4 consente di impostare il

microcontrollore come master o slave. I bit3-2 consentono di stabilire la polarità del clock come mostrato in figura 80 e in figura 81.

Figura 80 Trasferimento SPI con CPHA=0

Per ottenere una corretta comunicazione con lo Slave è fondamentale settare

correttamente questi bit, per sapere quale modalità va impiegata è necessario consultare il datasheet del componente Slave. Nel cado dell’accelerometro impiegato per il

prototipo è stato necessario impostare la modalità CPHA=1, CPOL=1 questo per

rendere la trasmissione compatibile con le temporizzazioni riportate nel paragrafo 5.3.2.

Tramite i bit1-0 e il bit SPI2x del registro SPSR si imposta la frequenza di trasmissione secondo i valori riportarti in tabella.

Tabella 8

Il bit7 (SPIF) è un bit di flag che ci consente di controllare quando il trasferimento è ultimato; infatti questo bit resta a 0 per tutta la durata del trasferimento dati e torna a 1 al termine.

Figura 82

La funzione SPI_init( ) sotto riporta, imposta i piedini per la linea SPI e configura il registro SPCR ponendo il bit PSE=1 per abilitare l’SPI, DORD=0 per trasmettere come primo bit LSB MSTR=1 configurando il microcontrollore come Master, CPOL e CPOH=1 per sincronizzare l’invio dei dati sul fronte di salita del clock come richiesto dall’accelerometro e i bit SPR1 e SPR0 per avere un fattore di prescalar pari a fck/16 cioè 500KHz. Fortunatamente i registri per la gestione dell’SPI dell’ ATmega128L e ATmaga16L sono identici, questo semplifica notevolmente al sezione di preprocessor dedicata che si riduce ad assegnare a DDR_SPI, SPIDI, SPICLK, SPIDO, SPICS i

rispettivi pin delle porteB a seconda del microcontrollore utilizzato (vedi paragrafo 6.2.6).

//--- //Funzione setup SPI

//_________________________________

void SPI_init(void) {

cbi(DDR_SPI, SPIDI); // PBx come SPI data input (MISO)

sbi(DDR_SPI, SPICLK); // PBx come SPI clock output

sbi(DDR_SPI, SPIDO); // PBx come SPI data out (MOSI)

sbi(DDR_SPI, SPICS); // PBx come uscita di chip select

outp((1 << SPE) | (0<<DORD) | (1 << MSTR) | (0<< SPR1) |( 1<<CPOL) | (1<<CPHA) | (1 << SPR0),SPCR); //frequenza di trasmissione fck/16

sbi(PORTB, 4); // pongo CS a 1 }

La funzione write register( ) consente la scrittura di un registro dell’accelerometro; come mostrato nella temporizzazione riportata in figura nel paragrafo 5.3.2 per accedere ad un registro dell’accelerometro in scrittura è necessario inviare per primo un byte nel quale il bit0 (RW) sia 0 ad indicare che si sta accedendo per effettuare una scrittura il bit1 (MS) va posto a 1 o a 0 a seconda che si voglia far incrementare l’indirizzo del registro in maniera automatica o meno e nei restati sei bit (bit2-7) deve essere indicato l’indirizzo del registro nel quale il bit2 corrisponde al MDB e il bit7 al LSB.

Alla funzione di scrittura vengono passate dall’esterno le variabile che contengono l’indirizzo del registro (register_name ) e il dato che si desidera scrivere (data ).

La funzione inserisce l’indirizzo nel registro SPCR partendo dal bit0 con LSB mettendo RW nel MSB; per ottenere l’invio partendo dal MSB è necessario porre a 1 il bit5 (DORS) del registro SPCR. Il termine dell’invio si ha quando il bit di flag (SPIF) torna a 1 a questo punto viene caricato nel registro SPDR il dato da inviare, una volta che i dati sono stati inviati e si è ricevuta conferma dal flag SPIF la funzione riporta CS a 1 per indicare la fine della comunicazione con l’accelerometro.

// --- // scrittura in un registro dell' accelerometro //__________________________________

void write register(char register_name, char data) {

// pone a 0 il bit 0 per indicare che stiamo scrivendo nell'accelerometro

cbi(register_name,7);

cbi(register_name,6);//pone a 0 il bit1 per non incrementare gli indirizzi

cbi(PORTB, 4); // pongo CS a 0 quindi attivo l'accelerometro

SPDR= register_name;

while (!(SPSR & (1<<SPIF))) {};//aspetto che il trasferimento degli 8 bit sia terminato

// invio i dati da mettere nel registro

SPDR = data; //scrivo i dati nel registro di trasferimento SPDR

while (!(SPSR & (1<<SPIF))) {};//aspetto che il trasferimento degli 8 bit sia terminato

sbi(PORTB, 4); // pongo CS a 1 fine della trasmissione

}

La funzione che permette la lettura di un registro dell’accelerometro è la spi_read( ) alla quale viene passato dall’esterno l’indirizzo del registro a cui accedere e al termine della lettura restituisce il valore contenuto in tale registro “return (dato_ricevuto)”.

Per accedere ad un registro dell’accelerometro in lettura è necessario inviare un byte nel quale il bit0 (RW) sia 1 ad indicare che si sta accedendo per effettuare una lettura, il bit1 (MS) va posto a 1 o a 0 a seconda che si voglia far incrementare l’indirizzo del registro in maniera automatica o meno e nei restati sei bit (bit2-7) viene messo l’indirizzo del registro del cui vogliamo leggere il contenuto; nel quale il bit2 corrisponde al MDB e il bit7 al LSB. Una volta inviato il byte con l’indirizzo

l’accelerometro mette il valore contenuto in tale registro nel registro di trasmissione che comunica con il microcontrollore, quindi è necessario un nuovo ciclo di lettura per fare in modo che gli shift register si scambino i valori e quindi che venga “ciclato” nel registro SPDR il contenuto di nostro interesse. Al termine di questa operazione il contenuto di tale registro viene copiato nella variabile “dato_ricevuto” che lo riporta all’esterno della funzione.

//--- // lettura di un registro dell' accelerometro //________________________________

char spi_read(char register_name) {

char dato_ricevuto = 0;

// invio l'indirizzo del registro

//pone a 1 il bit 0 per indicare che stiamo leggendo nell'accelerometro

sbi(register_name,7);

cbi(register_name,6); //pone a 0 il bit1 per non incrementare gli indirizzi

SPDR= register_name;

while (!(SPSR & (1<<SPIF))) {}; // si attende il termine dell'invio del byte //dell'indirizzo

SPDR=0; // nova trasmissione per far shiftare i dati del

//registro che si vuole leggere nel registro SPDR

while (!(SPSR & (1<<SPIF))) {}; // si attende il termine dell'invio del byte

//dell'indirizzo6

dato_ricevuto = SPDR; return (dato_ricevuto); }

Documenti correlati