PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : I²C Master und Slave, Problem bei Master Reset



ACU
27.02.2007, 12:09
Hallo,
wir arbeiten für ein Projekt daran, einen I2C-Master und -Slave auf dem
Mega 32 umzusetzen. Die ganze Sache funktioniert soweit auch ganz gut.
Der Slave löst einen Interrupt aus, wenn auf dem Bus seine Adresse
auftaucht, in der Form:

Signal(TWI_vect)
{
switch (TWSR) //TWI-Statusregister prüfen und nötige Aktion bestimmen
{
//alle Fälle werden hier abgehandelt
case: .....
case:....
default:
{
//Falls Bus-Error (TWSR = 0) setze die Register auf dem
Slave zurück
PORTA = setBit(PORTA, 0); //Fehler-LED
TWCR = (1<<TWEN)|
(1<<TWIE)|(1<<TWINT)|
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
(0<<TWWC);
break;
}
}
}


Das funktioniert einwandfrei. Sobald jedoch der Master resettet wird
(z.B. durch einen Fehler oder Stromausfall, etc.) signalisiert der
Slave jedes Mal einen Buserror, wenn der Master wieder aktiviert wird,
und die komplette Leitung steht.
Wir resetten aber auf dem Slave im Fehlerfall das TWCR Register, siehe
Code oben.

Weiß vielleicht Jemand, wie man diesen Fehlerfall abfangen kann, sodass auch nach einem Masterreset die Kommunikation wieder einwandfrei läuft?


MfG Marcus

linux_80
27.02.2007, 20:17
Hallo,

wenn der Slave erkennt, das ein BusFehler vorliegt, kann man das mit zusätzlichem setzen von TWSTO wieder hinbiegen.
schau mal hier:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=246777#246777
ist zwar für Bascom, aber vom Prinzip erkennt man was es sein soll.
Nach Case &H00 suchen.

Doozer
01.03.2007, 11:07
Woah! Tx!!!
Ich saß ebenfalls jetzt schon 2 Tage an dem Problem!
Aber anscheinend ist dies die Lösung.

Hier mein Schnipsel, damit besser auf AVR-GCC nachvollziehbar:


void twi_init(void) {
//Bit Rate Register auf 0, damit Slave
TWBR = 0x00;

//Status-Register auf Startwerte
TWSR = 0xFF;

//Adress-Register mit Addresse füllen
TWAR = (TWI_SLAVE_ADDRESS<<TWI_ADRESS_SHIFT);

//Control-Register
TWCR = 0x00
|(1<<TWINT) //Interrupt-Flag löschen
|(1<<TWEA) //Enable Acknowledge Bit aktiv
|(1<<TWEN) //Enable Bit aktiv
|(1<<TWIE); //Interrupt Enable aktiv
}

/*-------------------------------------------------------------------------*/
ISR(TWI_vect)
{
switch(TWSR & TW_STATUS_MASK) {
case TW_SR_SLA_ACK:
break;
case TW_SR_ARB_LOST_SLA_ACK:
break;
case TW_SR_GCALL_ACK:
break;
case TW_SR_ARB_LOST_GCALL_ACK:
break;
case TW_SR_DATA_ACK:
break;
case TW_SR_DATA_NACK:
break;
case TW_SR_GCALL_DATA_ACK:
break;
case TW_SR_GCALL_DATA_NACK:
break;
case TW_SR_STOP:
break;
case TW_NO_INFO:
break;
case TW_BUS_ERROR:
default:
TWCR |= (1<<TWSTO);
break;
}
twi_init();
}


Danke nochmal

Mfg Frank