Forum: Mikrocontroller und Digitale Elektronik TWI I2C Anfängerhilfe


von Sebastian E. (musarati)


Lesenswert?

Hallo,

ich suche Infos für Anfänger um an einem Atmega8 den TWI Bus zum laufen 
zu bekommen.

Ich habe das AVR TWI gesehen, aber mich würde vor allem mal 
interessieren, wie ich PC4/5 dazu bringe kein Ein/Ausgang zu sein, 
sondern ein TWI zu sein.

Also so ein richtiges Anfänger Tut.

Grüße

Sebastian

von Tim (Gast)


Lesenswert?

Sofern auf PC4/5 das TWI hängt, einfach TWI per enable Bit einschalten.
(Baudrate noch festlegen)
Geh einfach mal das Datenblatt vom AVR durch, da ist das
gut beschrieben. Im Prinzip muss deine software nur dem TWI
einen Auftrag geben, dann warten bis das IRQ Flag gesetzt wird und 
entsprechend dem Status den Nächten Auftrag geben.

Was wann wie gemacht werden kann und welche folgen es hat steht im.... 
Datenblatt :-)

Tipp: Besorge die einen I2C Sniffer! Speicheroszi geht zwar auch,
ist aber sehr mühsam.

von Sebastian E. (musarati)


Lesenswert?

Tim schrieb:
> Was wann wie gemacht werden kann und welche folgen es hat steht im....
> Datenblatt :-)

Naja, wenn man weiß wonach man suchen muss bestimmt toll, aber auf den 
310 Seiten als Anfänger was zu finden nicht so toll ;)

Ich hab die Fuse Bit Seite angeschaut aber da ist nicht passendes - 
kannst du mir auf die Sprünge helfen?

von ich (Gast)


Lesenswert?

Also ich würde ab der Seite 163 versuchen. Da startet die Beschreibung 
für TWI.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian E. schrieb:
> Tim schrieb:
>> Was wann wie gemacht werden kann und welche folgen es hat steht im....
>> Datenblatt :-)
>
> Naja, wenn man weiß wonach man suchen muss bestimmt toll, aber auf den
> 310 Seiten als Anfänger was zu finden nicht so toll ;)

Darum ist das Datenblatt ja auch in Kapitel organisiert :-)

> Ich hab die Fuse Bit Seite angeschaut aber da ist nicht passendes -
> kannst du mir auf die Sprünge helfen?

Die Fuse Bits werden dir da nicht weiterhelfen.


Hinweis: Es gibt ein Kapitel "Two Wire Serial Interface"
Dreimal darfst du raten, worum es in diesem Kapitel geht

Hinweis 2: Du hast dir im PDF hoffentlich das "Inhaltsverzeichnis" 
dazugeschaltet, auch wenn der entsprechende Schalter links mit dem 
Tooltip 'Bookmarks' versehen ist? (Das Blatt Papier mit der blauen 
Fahne)

von Sebastian E. (musarati)


Lesenswert?

Karl heinz Buchegger schrieb:
> Hinweis: Es gibt ein Kapitel "Two Wire Serial Interface"
> Dreimal darfst du raten, worum es in diesem Kapitel geht

Schon klar... ich habe mir auch schon alles über die Kommunikation 
durchgelesen, aber den Part "Send START condition" braucht man denke ich 
nur um die Kommunikation einzuleiten, nicht aber für die Konfiguration 
der Pins oder?

von ich (Gast)


Lesenswert?

Versuch mal auf Seite 169 unter "SCL and SDA Pins".

von Sebastian E. (musarati)


Lesenswert?

Oje schwere Geburt...
Für alle dies mal suchen:

von Seite 169 landet man auf Seite 61.
Da steht dann:
1
When the TWEN bit in TWCR is set (one) to enable the
2
Two-wire Serial Interface, pin PC4 is disconnected from the port and becomes the Serial Data
3
I/O pin for the Two-wire Serial Interface.

Also man muss nichts aktivieren, es reicht wenn das TWEN Bit gesetzt 
wird.

Das wiederum (so schauts mir auf Seite 177 aus) wird einfach im TWI 
Control Register (Befehl TWCR) erledigt.

stimmts?

von spess53 (Gast)


Lesenswert?

Hi

>Das wiederum (so schauts mir auf Seite 177 aus) wird einfach im TWI
>Control Register (Befehl TWCR) erledigt.
>stimmts?

Ja. Und in der Beschreibung zum TWEN-Bit steht das Gleiche.

MfG Spess

von Sebastian E. (musarati)


Lesenswert?

ahja wenn man das weiß kann man auch schonmal mit AVR TWI was 
anfangen ;)

ich versuche nämlich den SAA1064 mit 2 7-Segmentanzeigen die ich auf 
meinem Breadboard zusammengesteckt habe zum laufen zu bringen ;)

Das erweist sich als schwieriger als gedacht aber wenns einfach wäre 
könnts ja jeder 8)
1
#include <avr/io.h>
2
3
int main(void)
4
{
5
6
  PORTC = 0xff;                 /* Alle Pull-UP Widerstände aktivieren */
7
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);    /* TWEN (aktiviert TWI), TWSTA (ich bin Master), TWINT (Interupt)*/
8
  while (!(TWCR & (1<<TWINT)))        /* wenn Interupt nicht auf 1 ist dann */
9
  {
10
    TWDR = 0x70;              /* Adresse HEX 70 festlegen */
11
    TWCR = (1<<TWINT) | (1<<TWEN);      /* wenn Interupt nicht auf 1 ist dann */
12
    while (!(TWCR & (1<<TWINT)))      /* Interupt auf 1 und */
13
    {
14
    /* if ((TWSR & 0xF8) != MT_SLA_ACK)    /* wenn Start nicht richtig empfangen wurde */*/
15
    /* ERROR();                /* mal eine Errorrutine schreiben wenn mans mal kann*/*/
16
    TWDR = DATA;              /* Daten senden */
17
    TWCR = (1<<TWINT) | (1<<TWEN);      /* Twen (da Bus aktiv, wird zuerst gestoppt und dann wieder gestartet) + Interupt*/
18
      };
19
  };
20
return (0);
21
}

so ich hoffe jemand erbarmt sich und liest sichs mal durch.

Was ich noch nicht verstanden habe:

Gehören Subadressen mit in den Data Block? Wenn ja, der Datablock darf 
ja nur 8 Bit haben, also muss ich danach das ganze Spiel von vorne 
starten nur  beim 2. mal mit den Daten?

Danke für eure Geduld ;)

Grüße Sebastian

von Tim (Gast)


Lesenswert?

> so ich hoffe jemand erbarmt sich und liest sichs mal durch.

Ich versuchs mal...
1
PORTC = 0xff;                 /* Alle Pull-UP Widerstände aktivieren */
Warum? du hast aber schon extern 4,7K Pullups am BUS ja?
1
 TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);    /* TWEN (aktiviert TWI), TWSTA (ich bin Master), TWINT (Interupt)*/
TWEN passt ja noch,
TWSTA = das TWI soll Master werden
TWINT setzt hier das Flag zurück, gibt dem TWI also die freigabe zu 
arbeiten. Hat bei dir erstmal nix mit IRQs zu tun.

1
  while (!(TWCR & (1<<TWINT)))        /* wenn Interupt nicht auf 1 ist dann */
Solange (!(TWCR & (1<<TWINT))) hast du am TWI NIX rumzufummeln.
Da ding versucht nämlich gerade Busmaster zu werden (1<<TWSTA).
Sollte das geklappt haben spring TWINT auf 1.
Solange musst du *warten*:
1
while (!(TWCR & (1<<TWINT))) {
2
 asm volatile ("nop");
3
};

Dann das TWSR hohlen, putzen, auswerten und entsprechend
Tabelle 99 Seite 180 handeln:
1
void twi_handler(void){
2
 uint_8t twi_status;
3
 twi_status = TWSR & 0xf8;
4
 if (twi_status == 0x08){
5
  // Start hat geklappt
6
  // Jetzt Zieladresse senden
7
  TWDR = 0x70;  // Stimmt das das R/W flag????
8
  // Fertig, TWI soll weitermachen:
9
  TWCR = (1<<TWINT)|(1<<TWEN);
10
 } else if (twi_status == 0x18){
11
  // Slave ACK
12
  TWDR = 0x33;  // die zu sendenden Daten
13
  // Fertig, TWI soll weitermachen:
14
  TWCR = (1<<TWINT)|(1<<TWEN);
15
 } else if (twi_status == 0x00){
16
  // Oh, Bus error....
17
  //....
18
 };
19
};
Jetzt must du das nur noch für alle anderen (relevanten) Statuscodes
erweitern. Die Funktion rufst du immer dann auf, wenn das TWI seinen
Auftrag erledigt hat.
1
while (1) {
2
 // Warten auf twi.....
3
 while (!(TWCR & (1<<TWINT))) {
4
  asm volatile ("nop");
5
 };
6
 // Status bearbeiten
7
 twi_handler();
8
};

Das ist kein funktionsfähiger (oder gar geprüfter) code.
Er soll dir nur den weg zeigen.....

Das TWI ist eine (billige) statemaschine.
Du gibst ihr einen Auftrag (Start||Stop||Daten) + TWINT=1 und
dann werkelt das teil. Wenn es eine Entscheidung brauch was
als nächtes zu tun ist setzt es TWSR + TWINT und wartet.
(Solange ist auch der Bus blockiert)
Alles was dein code tun ist die (richtige) entscheidung zu
fällen und dem TWI einen neuen Auftrag zu geben.

> Danke für eure Geduld ;)
Lies erstmal das Datasheet und verstehe wie das ding arbeitet.
Dann schreib code. Mit rumprobieren kommt du beim TWI NIE an ziel.
Hoffe du hast wenigstens einen funktionierenden UART um die
Status/Debuginfos ausgeben zu lassen.

von Sebastian E. (musarati)


Lesenswert?

Tim schrieb:
>> Danke für eure Geduld ;)
> Lies erstmal das Datasheet und verstehe wie das ding arbeitet.
> Dann schreib code. Mit rumprobieren kommt du beim TWI NIE an ziel.
> Hoffe du hast wenigstens einen funktionierenden UART um die
> Status/Debuginfos ausgeben zu lassen.

OK... also ich vergess das ganze dann mal und fang weiter unten an ;)

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.