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
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.
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?
Also ich würde ab der Seite 163 versuchen. Da startet die Beschreibung für TWI.
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)
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?
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?
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
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
> 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.