Domanda:
Come viene stabilita la frequenza di clock tra master e slave nel protocollo I2C?
Ricardo
2014-03-13 18:40:53 UTC
view on stackexchange narkive permalink

Questa è una domanda successiva a Cosa succede se ometto le resistenze pullup sulle linee I2C?

In un orologio da parete digitale che ho progettato (utilizzando l'RTC DS1307 e l'MCU ATmega328), ho accidentalmente omesso le resistenze di pull-up che devono essere collegate a entrambe le linee I2C. Alla fine ho avuto la fortuna che i pull-up interni sulle linee ATmega I2C fossero sufficienti a permettere (a malapena) la comunicazione tra i dispositivi. Il risultato sono stati lunghi tempi di salita sulle linee I2C e riduzione della velocità a 32kHz , come si vede nelle immagini dell'oscilloscopio di seguito.

Modifica: in realtà, la frequenza è esattamente 100kHz - ci sono 2 picchi per 20us sulla traccia verde. Inizialmente pensavo ci fosse una riduzione a 32 kHz perché il mio oscilloscopio calcolava la frequenza sulla traccia gialla.

Scope shot 1 Scope shot 2

Ciò che mi lascia perplesso ora è come il i dispositivi hanno deciso che 32 kHz erano sufficienti per la comunicazione. La scheda tecnica DS1307 afferma che il dispositivo supporta la frequenza di 100 kHz sul bus I2C. Come mai invece è finito a usare 32kHz? Esiste una sorta di fase di handshake in cui la frequenza viene stabilita?

Alla fine, la mia domanda è davvero questa: Come viene stabilita la frequenza di clock tra master e slave nel protocollo I2C?

Non sono riuscito a trovare quelle informazioni cercando in rete.

Nel caso in cui ciò sia importante, sto usando Arduino IDE 1.03 e il mio firmware gestisce RTC utilizzando la libreria DS1307RTC Arduino (tramite le sue funzioni RTC.read () e RTC.write () ). Quella libreria a sua volta usa Wire.h per parlare con l'RTC.

Lo standard per I2C è [qui] (http://www.nxp.com/documents/user_manual/UM10204.pdf)
Non potresti essere tu a codificare arbitrariamente quella frequenza senza saperlo?
@Warren Questo riferimento è davvero utile, grazie. Non sono riuscito a convincere Google a portarmi a THE SPEC. Invece, mi ha portato a un articolo di Wikipedia e ad altri documenti tangenziali. Tuttavia, non riuscivo a capire come viene determinata la velocità. Penso che quello che voglio sapere sia nella sezione * 3.1.7 Sincronizzazione dell'orologio *, ma apprezzerei davvero se qualcuno potesse spiegarmelo in termini più semplici, dato che è ancora un po 'sopra la mia testa.
@Dzarda - Questo è esattamente quello che volevo sapere. Come viene codificata la frequenza (se lo è davvero)?
Nel tuo sistema il DS1307 è uno slave e la sua linea SCL è solo un ingresso. La frequenza è impostata dal master della MCU. Chiunque abbia scritto il firmware per questo ha deciso quale velocità volevano. Non c'è negoziazione, è hard coded.
@Warren - Capisco. È un ottimo inizio per me cercare la risposta nel mio codice e nelle librerie che utilizza. Grazie! Inoltre, quello che sto arrivando è che la sincronizzazione dell'orologio si verifica solo quando è coinvolto più di un master. È giusto? Penso di poterlo suggerire leggendo le specifiche.
Corretto, la maggior parte dei sistemi ha un solo master, la sincronizzazione dell'orologio ha senso solo in un ambiente multi-master
Tre risposte:
supercat
2014-03-13 20:34:06 UTC
view on stackexchange narkive permalink

Affinché un fronte di clock in aumento si verifichi in I2C, il master deve affermare il clock, il che può far sì che anche alcuni slave si uniscano nell'asserirlo, quindi il master e tutti gli slave devono concorrere a rilasciare il clock. Fino a quando tutti i dispositivi non rilasciano l'orologio, rimarrà affermato e tutti i dispositivi vedranno che è affermato.

Una volta che ogni dispositivo ha rilasciato l'orologio, ogni dispositivo slave "reinserirà" il circuito di mantenimento dell'orologio a meno che o fino a quando non sarà pronto per il successivo fronte di salita [alcuni dispositivi sono sempre "pronti" per i fronti di salita alla velocità con cui il master può inviarli, e quindi non necessitano affatto di un circuito di blocco del clock; altri possono a volte sapere che non saranno interessati a nessun fronte di salita fino a quando non appare la prossima condizione di avvio, e non riattaccano il loro circuito di blocco fino ad allora]. Quando il master vede che l'orologio è stato rilasciato, attende un periodo di tempo minimo per garantire che chiunque abbia bisogno di riarmare un circuito di attesa del bus abbia la possibilità di farlo, quindi riaffermare l'orologio e assicurarsi che sia tenuto abbastanza a lungo da consentire a qualsiasi circuito di attesa bus armato di unirsi per tenerlo. Il ciclo può quindi ripetersi.

I dispositivi slave generalmente non hanno una velocità minima di funzionamento, ma ne avranno una massima. Alcuni dispositivi sincronizzano tutta la loro logica I2C con un orologio interno e possono quindi richiedere uno o due cicli per inserire o attivare il loro circuito di blocco del clock. Inoltre, I2C richiede che i dispositivi debbano determinare in modo affidabile al 100% se i fronti sul filo di clock si verificano prima o dopo i fronti sul filo dati; poiché i cambiamenti della linea dati spesso si verificano quasi immediatamente dopo la caduta dei fronti di clock, i dispositivi possono aggiungere un certo ritardo quando percepiscono i cambiamenti della linea dati. Ciò richiede l'aggiunta di un ritardo tra il momento in cui il master cambia i suoi dati in uscita e il momento in cui aumenta il suo clock. A condizione che ogni dispositivo abbia il suo requisito di ritardo minimo soddisfatto, il master può ritardare quanto vuole; maggiore è il ritardo del master, maggiore è il tempo necessario per inviare i dati.

Dzarda
2014-03-13 19:16:46 UTC
view on stackexchange narkive permalink

Seguendo i commenti:

Sì, la frequenza è hardcoded in alcuni registri specifici relativi a I2C. In fase di esecuzione.

Detto questo, la tua libreria Arduino potrebbe eseguire un po 'di sondaggio e misurazione del tempo di salita sul bus per determinare una frequenza di clock valida. Vediamo.


Dopo aver fatto un po 'di ricerca sui sorgenti, la risposta è in twi.h

  #ifndef TWI_FREQ # define TWI_FREQ 100000L # endif  

Un altro pezzo da quel file:

  TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2;  

Dove TWBR sta per Two Wire Baudrate Register , sospetto.

La definirei una prova sufficiente e direi sicuramente, sì, la tua frequenza I2C è impostata direttamente dalla tua libreria senza alcuna negoziazione. Se vuoi cambiarlo, ti suggerisco di #define TWI_FREQ prima di #include twi.h (o indirettamente tramite Wire.h)

* "Se vuoi cambiarlo, suggerirei` # undef` e `# define` su` TWI_FREQ` dopo aver incluso Wire.h "* No, non è corretto. Nel modo in cui è scritto `twi.h`, dovresti` # definire` il tuo `TWI_FREQ` ** personalizzato prima ** di` #includere twi.h`. (E cosa c'entra "Wire.h"?)
In realtà, la frequenza è sempre stata esattamente 100kHz - ci sono 2 picchi per 20us sulla traccia verde.Inizialmente ho pensato che ci fosse una riduzione a 32kHz perché il mio oscilloscopio ha calcolato la frequenza sulla traccia gialla.Questo rende la tua risposta corretta.Grazie!!
Passerby
2014-03-14 05:18:09 UTC
view on stackexchange narkive permalink

Dal sito Web di Arduino - Riferimento dettagliato della libreria Wire:

La chiamata twi.init () è interna alla libreria Wire. Esegue le seguenti attività: imposta la frequenza di clock che l'hardware TWI utilizzerà se / quando è il master sul bus I2C. È impostato nel codice sorgente a 100kHz, ma in teoria almeno puoi reimpostare questa frequenza ridefinendo TWBR prima di chiamare Wire.begin (), ad esempio: TWBR = 400000L dovrebbe impostarlo a 400kHz.

La libreria RTC che usi non cambia TWBR. Qualcos'altro che stai usando potrebbe averlo cambiato. Oppure il lungo e lento tempo di pull-up dei pull-up interni super deboli ha effettivamente causato il rallentamento del motore i2c di ATMega. Il motore controlla se la linea è alta o bassa prima di cambiarla.

Detto questo, la frequenza di clock i2c è arbitraria , fino alla frequenza massima più bassa supportata da qualsiasi dispositivo sul bus (e forse qualche decina di Hz in più). Più velocemente e inizi a ricevere problemi di lettura e scrittura. Alcuni dispositivi hanno frequenze minime prima del timeout, ma ho visto dispositivi a 400 kHz funzionare a 10 kHz. La velocità di clock è decisa esclusivamente dal master (cioè tu, il programmatore).

C'è un'opzione per allungare il clock da parte dello slave (mantiene la linea di clock bassa finché non è pronta, e richiede che il controllo principale per questo), ma le immagini dell'ambito non sembrano indicare che questo sta accadendo qui.

Se dovessi aggiungere alcuni pullup esterni appropriati, senza modificare alcun codice, dovresti vedere l'aumento della frequenza più vicino a 100kHz come la Wire Library definisce come standard



Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...