Forum: Mikrocontroller und Digitale Elektronik Problem mit TWI beim AVR


von Mike (Gast)


Lesenswert?

Hallo,

ich versuche gerade einen I2C-Slave (DS1337) am TWI eines Atmega32 
anzusprechen.Der Atmega ist Master, der DS1337 der einzige Slave. Was 
die Software angeht, habe ich mich exakt an das Datenblatt gehalten. 
Meine Kommunikation funktioniert so, dass ich ein Byte (die interne 
Registeradresse des DS1337) an den Slave sende (Master transmitter mode) 
und dann vom DS1337 lese (Master receiver mode):

1. Sende Start condition - TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
2. Sende SLA+W
3. Sende Datenbyte (hier: die Register Adresse des DS1337)
4. Sende Stop - TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN)


Bis hier funktioniert alles perfekt. Danach möchte ich vom DS1337 lesen:

1. Sende Start condition - TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
                           while (!(TWCR & (1<<TWINT)));
...

Leider bekomme ich als Statuscode hier nicht $08 zurück (START 
condition) sonder $10 (Repeated START condition). Wurde die 
STOP-condition des vorigen Buszyklus vielleicht nicht richtig gesendet? 
Wenn ja, wie kann ich das überprüfen. Warten auf TWINT und Abfrage des 
Status geht leider nach STOP nicht.

Gruss
Mike

von ... .. (docean) Benutzerseite


Lesenswert?

http://homepage.hispeed.ch/peterfleury/avr-software.html#libs

kannst da ja mal schauen wie der das macht...

von Mike (Gast)


Lesenswert?

> http://homepage.hispeed.ch/peterfleury/avr-softwar...
> kannst da ja mal schauen wie der das macht...

Danke für den Tip. Er scheint das gleiche Problem zu haben. Deshalb
erlaubt er als Status sowohl TW_START als auch TW_REP_START.
Trotzdem irgendwie unbefriedigend.

Gruss
Mike
1
// send START condition
2
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
3
4
// wait until transmission completed
5
while(!(TWCR & (1<<TWINT)));
6
7
// check value of TWI Status Register. Mask prescaler bits.
8
twst = TW_STATUS & 0xF8;
9
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
10
...

von John S. (linux_80)


Lesenswert?

Hallo,

also ich würde sagen, das es egal ist ob es Start oder repeated Start 
ist.

von Michael U. (amiga)


Lesenswert?

Hallo,

Du wartest auch auf das Ende der Stop-Condition bevor Du den nächsten 
Start sendest?
TWSTO setzen und dann abwarten, bis es von der TWI-Hardware wieder 
gelöscht wird.

Dann geht es erst mit dem nächsten Start weiter.

Gruß aus Berlin
Michael

von pacer (Gast)


Lesenswert?

solange kein Stop gesendet wird, wird der Bus nicht freigegeben.
Deswegen ist es schon ein Unterschied ob ein start oder repeat start 
gesendet wird.
Manche Aktionen benötigen einen repeat start. Deswegen ist es einfacher 
zu prüfen ob entweder 08h oder 10h auftritt.

von John S. (linux_80)


Lesenswert?

Mit egal meinte ich, das die Start-Bedingung auf jeden Fall gesendet 
wurde, obs nun ein Rep-Start war, weiss man ja dann :-)
aber vom Ablauf her gehts ja genauso weiter.
Wer meint auf das STOP zu warten kann das ja tun, damits den richtigen 
Status bekommt ;-)

PS: Es geht hier ja nur um einen Master und einen Slave, da braucht man 
andern Masters keine Chance geben.

von Mike (Gast)


Lesenswert?

@Michael

> Du wartest auch auf das Ende der Stop-Condition bevor Du den nächsten Start 
sendest?
> TWSTO setzen und dann abwarten, bis es von der TWI-Hardware wieder gelöscht 
wird.

Ich dachte, dass die Hardware das für mich tut, oder irre ich mich da. 
Im ATMEGA32 Datasheet steht:

"The application writes the TWSTA bit to one when it desires to become a 
master on the Two-wire Serial Bus. The TWI hardware checks if the bus is 
available, and generates a START condition on the bus if it is free. 
However, if the bus is not free, the TWI waits until a STOP condition is 
detected, and then generates a new START condition to claim the bus 
Master status."

Aber im Prinzip ist es egal, da ich nur einen Master habe, also kann ihm 
auch niemand den Bus vor der Nase wegschnappen.

Eine Frage bleibt: Könnte eventuell eine teilweise gesendete 
STOP-Condition den Slave durcheinanderbringen, so dass der Bus hängt?

Gruss
Mike

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.