Forum: Mikrocontroller und Digitale Elektronik I2C - Endes der Daten erkennen


von Hans-Joachim B. (beckhj)


Lesenswert?

Hallo!

Ich nutze die Slave Implementierung von "Martin Junghans" (danke an 
Martin für die Implementierung!!).
Bisher habe ich immer nur ein Byte an meinen Slave geschickt - läuft 
prima. Lesen ebenfalls.

Nun möchte ich mehrere Bytes zum Slave schicken. Jetzt stellt sich bei 
mir aber die Frage, wie ich das Ende der Datenübertragung im Slave 
erkennen kann.
OK, es geht alles, wenn ich die Anzahl der zu erwartenden Bytes kenne, 
dann kann ich warten, bis der Pointer des Receive-Buffes (buffer_adr) 
den richtigen Wert hat.
Aber eigentlich sollte man auch anhand der STOPP-Info des I2C Protokolls 
erkennen können, dass die Übertragung fertig ist und erst dann lohnt es 
sich für den Slave die Auswertung zu starten.

Ebenfalls wäre es hilfreich festzustellen, ob die Daten vom Master 
abgeholt worden sind.

Also: Ich habe versucht dort eine "is_transmitted" und ein "is_received" 
Info einzubauen. Ich bin ehrlich, so rund läuft es nicht.

Wie wird so was typischerweise implementiert?

Grüße
Hans-Joachim

von Joe F. (easylife)


Lesenswert?

Dafür gibt es die ACK bits.
Beim letzten Byte wird einfach nicht ge-ACK-ed.

von Peter D. (peda)


Lesenswert?

Beim Atmel 8051 oder AVR:
Table 18-8. Status Codes for Slave Receiver Mode
A0h:
A STOP condition or
repeated START condition
has been received while still
addressed as slave

von Hans-Joachim B. (beckhj)


Lesenswert?

Hallo Peter,

ich nutze hier gerade einen ATTINY 85 und ich war da an dieser Stelle:
1
 
2
  if ( !( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
3
    {  // A Stop Condition did not occur
4
    USICR =
5
    ( 1 << USISIE ) |                // Keep Start Condition Interrupt enabled to detect RESTART
6
    ( 1 << USIOIE ) |                // Enable Overflow Interrupt
7
    ( 1 << USIWM1 ) | ( 1 << USIWM0 ) |          // Set USI in Two-wire mode, hold SCL low on USI Counter overflow
8
    ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |  // 4-Bit Counter Source = external, both edges; Clock Source = External, positive edge  
9
    ( 0 << USITC );    
10
    }
11
  else
12
    {  // A Stop Condition did occur
13
    USICR =
14
    ( 1 << USISIE ) |                // Enable Start Condition Interrupt
15
    ( 0 << USIOIE ) |                // Disable Overflow Interrupt
16
    ( 1 << USIWM1 ) | ( 0 << USIWM0 ) |          // Set USI in Two-wire mode, no USI Counter overflow hold
17
    ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |    // 4-Bit Counter Source = external, both edges; Clock Source = external, positive edge
18
    ( 0 << USITC );                  // No toggle clock-port pin
19
    }

Da hatte ich extra mal meine Bits gesetzt - aber das war nicht das 
erwartete Ergebnis.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.