Forum: Mikrocontroller und Digitale Elektronik TWI mit ATTiny817 - Verständnis-Frage


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Jürgen (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich möchte auf einem ATTiny817 einen simplen TWI-Slave, nur im 
Slave-Receive-Mode, realisieren.
Da ich im Moment keine andere Hardware greifbar habe, verwende ich einen 
Arduino in Verbindung mit "Wire" als Master. Er sendet Daten an den 
Tiny817. Das Empfangen funktioniert bisher auch problemlos. Das 
Debugging mache ich im Moment über die UART-Ausgabe und Putty.

Nun meine Frage zum Verständnis des TWI-Transfers.
Ich kann auf der Empfängerseite sehen, daß nach dem Empfang der 
korrekten Adresse und auch nach dem Daten-Byte jeweils in Interrupt 
ausgelöst wird. Darauf wird jeweils mit einem ACK reagiert.
Auf den Empfang der Stop-Condition kann ich aber keinen Interrupt 
registrieren.
Müsste ich normalerweise auf das STOP einen Interrupt erhalten?

Mein Code aus dem Tiny817 sieht so aus:
1
void I2C_0_send_ack(void)
2
{
3
  TWI0.SCTRLB = (0 << TWI_ACKACT_bp) | TWI_SCMD_RESPONSE_gc;
4
}
5
6
ISR(TWI0_TWIS_vect){
7
  
8
  // Address received
9
  if ((TWI0.SSTATUS & TWI_APIF_bm) && (TWI0.SSTATUS & TWI_AP_bm)) {
10
    I2C_0_send_ack();
11
    i = 65;
12
  }
13
  
14
  // Data received
15
  if (TWI0.SSTATUS & TWI_DIF_bm) {
16
    I2C_0_send_ack();
17
    i = TWI0_SDATA;
18
  }  
19
  
20
  
21
  // Check if STOP was received
22
  if ((TWI0.SSTATUS & TWI_APIF_bm) && (!(TWI0.SSTATUS & TWI_AP_bm))) {
23
    //I2C_0_send_ack();
24
    TWI0.SCTRLB = TWI_SCMD_COMPTRANS_gc;
25
    i = 83;
26
    I2C_0_send_ack();
27
  }
28
    
29
  LED0_toggle_level();
30
  
31
}    // end ISR
32
33
int main(void)
34
{
35
  
36
  TWI0.SADDR = 0x71; /* Slave Address: 0x71 */
37
  TWI0.SCTRLA = 1 << TWI_APIEN_bp    /* Address/Stop Interrupt Enable: enabled */
38
  | 1 << TWI_DIEN_bp   /* Data Interrupt Enable: enabled */
39
  | 1 << TWI_ENABLE_bp /* Enable TWI Slave: enabled */
40
  | 1 << TWI_PIEN_bp   /* Stop Interrupt Enable: enabled */
41
  | 0 << TWI_PMEN_bp   /* Promiscuous Mode Enable: disabled */
42
  | 0 << TWI_SMEN_bp;  /* Smart Mode Enable: disabled */
43
  
44
  TWI0.SCTRLA |= TWI_ENABLE_bm;
45
  
46
  
47
  
48
49
  /* application code */
50
  while (1) {
51
    
52
    if (i)
53
    {
54
      USART_0_write(i);
55
      i = 0;
56
      
57
    }
58
  }
59
}

Der Arduino sendet hiermit:
1
void loop() {
2
3
4
  x++;                  // Increment x
5
  if (x > 126) x = 32; //
6
7
8
 Wire.beginTransmission(0x38); // transmit to device #0x71
9
 Wire.write(x);                // sends x 
10
 //Wire.write(106);
11
 //Wire.write(104);
12
 //Wire.write(x);
13
 int i = Wire.endTransmission(true);    // stop transmitting
14
15
 Serial.println(i);
16
  
17
 delay(1000);
18
19
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
20
}

von Jürgen (Gast)


Bewertung
0 lesenswert
nicht lesenswert
PS:
Das Datenblatt - 
http://www.atmel.com/Images/Atmel-42721-ATtiny417-814-816-817_Complete.pdf 
- sagt zum APIF - Flag im SSTATUS - Register:
This flag is set when the slave address match logic detects that a valid 
address has been received or by a
stop condition. … The APIF flag can be used to generate a slave address 
or stop interrupt (see description of the AIEN
control bit in TWI.CTRLA). Take special note of that the slave stop 
interrupt shares the interrupt vector
with slave address interrupt.

PPS:

Allen einen guten Rutsch und viel Gesundheit im neuen Jahr!

von Np R. (samweis)


Bewertung
0 lesenswert
nicht lesenswert
Jürgen schrieb:
> PS:
> Das Datenblatt -
> http://www.atmel.com/Images/Atmel-42721-ATtiny417-814-816-817_Complete.pdf
> - sagt zum APIF - Flag im SSTATUS - Register:
> This flag is set when the slave address match logic detects that a valid
> address has been received or by a
> stop condition. … The APIF flag can be used to generate a slave address
> or stop interrupt (see description of the AIEN
> control bit in TWI.CTRLA). Take special note of that the slave stop
> interrupt shares the interrupt vector
> with slave address interrupt.
>
> PPS:
>
> Allen einen guten Rutsch und viel Gesundheit im neuen Jahr!

Dir auch ein gutes Neues Jahr!

Könnte es sein, dass die Taktfrequenz zu langsam ist?

Seite 318:
"Bit 5 – PIEN: Stop Interrupt Enable
Writing this bit to '1' enables APIF to be set when a STOP condition 
occurs. To use this feature the system frequency must be 4x the SCL 
frequency."

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe einen TWI Slave auf dem ATtiny841 implementiert. Der hat ein 
Modul drauf, das weitgehend dem TWI Slave des ATtiny817 entspricht. Und 
dafür kann ich bestätigen, dass der Stop-Interrupt durchkommt.

In
1
    TWI0.SCTRLB = TWI_SCMD_COMPTRANS_gc;
2
    i = 83;
3
    I2C_0_send_ack();
sollte die letzte Zeile raus, weil schon in der ersten erledigt.

NB: Als Master für den Test verwendete ich den Bus Pirate. Den 
Arduino-Code kann ich nicht einschätzen.

: Bearbeitet durch User
von Jürgen (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Danke für Eure Antworten!
@np rn
Die Taktfrequenz beträgt 3,33MHz. Das sollte also ok sein.

Ja, es ist eine blöde Idee sich in unbekannte Materie einarbeiten zu 
wollen, wenn das Handwerkszeug nicht passt. Ich muss zugeben, mich für 
die ATMegas der üblichen I2C-Libs bedient zu haben. Daher fehlt mir doch 
I2C - Grundlagenwissen. Der Bus-Pirate scheint in dieser Hinsicht eine 
sinnvolle Investition. Ich hatte eigentlich ein Dev-Board mit dem 
MCP2221 im Sinn. Der Pirate ist aber universeller.

Wie dem auch sei, ich habe noch etwas mit dem Arduino getestet.
Dabei stellte sich heraus, daß wenn ich den Tiny817-Slave nur schreibend 
anspreche (Adress-Bit 8 = 0) kann ich auf meinem "Serial-Debug-Terminal" 
erkennen, daß im TWI-Interrupt die Adresse erkannt wird und mein 
Datenbyte empfangen wird.
1
i2c_start(0x70);  // address + 0
2
i2c_write(0x79);  // data Byte 'y'
3
i2c_stop();

Spreche ich den Slave mit Adress-Bit 8 = 1 an wird im TWI-Interrupt die 
Stop - Condition erkannt. Das Datenbyte enthält jedoch den Wert der 
Adresse. Die erste if-Abfrage im Interrupt, die Adresserkennug, wird 
offensichtlich nicht durchlaufen.
1
i2c_start(0x71);  // address + 1
2
i2c_write(0x79);  // data Byte 'y'
3
i2c_stop();

Mit folgender Sequenz:
1
i2c_start(0x70);  // address +0
2
i2c_write(0x79);  // data Byte 'y'
3
i2c_rep_start(0x71);  //repeat_start Address + 1
4
i2c_stop();
werden alle 3 if-Bedingungen im TWI-Interrupt erfüllt und an meiner 
Konsole erkenne ich, daß die Adresse korrekt erkannt, das Datenbyte 
korrekt empfangen und die Stop-Condition erkannt wurde.

Die letzte, für mich unlogische, Sequenz erzeugt das, von mir, erwartete 
Ergebnis.

Sobald ich neues Spielzeug, den Bus-Pirate, habe kann ich wohl etwas 
sinnvoller weitermachen. Jetzt hat es etwas von im Nebel herumstochern.

von Jürgen (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Laut Datenblatt teilen sich 'valid address' und 'stop condition' ein 
Interrupt - Flag.

Demzufolge können die beiden Zustände gar nicht gemeinsam während der 
Übertragung eines Bytes auftreten - oder?

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Jürgen schrieb:
> Demzufolge können die beiden Zustände gar nicht gemeinsam während der
> Übertragung eines Bytes auftreten - oder?

Das ergibt sich zumindest auch aus dem Zustandsdiagramm in 26.3.4.3.

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Jürgen schrieb:
> Sobald ich neues Spielzeug, den Bus-Pirate,

Dass ich den Bus Pirate verwendete macht ihn nicht empfehlenswert. Der 
beherrscht kein Clock Stretching. Man muss also den I2C-Takt ziemlich 
weit absenken, um garantiert keine Latenzprobleme zu kriegen.

Ich hatte den einfach nur deshalb verwendet, weil ich ihn rumliegen 
hatte. Ich wollte als Master ein für interaktive Tests einfach 
verwendbares und getestetes Interface haben, das ich also nicht auch 
debuggen muss. Was, wie ich bei der Gelegenheit feststellen musste, ein 
Griff ins Klo war.

Mit der erwähnten Einschränkung kann man ihn für Tests verwenden, aber 
ihn extra wegen I2C zu besorgen wäre wohl nicht sinnvoll.

: Bearbeitet durch User
von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Ein Werkzeug, das bei Problemen mit seriellen Protokollen durchaus 
weiter helfen kann, ist ein DSO oder ein Logikanalysator. Was beim 
niedrig getakteten I2C wohl auch die Spielzeugklasse leisten kann. Es 
gibt welche, die mehr oder weniger nur aus einem STM32 bestehen.

: Bearbeitet durch User
von Jürgen (Gast)


Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Dass ich den Bus Pirate verwendete macht ihn nicht empfehlenswert.

Danke für den Hinweis!

A. K. schrieb:
> Ich wollte als Master ein für interaktive Tests einfach
> verwendbares und getestetes Interface haben...

Das war nun auch mein Gedanke, zumal ich mich als nächstes noch am SPI - 
Empfang auf dem Tiny817 versuchen möchte. Ich werde also vor einer 
Kaufentscheidung noch mal durchs "Bus Pirate Support" - Forum schauen. 
Das Board scheint interessant, da wohl verschiedene Protokolle 
unterstützt werden.
Gibt es da noch etwas ähnliches, eventuell empfehlenswerteres?

Der größte Teil meiner Hobby-Werkstatt ist im Moment, wegen einer 
größeren Renovierung, in Umzugskartons ausgelagert. Darunter auch mein 
LA, ein Logic Cube von Zeroplus. Mir hat einfach die Bastelei gefehlt. 
Daher habe ich, über die etwas ruhigeren Feiertage, angefangen mal etwas 
mit den noch verfügbaren Komponenten herum zu probieren.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.