PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Interrupt bei TWI Slave (Atmega8)?



ingo pirker
12.07.2009, 15:10
Hallo!!
Ich bitte um Hilfe, da ich zur zeit "auf der Leitung stehe" :-)!!

Ich will einen ATmega8 im TWI (I2C) Slave Modus laufen lassen, es soll
eine i2C Motor Steuerung werden.

Nun meine Frage:
Der Atmega8 besitzt einen TWI Interrupt Vector (18), der wird ausgelöst
wenn das TWINT bit im TWCR Register gesetzt ist.
Wird dieses Bit auch gesetzt, wenn die Slave Adresse, die ich dem Atmega
gegeben habe, auf den Bus gesendet wurde, oder wird das Bit nur gesetzt
wenn das TWI Modul mit der Datenübertragung fertig ist??? Oder weder
noch???

Wenn dadurch kein Interrupt ausgelöst wird, gibt es dann noch eine
andere möglichkeit den Atmega8 in eine ISR springen zu lassen, wenn
seine Adresse am Bus liegt oder zumindest wenn die Startbedingung auf
den Bus gesendet wurde????

Bitte um dringende Hilfe!!!!!

MFG

PicNick
12.07.2009, 16:38
Lei, lei

Der Interrupt wird bei jedem Byte ausgelöst. (genaugenommen: bei jeder Zustandsänderung am Bus)

Wenn die eine Slave-addresse angegeben und ACK enabled hast, wird die Routine aufgerufen, wenn am Bus DEINE Adresse empfangen wurde
(Schau in der Doku-Tabelle bei "Slave-receiver" u. "Slave-transmitter")
UND dein Mega geACKed hat.
Bei Slave-Trans musst du nun ein Byte ins Output register schreiben und aktivieren
Bei Slave-recv musst nur aktivieren
In beiden Fällen wartest du auf den nächsten interrupt, der sagt dir dann was sich mittlererweile abgespielt hat.

guckst du da:
http://www.rn-wissen.de/index.php/TWI_Praxis
und eventuell da
http://www.rn-wissen.de/index.php/TWI_Praxis_Multimaster

tranh85bo
20.11.2009, 22:36
Hallo,

Ich habe test programm (Slave Transmit und Masterreceive Polling-betrieb )aus RN-wissen aufgespielt und erfolgreich gehabt .

Jetzt will ich in Interrupt betrieb umsteigen

Untere sind meine code in Bascom :



$regfile = "m128def.dat" ' the used chip
$crystal = 16000000 ' frequency used
$baud1 = 9600 ' keine baud rate angeben !
Config Sda = Portd.1 'Pins für I2C festlegen
Config Scl = Portd.0
Config Twi = 200000
Open "com2:" For Binary As #3
Dim Twi_control As Byte ' Controlregister lokale kopie
Dim Twi_status As Byte
Dim Twi_data As Byte

Dim Count1 As Byte
Dim Count2 As Byte ' Testwert,

Declare Sub Twi_init_slave


Enable Interrupts
Enable Twi
On Twi Transmit Nosave


' Werte zuweisen
Count1 = 1
Count2 = 2
Twi_data = 0
Call Twi_init_slave ' TWI aktivieren


' ---------------Hauptschleife------------------
Do
' hier könnte ihr Code stehen

Loop

End


' ------------------Unterprogramme -------------------------------------


' TWI als slave aktivieren
Sub Twi_init_slave
Twsr = 0 ' status und Prescaler auf 0
Twdr = &HFF ' default
Twar = &H30 ' Slaveadresse setzen
Twcr = &B11000101 ' TWI aktivieren, ACK einschalten

End Sub

Transmit:
Twi_status = Twsr And &HF8
Print #3 , "Twi status : " ; Twsr 'Debug
If Twi_status = &HA8 Then

Twdr = Count1 ' neue Daten ausgeben
Print #3 , "test1"

End If
' Twcr = &B10000000
' Return

If Twi_status = &HB8 Then
Twdr = Count2 ' neue Daten ausgeben
Print #3 , "test2"

End If
' Twcr = &B10000000
' Return


' TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht
Twcr = &B11000101 ' TWINT löschen,TWIE löschen mit ACK
Return


Aber das Programm funktioniert leider nicht .Ich will count1 und count2 zu Master senden aber wenn ich debug in Master angeguckt , habe ich nur den Wert von Adresse gesehen ;und wenn ich das Status gelesen ,bekomme ich nur einen Wert A8 .Ich glaub , ich habe den Fehler in Slave-Transmit gemacht aber ich weiss nicht wo.Kannst du den code für mich kurz schauen oder eine Bspl mit Interrupt in TWI geben, damit ich von der lernen kann.

Masterreceive Programm habe ich in C geschrieben und scheint nicht
Problem zu sein





swicht (twi_state++)
{
..
case 23:

//i2c_write_byte(0x00);
i2c_write_byte(SLAVE_ADRESSE+1);
break;
case 24:
byte1=i2c_readAck();
break;//1 byte lesen
case 25:
byte2= i2c_readNak(); //letztes Byte lesen, darum kein ACK

i2c_stop();
//-------ende des zugefügeteil-----
I2CTimeout = 10;
twi_state = 0;
break;
}

//Aus library
unsigned char i2c_readAck(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA)|(1<<TWIE);


return TWDR;

}// i2c_readAck

unsigned char i2c_readNak(void)
{
TWCR = (1<<TWINT) | (1<<TWEN)| (1<<TWIE);


return TWDR;

}// i2c_readNak






Ich danke euch im Voraus

MFG