Problem mit TWI beim AVR

Gast #1157932
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
Gast #1157971
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
...
Gast #1158184
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.
#1158198
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.
Gast #1158982
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren