GUIDA ALLA PROGRAMMAZIONE IN C DEL PIC, 13° PARTE

Nella Tredicesima Parte della Guida si Parlerà del Protocollo I2C e One Wire con uno sguardo alla Codifica Manchester…

 

 

 

 




 

INTRO

I2C è una sigla che significa Inter-Integrated Circuit bus, ovvero bus di comunicazione tra integrati. Esso consiste in un protocollo di comunicazione seriale sincrono che utilizza soltanto due linee per la comunicazione. Le due linee, chiamate SDA (linea dati bidirezionale) ed SCL (clock, fornito dal

master), sono condivise tra tutte le periferiche.  Solitamente questo protocollo usa finali open collector quindi necessitano resistenze di pull-up sulle linee.

Il protocollo prevede la possibilità di avere uno o più dispositivi master, e uno o più

dispositivi slave. Ciascuna comunicazione è iniziata da parte di un master imponendo sul bus uno

stato di Start (SDA va basso mentre SCL è alto), e termina con uno di Stop (SDA va alto mentre SCL è alto). Ad ogni scambio di dati tra master è slave il ricevente può rispondere con un bit aggiuntivo di Acknowledge. Sul mercato sono disponibili moltissimi dispositivi che utilizzano il protocollo I2C, tra questi: sensori, porte di espansione di I/O (GPIO), convertitori A/D e D/A, memorie e diverse periferiche dedicate.

Il protocollo One Wire è stato inventato dalla Dallas ed è un protocollo master/slave in cui vi è un solo master e tutti i dispositivi sono connessi, come dice il suo nome, tramite un unico filo. Il protocollo ha dei driver open collector quindi sulla linea di trasmissione ci vuole una resistenza di pull-up.

Le caratteristiche di questo protocollo sono il basso costo, la velocità inferiore a 16kbps con distanza massima di 300m. Viene usato principalmente per sensori di temperatura o altri sensori come il DS1820.

Infine Mikroc dispone di una libreria di codifica e trasmissione Manchester, il dato è codificato con il clock per creare una trasmissione che si auto-sincronizza con il ricevitore.

 




 

I2C

Alcuni microcontrollori PIC, come ad esempio il PIC18F252, dispongono del modulo di comunicazione per realizzare la comunicazione I2C. Inoltre Mikroc dispone di una libreria completa per avviare questa comunicazione. Il timing di questo protocollo è:

Per avviare la comunicazione viene posto a 0 SDA e SCL, il clock oscilla alla frequenza fissata e su SDA si invia l’indirizzo, dopo di che vi è un bit di controllo ACK e dopo di che vi è dato di 8 bit con infine un altro bit di controllo. Quando parte il dato il bit interno al microcontrollore SSPIF viene messo a 1 e dopo un colpo di clock viene posto a 0, questo può essere utile in caso di interrupt.

Le routine di Mikroc per questa comunicazione sono:

La funzione I2C1_Init(const unsigned long clock);, inizializza i pin del modulo I2C e in particolare del primo modulo, usando invece I2C2.. si inizializza l’eventuale secondo modulo I2C. Tra le parentesi bisogna indicare la frequenza di clock desiderata per questa comunicazione, il massimo è 1MHz, ovvero 1000000.

La funzione I2C1_Start();, è la funzione di start della trasmissione, ritorna uno 0 logico se non ci sono errori di trasmissione, altrimenti uno 1 logico.

La funzione I2C1_Repeated_Start(); , ripete la funzione sopra citata in caso di errore

La funzione I2C1_Is_Idle();, è una funzione di controllo che ritorna un 1 logico che SDA è libero e non occupato da altri master.

La funzione take = I2C1_Rd(0);, è la funzione usata per leggere il dato trasmesso dal master e va ad inserire nella variabile “take” il dato ricevuto.

La funzione I2C1_Wr(0x00);, è la funzione usata per scrivere il dato da trasmettere, nell’esempio viene inviato un dato composto da 8 0 logici.

Infine la funzione I2C1_Stop();, genera la condizione di fine trasmissione nel bus SDA dando la possibilità ad altri dispositivi di trasmettere.

Proviamo a scrivere un semplice codice in cui si va a scrivere su una EEPROM la temperatura ogni  secondo e questa EEPROM è connessa in I2C con il PIC. Il codice è:

unsigned short int dato;         //Dato convertito
unsigned int i;                  //Indirizzo EEPROM

void main(){                     //Programma principale

  I2C1_Init(100000);             //Inizializza I2C con F=1MHz
  ADC_init();                    //Inizializza ADC

  for (i =0; i < 512; i++){      //ciclo for per riempire la EEPROM

    dato = ADC_Read(0);          //Leggi temperatura

    I2C1_Start();                //Segnale avvio comunicazione
    I2C1_Wr(0xA2);               //Indirizzo periferica
    I2C1_Wr(i+1);                //Indirizzo di memoria
    I2C1_Wr(dato);               //Dato da salvare
    I2C1_Stop();                 //Stop comunicazione

    Delay_ms(1000);              //Delay 1 secondo
  }
}


Quindi si inizializzano le variabili e poi l’ADC e il modulo I2C. Supponendo di voler salvare 512 valori si usa un for a 512 ripetizioni, ed in esso si legge il valore dell’ADC, si invia il valore nella EEPROM e infine si aspetta un secondo.

Lo schema è:

I due integrati sono connessi tramite I2C con le resistenze di pull-up da 10K. Il PIC18F252 è alimentato da 5V continui e l’oscillatore è fatto con un quarzo da 8MHz e due condensatori da 22pF. R1 mantiene il PIC in funzione mentre la memoria è connessa a VCC e GND come mostrato da immagine.

 

ONE WIRE

Come detto in precedenza questo protocollo è a basse prestazioni di velocità ma permette lunghe distanze, inoltre permette anche l’alimentazione sulla linea di trasmissione. I driver sono open collector con resistenza di pull up. La comunicazione parte quando un master o uno slave portano la linea di bus a livello logico 0. Il data rate massimo è 16Kbit al secondo.

Il master avvia la comunicazione con un impulso a livello logico 0 di 480uS che resetta tutti gli slave sulla linea bus, quando il master rilascia il bus lo slave da un segno di presenza con un impulso di 60uS. Per inviare un uno logico si invia un impulso di breve durata, per inviare invece uno 0 logico l’impulso basso avrà una durata maggiore. Il fronte di discesa generato dal master attiva nello slave un multivibratore che genera un segnale digitale utile a contare il tempo della durata dell’impulso per capire se vi è uno 0 o un 1 logico.

Quindi si invia un impulso di reset e poi gli otto bit ed è possibile anche avere 8 bit per il controllo dell’errore.

La libreria MIKROC dispone delle seguenti funzioni:

Ow_Reset(&PORTE, 2); Bisogna indicare per ogni routine dove è connesso il bus del protocollo. Questa funzione resetta lo slave che è connesso alla PORTB in particolare il pin 2 (PB2).

Take = Ow_Read(&PORTE, 2); Una volta inizializzata la variabile “Take” in essa viene deposito il dato ricevuto sul bus One Wire. Si può usare un interrupt per rilevare la partenza della scrittura e quini avviare la lettura sullo slave.

Ow_Write(&PORTE, 2, Dato); La routine per la scrittura scrive in protocollo One Wire su PORTB.F2 il Dato.

Un codice semplice, per leggere il dato da un sensore di temperatura del tipo BS1820 e semplicemente mostrarlo in uscita sulle porte del PIC è il seguente:

const unsigned short TEMP_RESOLUTION = 9;        //Risoluzione del sensore a 9bit
unsigned temp;                                   //Variabile temperatura

void main() {                                    //Programma principale

  TRISB = 0x00;

  while(1){

    Ow_Reset(&PORTC, 2);                         //Onewire reset
    Ow_Write(&PORTC, 2, 0xCC);                   //Comando  SKIP_ROM Sensore
    Ow_Write(&PORTC, 2, 0x44);                   //Comando CONVERT_T Sensore
    Delay_us(120);

    Ow_Reset(&PORTC, 2);                         //Onewire reset
    Ow_Write(&PORTC, 2, 0xCC);                   //Comando  SKIP_ROM Sensore
    Ow_Write(&PORTC, 2, 0xBE);                   //Comando READ_SCRATCHPAD Sensore

    temp =  Ow_Read(&PORTC, 2);                  //Ricevi valore di temperatura (LSB)
    temp = (Ow_Read(&PORTC, 2) << 8) + temp;     //Ricevi valore di temperatura (MSB)

    PORTB = temp;                                //Mostra in uscita il valore

    Delay_ms(500);                               //Aspetta mezzo secondo
  }
}

Il seguente codice è scritto per il sensore 18s20 che ha precisione a 9bit. Si inizializza la variabile di temperatura e nel programma principale si inizializzano le PORTB come uscite.

Nel ciclo infinito si va ad inizializzare il sensore, poi si va a ricevere la temperatura e in particolare prima gli 8 bit bassi e poi il bit alto. Infine il dato viene mostrato in uscita e poi si aspetta mezzo secondo prima di ricominciare tutto.

Lo schema è:

I due integrati sono connessi tramite One Wire con la resistenza di pull-up da 10K. Il PIC18F252 è alimentato da 5V continui e l’oscillatore è fatto con un quarzo da 8MHz e due condensatori da 22pF. R1 mantiene il PIC in funzione.  Nella simulazione viene usato il DS1822 simile a quello citato in precedenza.

 

CODIFICA MANCHESTER

La peculiarità di questa codifica è che permette una comunicazione con una sola linea di bus e inoltre permette di inviare anche una informazione sul clock essendo esso codificato bel dato inviato. La codifica Manchester Ogni bit del dato trasmesso ha una commutazione a metà periodo del dato, ovvero:

Quindi se si trasmette un 1 logico vi è prima uno 0 e poi un uno, se invece vi è uno 0 logico vi è prima un 1 e poi uno 0. Inoltre nella routine di MIKROC vengono anche inseriti 3 bit due per la sincronizzazione e uno di controllo per avviare la comunicazione. Questa codifica viene solitamente usata per i trasmettitori e ricevitori wireless.

Nell’Help di Mikroc (accessibile premento F1 quando il programma è aperto) è possibile trovare la spiegazione di tutte le funzioni e un esempio molto semplice da capire.




 

[Voti Totali: 0 Media Voti: 0]
Segui la Nostra Pagina Facebook: Facebook

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *