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
http://homepage.hispeed.ch/peterfleury/avr-software.html#libs kannst da ja mal schauen wie der das macht...
> 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 | ...
|
Hallo, also ich würde sagen, das es egal ist ob es Start oder repeated Start ist.
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
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.
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.
@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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.