Tutorials - PIC18 by Data Sheet

 
 

MSSP - I2C


 

MSSP in modo Master

Il modo Master è abilitato con i bit SSMP3:0 di SSPCON1. Sono possibili due condizioni:

SSPM3:0 = 1000 Master
SSPM3:0 = 1011 Master firmware controlled

Il modo Master supporta la generazione di interrupt al riconoscimento di varie condizioni:

  • Start
  • Stop
  • trasferimento dato completato
  • trasmissione dell' ACK
  • Restart

Nel modo firmware controlled la conduzione del bus è a carico dell' utente in seguito alle condizioni Start e Stop.

Le condizioni applicate al bus dal modulo MSSP saranno cancellate da un Reset del microcontroller o dalla disabilitazione del modulo MSSP (SSPEN=0). Le linee SDA e SCL saranno rilasciate.

Il diagramma riporta la struttura logica del modulo MSSP in modo Master

I pin hanno un drive open drain e un receiver Schmitt trigger ciascuno.

Elemento chiave è la logica hardware di controllo delle condizioni, che rileva e/o genera in modo automatico:

  • Start
  • Stop
  • ACK
  • Collisioni
  • Arbitraggio del clock
  • Stato dei contatori per la fine di trasmissione e ricezione

Il clock di comunicazione dipende da un generatore di baud rate (BRG), alimentato dal clock principale (Fosc/4) e controllabile dai segnali di arbitraggio per la sincronizzazione del clock nel caso di bus multi-Master.


Configurazione del Master.

Prima di poter utilizzare il modulo MSSP come Master, occorre configurarlo.
Supponiamo di voler impostare il PIC per un funzionamento:

  • in modo Master
  • su un bus a 400 kHz, con la Fosc=40 MHz 

occorreranno i seguenti passi:

  1. Programmiamo il registro TRISC (direzione del PORTC) come ingressi per i pin SCL (RC3) e SDA (RC4).
  2. Selezioniamo con i bit SSMP di SSPCON1 la modalità Master
     
  3. Configuriamo SSPSTAT portando a 0 il bit SMP per il 400 kHz e il bit CKP anche a 0 per la compatibilità con I2C
     
  4. Calcoliamo il valore da impostare nel BRG  (0x18) e scriviamo questo in SSPADD
     
  5. Accendiamo il modulo con il bit SSPEN di SSPCON1

In Assembly:

; Configura MSSP per Master I2C a 400kHz con Fosc=40MHz
i2c_setmssp  bsf    TRISC,3        ; SCL input
             bsf    TRISC,4        ; SDA input

             movlw  b'0x08'        ; modo Master
             movwf  SSPCON1              
                                 
            
clrf   SSPSTAT        ; SMP=CKP=0

            
movlw  0x18           ; programma BRG
             movwf 
SSPADD 
 
            
bsf    SSPCON1,SSPEN  ; accendi MSSP 


Operazioni in modo Master

Quando il Master è abilitato, l' utente può avviare le seguenti operazioni:

  • Generazione della condizione di Start
  • Generazione della condizione di Restart
  • Scrivere dati/indirizzi sul bus (Master trasmettitore)
  • Ricevere dati dal bus (Master ricevitore)
  • Generare un ACK o un NACK alla fine della ricezione di un byte di dati
  • Generare la condizione di Stop

I dispositivi Master sono i soli a poter generare sul bus gli impulsi di clock seriale e le condizioni di Start e Stop

La sessione inizia con la condizione di Start e un trasferimento è chiuso con una condizione di Stop o con un Restart. 
La differenza tra Stop e Restart è la seguente:

  • Stop indica allo Slave che il Master ha chiuso la comunicazione e il bus viene rilasciato. Un altro Master può intervenire e prenderne il controllo.
  • Restart indica allo Slave che il Master ha chiuso la comunicazione corrente, ma non intende perdere il controllo del, dato che darà subito inizio ad un nuovo trasferimento, sulla stessa o su un' altra periferica. Il bus I2C non verrà rilasciato.

In modalità Master trasmettitore, i dati seriali sono in uscita attraverso SDA, mentre SCL emette il clock sincrono. Il primo byte trasmesso dopo lo Start contiene l'indirizzo dello Slave richiesto (7 bit) e il bit di lettura/scrittura (R/W). In questo caso, il bit R/W sarà a 0 (write).
I dati seriali sono trasmessi a blocchi di 8 bit; dopo la trasmissione ogni byte, viene atteso un ACK dalla periferica, che, con questo, conferma la corretta ricezione del dato.

In modalità ricezione del Master, il primo byte trasmesso contiene l'indirizzo di Slave del dispositivo trasmittente (7 bit) e il bit R/W. In questo caso, il bit R/W sarà a 1 (read): il primo byte trasmesso è un indirizzo di 7 bit , seguito da un '1' per indicare il bit di ricezione. 
I dati seriali sono ricevuti tramite SDA, mentre SCL è l' uscita del clock.Dopo aver ricevuto ogni byte, viene trasmesso un bit di ACK dalla periferica, che, con questo, conferma la corretta ricezione del dato.

Va notato che, essendo I2C un sistema multi-Master, un Master potrà essere chiamato da un' altro Master per uno scambio di dati. Un microcontroller quindi, quindi, potrà assumere sia le funzioni di Master che quelle di Slave.
In condizione Slave, sarà dotato di un indirizzo che servirà ad altri Master per la chiamata.
Per contro, uno Slave non potrà iniziare una comunicazione, ma si limiterà a rispondere alle richieste di un Master
.

Il generatore di Baud Rate utilizzato per il funzionamento in modalità SPI viene utilizzato per anche per  impostare la frequenza di clock SCL, tipicamente 100 kHz, 400 kHz o 1 MHz.

Una sequenza di trasmissione tipica può essere la seguente:

  1. l'utente genera una condizione di Start impostando il bit di Start, SEN (SSPCON2 <0>) = 1.
     
  2. Il modulo MSSP dovrà attendere il completamento della operazione richiesta prima di avviare qualsiasi altra operazione, verificando se il bit SSPIF è settato.
     
  3. L'utente carica il SSPBUF con l'indirizzo dello Slave a cui trasmettere.
     
  4. L' indirizzo è shiftato su SDA partendo dal bit più significativo. 
     
  5. Il modulo MSSP riceve l' ACK dal dispositivo Slaves e aggiorna il registro SSPCON2.
     
  6. Il modulo MSSP genera un interrupt alla fine del nono impulso di clock, settando il bit SSPIF.
     
  7. L'utente carica SSPBUF con il byte dei dati.
  8. I dati sono shiftati sul pin SDA fino a quando tutti gli 8 bit sono trasmessi.
     
  9. Il modulo MSSP riceve l' ACK dal dispositivo Slave e aggiorna il registro SSPCON2.
     
  10. Il modulo MSSP genera un interrupt alla fine del del nono impulso di clock, settando il bit SSPIF.
     
  11. L'utente genera una condizione di Stop impostando il bit di Stop PEN (SSPCON2 2) = 1.
  12. Un interrupt viene generato una volta che è la condizione di Stop è stata completata


Alcuni esempi in Assembly e C per la gestione della trasmissione in polling.

Il modulo MSSP svolge interamente le funzioni di gestione dei pin di controllo del bus e delle relative temporizzazioni in modo del tutto trasparente all' utente: per generare una condizione, ad esempio, basta semplicemente settare un bit in un registro di controllo !

Avvertenze:
  1. Se il modulo MSSP automatizza al massimo le condizioni sul bus, la gestione della logica del protocollo è interamente a carico dell' Utente.
     
  2. Molto importante avere presente che il modulo MSSP in modo Master non supporta l' accodamento degli eventi
    Ad esempio, se l' utente ha comandato uno Start, non può immediatamente scrivere SSPBUF, ma deve attendere il completamento dell' operazione precedente (che può richiedere un certo tempo).
    In un caso come questo SSPBUF non sarà scritto e il bit di collisione WCOL sarà settato, indicando la situazione
    anomala
    .

Quindi, una gestione tipica della comunicazione sarà costituita da macchine a stati il cui passaggio allo stato successivo sarà ammesso alla conclusione dello stato precedente.

Vediamo alcuni semplici esempi di codice per generare le varie condizioni.


Generare una condizione di Start

Per generare uno Start basta settare il bit SEN in SSPCON2:

; genera condizione di Start
  
bsf   SSPONC2, SEN 

oppure, in C: 

/*genera condizione di Start*/
  
SSPONC2bits.SEN = 1 ;

Il modulo MSSP si prende carico delle temporizzazioni e del controllo dei pin del bus necessari

Occorre sempre verificare che la condizione sia completata
Lo stesso bit utilizzato per la generazione, portandolo a livello alto (1), servirà da indicatore della conclusione dell' operazione, che azzera il bit:

; verifica esecuzione Start completata
vcsc   btfsc   SSPONC2, SEN 
       bra     vcsc

oppure, in C: 

/*verifica esecuzione Start completata*/
  
while (SSPONC2bits.SEN); 

Prima di poter occupare il bus occorre verificare che esso sia libero (idle), per evitare una collisone con un' altro dispositivo che stia trasmettendo in quel momento. Occorre anche verificare che ogni dato in SSPBUF sia stato ricevuto o inviato completamente:

; verifica per il bus idle (subroutine)
i2cbus_idle  movlw   0x1F 
             andwf   SSPCON2, W  ; verifica se le prime 5 condizioni
                                 ; di busy non sono attivate
            
bz      test_wr     ; se no, prossimo test
            
bra    
i2cbus_idle ; se si, resta in attesa
test_wr      btfsc   SSPSTAT,R_W ;
check status trasmissione 
            
bra     test_wr     ; se si, resta in attesa
            
return              ; se no, fine test              

oppure, in C: 

/*verifica esecuzione Start completata*/
  
void 12c_idle (void)
 
{
    while ((
SSPONC2 & 0x1F) | SSPSTATbits.R_W); 
 }


Generare una condizione di Restart

Del tutto analogamente a quanto visto per lo Start, anche per il Restart il bit RSEN in SSPCON2:

; genera condizione di Restart
  
bsf   SSPONC2, RSEN 

oppure, in C: 

/*genera condizione di Restart*/
  
SSPONC2bits.RSEN = 1 ;

Il modulo MSSP si prende carico delle temporizzazioni e del controllo dei pin del bus necessari

Occorre sempre verificare che la condizione sia completata, ad esempio con::

; verifica esecuzione Restart completata
vcpc   btfsc   SSPONC2, RSEN 
       bra     vcpc

oppure, in C: 

/*verifica esecuzione Restart completata*/
  
while (SSPONC2bits.RSEN) ;

Si ricorda che la condizione di Restart è valida solamente se è già stata emessa una condizione di Start.


Generare una condizione di Stop

Del tutto analogamente a quanto visto per lo Start, anche per lo Stop basta agire su un bit, il bit PEN in SSPCON2:

; genera condizione di Stop
  
bsf   SSPONC2, PEN 

oppure, in C: 

/* genera condizione di Stop*/
  
SSPONC2bits.PEN = 1 ;

Il modulo MSSP si prende carico delle temporizzazioni e del controllo dei pin del bus necessari

Occorre sempre verificare che la condizione sia completata, ad esempio con::

; verifica esecuzione Stop completata
vcpc   btfsc   SSPONC2, PEN 
       bra     vcpc

oppure, in C: 

verifica esecuzione Stop completata/
  
while (SSPONC2bits.
PEN) ;

Si ricorda che la condizione di Stop è valida solamente se è già stata emessa una condizione di Start oppure un Restart.


Scrivere un byte sul bus

Anche la scrittura di un byte sul bus è automatizzata al massimo.
Il byte da trasmettere viene semplicemente scritto nel registro SSPBUF; il modulo MSSP provvederà autonomamente alla trasmissione, generando i bit sulla linea SDA e il clock sincrono su SCL con le corrette temporizzazioni.
Ovviamente il bus dovrà:

  • essere stato precedentemente acquisito con uno Start

  • ed essere libero da collisioni con altre azioni.

Ecco una possibile subroutine che invia il dato in WREG sul bus I2C:

; verifica per il bus idle
i2cbus_wr  movwf   savew         ; salva dato in WREG
           rcal   
i2cbus_idle   ; verifica se il bus è libero
          
movf    savew, W      ; recupera dato
          
movwf   SSPBUF        ; e trsmetti
i2cbus_wre
btfsc   SSPSTAT,BF    ; attesa fine trasmissione 
          
bra     i2cbus_wre    ; se no, resta in attesa
          
return                ; se si, fine trasmissione             

oppure, in C: 

/*verifica esecuzione Start completata*/
  
void
i2cbus_wr (unsigned char dat)
 
{
   
i2cbus_idle
();
    SSPBUF = dat

    while
(SSPDATbits.BF); 
 }


Ricevere un byte dal bus

Il byte inviato sul bus da un' altra periferica viene raccolto nel registro SSPSR e, completati gli 8 bit, passato al registro SSPBUF.
Anche qui il modulo MSSP si incarica di tutte le operazioni connesse. Il flag BF di SSPSTAT conferma il completamento.  La ricezione viene abilitata con il bit RCEN di SSPCON2.
Ecco una possibile subroutine per effettuare l' operazione, rientrando con il dato ricevuto in WREG.:

; verifica per il bus idle
i2cbus_rd  bsf     SSPCON2, RCEN  ; abilita ricezione
i2c_rdl    rbtfss 
SSPSTAT, BF    ; attesa fine ricezione
          
bra    
i2c_rdl      
          
movf    SSPBUF, W      ; recupera dato
           return                 ; fine ricezione           

oppure, in C: 

/*verifica esecuzione Start completata*/
  
unsigned char
i2cbus_rd (void)
 
{
   
SSSPCON2bits.RCEN = 1 ;
    while (!SSPDATbits.BF);
    return (SSPBUF) ;
 }


Generazione di ACK o NACK sul bus

Se l' operazione di ricezione è andata a buon fine, occorrerà generare un ACK sul bus. Anche qui il modulo MSSP si occupa delle temporizzazioni hardware, ma resta all' utente la gestione della struttura logica connessa.
Da osservare che ACK e NACK sono avviate entrambe con il bit ACKEN, dopo di che il modulo MSSP si incarica di tutte le operazioni connesse. Per contro, la polarità della condizione (ACK a livello basso e NACK a livello alto su SDA) viene programmata con il bit ACKDT, sempre in SSPCON2, prima di avviare l'esecuzione della condizione.

; genera ACK
i2cbus_ack bcf     SSPCON2, ACKDT ; reset bit per acknowledge
           bsf    
SSPCON2, ACKEN ; inizia sequenza di ACK           

oppure, in C: 

/*verifica esecuzione Start completata*/
  
void i2cbus_ack (void)
 
{
   
SSPCON2bits.ACKDT = 0 ;
    SSPCON2bits.ACKEN = 1 ;
 }

Identicamente per il NACK

; genera NACK
i2cbus_nac bsf     SSPCON2, ACKDT ; set bit per not-acknowledge
           bsf    
SSPCON2, ACKEN ; inizia sequenza di NACK           

oppure, in C: 

/*verifica esecuzione Start completata*/
  
void i2cbus_nac (void)
 
{
   
SSPCON2bits.ACKDT = 1 ;
    SSPCON2bits.ACKEN = 1 ;
 }


 

E' molto consigliabile il raccogliere le varie sequenze di comandi come macro e subroutine in Assembly.
I
l C e altri linguaggi ad alto livello offrono librerie specifiche di comandi (funzioni) per la gestione del modulo MSSP.

 


 

 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 15/01/12.