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:
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
und der des masters:
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
Leider verhält sich das ganze jetzt garnicht so wie es soll,
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