Ich erlaube mir jetzt mal, diesen Thread zu benutzen, geht aber genau um das gleiche Thema,
nämlich eine Word-Variable über I2C zu übertragen, nur in die andere Richtung.
Auf einem ATMEGA8 ist ein Slave implementiert, ein ATMEGA16 ist der Master,
der vom Slave einen (später mehrere) Werte auslesen soll.
Der Code ist aus dem Wiki-Artikel "TWI Praxis" übernommen und dann zugegebener maßen etwas zusammengepfuscht.
Hier der Code für den Slave:
und der des masters:Code:' TWI-slave test $regfile = "m8def.dat" ' the used chip $crystal = 8000000 ' frequency used Dim Twi_control As Byte ' Controlregister lokale kopie Dim Twi_status As Byte Dim Twi_data As Byte Dim Count As Byte Dim Wert As Word Wert = &H1234 Dim Temp As Byte Dim Count2 As Byte Declare Sub Twi_init_slave ' Werte zurcksetzen Count = 7 Count2 = 23 Twi_data = 0 Call Twi_init_slave ' TWI aktivieren ' Hauptschleife Do ' schauen ob TWINT gesetzt ist Twi_control = Twcr And &H80 ' Bit7 von Controlregister If Twi_control = &H80 Then Twi_status = Twsr And &HF8 ' Status ' will der Master ein Byte haben If Twi_status = &HA8 Or Twi_status = &HB8 Then 'Temp = High(wert) 'Twdr = Temp 'Incr Count Twdr = Count ' testwert +1 End If ' TWINT muss immer gelscht werden, damit es auf dem Bus weiter geht Twcr = &B11000100 Twi_status = Twsr And &HF8 If Twi_status = &HA8 Or Twi_status = &HB8 Then 'Temp = Low(wert) 'Twdr = Temp 'Incr Count Twdr = Count2 End If ' TWINT muss immer gelscht werden, damit es auf dem Bus weiter geht Twcr = &B11000100 ' TWINT löschen, mit ACK End If Loop End ' Unterprogramme ' TWI als slave aktivieren Sub Twi_init_slave Twsr = 0 ' status und Prescaler auf 0 Twdr = &HFF ' default Twar = &H40 ' Slaveadresse setzen Twcr = &B01000100 ' TWI aktivieren, ACK einschalten End Sub
Leider verhält sich das ganze jetzt garnicht so wie es soll,Code:' TWI Testprogramm ' mit Slave @ &H40 $regfile = "M16def.dat" ' the used chip $crystal = 16000000 ' frequency used $baud = 9600 ' baud rate Declare Function Twi_read_byte(byval Slave As Byte) As Word Dim Twi_control As Byte ' Controlregister lokale kopie Dim Twi_status As Byte Dim Twi_data As Byte Dim Twi_read1 As Byte Dim Twi_read2 As Byte Dim B As Byte ' Zeichen von UART Dim X As Byte ' Zeichen von TWI Dim Error As Byte ' Fehlermerker Dim Msg As Word ' TWI Init Twcr = &B00000100 ' erstmal nur TWI aktivieren Twsr = 0 ' Status und Prescaler Register Twbr = 72 ' Bit Rate Register, 100kHz ' Startausgabe Print "TWI Master Receiver" ' Hauptschleife Do ' warten bis etwas ber UART kommt (egal welcher Wert, wird nur als Startbutton genutzt) Input B ' ein Byte vom Slave holen Msg = Twi_read_byte(&H40) ' Ausgabe, damit wir sehen was geschehen ist Print "LSB: " ; Twi_read2 Print "MSB: " ; Twi_read1 Print Msg ; Print " Error : " ; Print Hex(error) ' error status Ausgeben Loop End ' Unterprogramme ' TWI read_byte ' holt ein Byte und schliesst die bertragung ab Function Twi_read_byte(slave As Byte) As Word Error = 0 ' Fehler zurücksetzen Twi_read_byte = 0 ' Wert vorbelegen ' Startbedingung Twcr = &B10100100 ' TWINT ' warten bis TWINT gesetzt ist Gosub Twi_wait_int ' wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben If Twi_status = &H08 Or Twi_status = &H10 Then Twdr = Slave Or &H01 ' slave adresse + Read Twcr = &B10000100 ' TWINT lschen, Byte senden ' warten bis TWINT gesetzt ist Gosub Twi_wait_int ' Slave hat sich gemeldet If Twi_status = &H40 Then Twcr = &B11000100 ' TWINT lschen, Byte senden ' ein ACK (TWEA = 1) ' warten bis TWINT gesetzt ist Gosub Twi_wait_int ' ein Byte wurde empfangen If Twi_status = &H58 Or Twi_status = &H50 Then Twi_read1 = Twdr ' Daten lesen Error = 0 ' kein Fehler Else Error = Twi_status ' Fehler End If 'zweites lesen Twcr = &B10000100 ' TWINT lschen, Byte senden ' kein ACK (TWEA = 0) senden, weil wir nur ein Byte lesen wollen ' warten bis TWINT gesetzt ist Gosub Twi_wait_int ' ein Byte wurde empfangen If Twi_status = &H58 Or Twi_status = &H50 Then Twi_read2 = Twdr ' Daten lesen Error = 0 ' kein Fehler Else Error = Twi_status ' Fehler End If Twi_read_byte = Makeint(twi_read2 , Twi_read1) Else ' kein slave Error = Twi_status ' Fehler End If ' STOPbedingung kommt hier immer im Ablauf, egal welcher Status Twcr = &B10010100 ' TWINT lschen, STOP senden ' nach einem STOP wird TWINT nicht mehr gesetzt, ' man darf/kann also nicht darauf warten ! Else ' Bus belegt, wird er wieder freigegeben Twcr = &B10000100 ' TWINT lschen, Bus freigeben Error = Twi_status ' Fehler End If End Function ' warten bis TWINT gesetzt ist, status auslesen Twi_wait_int: Do Twi_control = Twcr And &H80 Loop Until Twi_control = &H80 Twi_status = Twsr And &HF8 ' status ' status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird ! ' Print "Err " ; Hex(twi_status) Return
in der Variante wie sie jetzt das steht, also das nicht auskommentierte,
sendet es zwei mal die 7 obwohl das zweite 23 seien sollte.
Wenn ich die Variante mit einer Variable verwende, die immer erhöht wird,
treten Sprünge auf wie:
LSB: 1
MSB:3
LSB:5
MSB:7
Wenn ich die Word Variable verwende, wie es ja eig. sein soll,
klappt das auch nicht wie gewollt.
Ich hab mir jetzt echt schon das Hirn zermartert, aber ich weiß nicht,
wie ich das hinkriegen soll, bitte helft mir.
Lukas







Zitieren

Lesezeichen