- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 9 von 9

Thema: TWI Hilfe!

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    01.12.2007
    Beiträge
    7

    TWI Hilfe!

    Anzeige

    Powerstation Test
    Servus,
    ich möchte nen Mega8 und Mega32 so miteinander über twi verbinden, dass beide sowohl senden als auch empfangen können. Leider werd ich aus den Wiki Beiträgen net schlau... ich versteh net ganz wie die mytwi lib funktionieren soll... Muss ich die M32Slave.bas auch auf den Mega8 laden und anpassen?
    Und wie würde jetzt der Code aussehn wenn ich vom Mega8 ne 1 an den M32 senden will, dieser dann einen Pin toggelt und ne 1 zurücksendet, die der Mega8 wieder auswerten kann?

    Kann mir da eventuell jemand helfen?
    Danke!

    MfG

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    01.12.2007
    Beiträge
    7
    Ich hab es jetzt hingekriegt dass der M32 dem M8 etwas senden kann. Allerdings kommen keine Daten an wenn er etwas vom M8 anfordert.

    Code:
    $regfile = "m8def.dat"
    $crystal = 8000000
    $baud = 19200
    
    
    Dim Send_data As Byte                                       ' was gesendet wird
    
    Send_data = 5
    
    
    Declare Sub Twi_init_slave
    Declare Function Twi_wait() As Byte
    Dim Twi_control As Byte                                     ' Controlregister lokale kopie
    Dim Twi_status As Byte
    Dim Twi_data As Byte
    
    
    Twi_data = 0
    Call Twi_init_slave                                         ' TWI aktivieren
    
    Do
    
    Twi_status = Twi_wait()
    If Twi_status = &H80 Then
       Cls
       Locate 1 , 1
       Lcd "Angekommen!"
       Locate 2 , 1
       Lcd "Daten: " ; Twi_data
    
    Elseif Twi_status = &HA8 Or Twi_status = &HB8 Then
       Cls
       Locate 1 , 1
       Lcd "Daten gesendet!"
    End If
    
    
    
    Loop
    
    End
    
    
    
    
    ' TWI als slave aktivieren
    Sub Twi_init_slave
        Twsr = 0                                                ' status und Prescaler auf 0
        Twdr = &HFF                                             ' default
        Twcr = &B00000100                                       ' erstmal nur TWI aktivieren
        Twar = &H40                                             ' Slaveadresse setzen
        Twcr = &B01000100                                       ' dann ACK einschalten
    End Sub
    
    Function Twi_wait() As Byte
    
        Twi_control = Twcr And &H80                             ' Bit7 von Controlregister
    
        If Twi_control = &H80 Then
            Twi_status = Twsr And &HF8                          ' Status
    
          ' wurde ein Byte geschickt
          If Twi_status = &H80 Or Twi_status = &H88 Then
                Twi_data = Twdr                                 ' neue Daten merken
    
          ' wird ein Byte angefordert
          Elseif Twi_status = &HA8 Or Twi_status = &HB8 Then
                Twdr = Send_data
    
          End If
          Twcr = &B11000100                                     ' damit es weitergeht
    
        End If
    
    
    
    
    
    End Function
    Das ist mein Code bis jetzt. Im Prinzip sind die zwei Wiki Beiträge (transmitter & receiver) zusammengefasst. Aber leider klappt es nicht!
    Elseif Twi_status = &HA8 Or Twi_status = &HB8 Then <--- das is leider niemals wahr und deshalb gehe ich mal davon aus dass der Slave nichts versendet hat!

    Findet jemand den Fehler?

    MfG

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    01.12.2007
    Beiträge
    7
    kann mir denn keiner helfen

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    01.12.2007
    Beiträge
    7
    ach ja, hier ist noch das programm vom mega32: (nur das wichtige)
    Code:
    $lib "i2c_twi.lbx"                                          ' we do not use software emulated I2C but the TWI
    
    Config Twi = 400000                                         ' wanted I2C clock frequency
    Twcr = &H04
    
    Do
    
    Data_read = 0
    
    I2cstart
    I2cwbyte &H40
    I2cwbyte 1
    I2cstop
    Print Data_read
    Waitms 500
    
    I2cstart
    I2cwbyte &H40
    I2cwbyte 2
    I2cstop
    print data_read
    Waitms 500
    
    I2cstart
    I2cwbyte &H40
    I2cwbyte 3
    I2cstop
    print data_read
    Waitms 500
    
    I2cstart
    I2cwbyte &H40
    I2crbyte Data_read , Nack
    I2cstop
    print data_read
    Waitms 500
    
    I2cstart
    I2cwbyte &H40
    I2cwbyte Data_read
    I2cstop
    print data_read
    Wait 1
    
    Loop
    der mega32 sendet nacheinander 1,2 und 3 an den mega8, dann sollte er eine 5 empfangen und die wieder zum mega8 zurückschicken, damit dieser sie auf dem lcd darstellen kann! leider klappt das nicht, der mega8 gibt immer 64 aus anstatt 5.

    Dieser Teil aufm Mega8 der für das Senden zuständig sein soltle, wird nie ausgeführt: (hab es mit ner lcd ausgabe überprüft)
    Code:
      Elseif Twi_status = &HA8 Or Twi_status = &HB8 Then 
                Twdr = Send_data 
    
          End If
    ich hab aber keine Ahnung wieso ...

    bitte bitte helft mir, wäre toll wenn ich das bis morgen hinkriegen würde =)

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,

    der Teil vom Mega 8 wird wohl deshalb nicht angesprungen, weil die I2C-Adresse dafür nicht passt, wenn man was vom Slave lesen will, muss man das RW-Bit setzen (für Read) also hier eine &H41, dann rückt der M8 auch Daten raus, und springt in den If-Zweig mit diesem Status.

    Hab das nur mal schnell überflogen, zwischen den TWI-Befehlen beim Slave, nicht zuviele (LCD)Befehle einbauen, sonst kommt evtl. der I2C durcheinander weils zulange dauert. Erst nach einem STOP den Rest machen, Daten auswerten usw.

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    01.12.2007
    Beiträge
    7
    wow was so eine 1 alles bewirkt

    vielen vielen vielen dank!
    hast mir echt geholfen! supi =)

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2007
    Beiträge
    386
    hallo habe hier mal send-empfang-slave und send-empfang-master.

    master gibt über die serielle schnittstelle die daten aus und slave gibt die daten über das lcd-display aus. muste noch anpassen an dein lcd/rs232/mega


    master-send-empfang:
    Code:
    ' TWI-slave test
    ' zum simulieren eines PCF8574
    
    $regfile = "m32def.dat"
    $crystal = 8000000
    $hwstack = 32
    $swstack = 32
    $framesize = 64
    $baud = 19200
    
    Declare Sub Twi_send_byte(byval Slave As Byte , Zeichen As Byte)
    Declare Function Twi_read_byte(byval Slave As Byte) As Byte
    
    Dim Twi_control As Byte
    Dim Twi_status As Byte
    Dim Twi_data As Byte
    
    Dim B As Byte
    Dim Error As Byte
    Dim X As Byte
    
    Enable Interrupts
    
    ' TWI init
    Twcr = &B00000100                       ' erstmal nur TWI aktivieren
    Twsr = 0                                ' Status und Prescaler Register
    Twbr = 72                               ' Bit Rate Register, 100kHz
    
    Print "TWI Master senden/empfangen"
    
    Do
    
        Input B
    
        Call Twi_send_byte(&H40 , B)
    
        Waitms 100
    
        X = Twi_read_byte(&H40)
    
        Print X ;
    
        Waitms 100
    
    Loop
    
    End
    
    Function Twi_read_byte(slave As Byte) As Byte
        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 löschen, Byte senden
    
            ' warten bis TWINT gesetzt ist
            Gosub Twi_wait_int
    
            ' Slave hat sich gemeldet
            If Twi_status = &H40 Then
                Twcr = &B10000100           ' TWINT löschen, 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_read_byte = Twdr    ' Daten lesen
                    Error = 0               ' kein Fehler
                Else
                    Error = Twi_status      ' Fehler
                End If
    
            Else
                ' kein slave
                Error = Twi_status          ' Fehler
            End If
        Else
            ' Bus belegt, wird er wieder freigegeben
            Twcr = &B10000100               ' TWINT löschen, Bus freigeben
            Error = Twi_status              ' Fehler
        End If
    
    End Function
    
    Sub Twi_send_byte(byval Slave As Byte , Zeichen As Byte)
        Error = 0
    
        ' 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 And &HFE           ' slave adresse + Write
            Twcr = &B10000100               ' TWINT löschen, Byte senden
    
            ' warten bis TWINT gesetzt ist
            Gosub Twi_wait_int
    
            ' Slave hat sich gemeldet
            If Twi_status = &H18 Or Twi_status = &H20 Then
                Twdr = Zeichen              ' Daten
                Twcr = &B10000100           ' TWINT löschen, Byte senden
    
                ' warten bis TWINT gesetzt ist
                Gosub Twi_wait_int
    
                ' Zeichen wurden gesendet
                If Twi_status = &H28 Or Twi_status = &H30 Then
                    Error = 0               ' kein Fehler
                Else
                    Error = Twi_status      ' Fehler
                End If
            Else
                ' kein slave
                Error = Twi_status          ' Fehler
            End If
    
            ' STOPbedingung kommt hier immer im Ablauf, egal welcher Status
            'Twcr = &B10010100               ' TWINT löschen, 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 löschen, Bus freigeben
            Error = Twi_status              ' Fehler
        End If
    End Sub
    
    Twi_wait_int:
        Do
            Twi_control = Twcr And &H80
        Loop Until Twi_control = &H80
    
        Twi_status = Twsr And &HF8          ' status
    Return
    slave-send-empfang:
    Code:
    ' TWI-slave test
    ' zum simulieren eines PCF8574
    
    $regfile = "m32def.dat"
    $crystal = 8000000
    $hwstack = 32
    $swstack = 32
    $framesize = 64
    $baud = 19200
    
    Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.6 , Rs = Portc.7
    Config Lcd = 20 * 2
    
    Dim Twi_control As Byte
    Dim Twi_status As Byte
    Dim Twi_data As Byte
    
    Dim Neuesbyte As Byte
    Dim Count As Byte
    
    Declare Sub Twi_init_slave
    
    Enable Interrupts
    
    Count = 77
    Twi_data = 0
    
    Call Twi_init_slave
    
    Do
    
        Neuesbyte = 0
    
        ' schauen ob TWINT gesetzt ist
        Twi_control = Twcr And &H80         ' Bit7 von Controlregister
    
        If Twi_control = &H80 Then
            Twi_status = Twsr And &HF8      ' Status
    
            ' wurde ein Byte geschickt
            If Twi_status = &H80 Or Twi_status = &H88 Then
                Twi_data = Twdr             ' neue Daten merken
                Neuesbyte = 1               ' merken das ein neues Byte da ist
            End If
    
             Waitms 100                     ' will der Master ein Byte haben
            If Twi_status = &HA8 Or Twi_status = &HB8 Then
             Twdr = Count                   ' neue Daten ausgeben
             Incr Count                     ' testwert +1
           End If
            ' TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht
            Twcr = &B11000100               ' TWINT löschen, erzeugt ACK
        End If
    
        ' wenn ein neues Byte gekommen ist, dieses auf LCD ausgeben
        If Neuesbyte <> 0 Then
            Cls
            Lcd Twi_data
        End If
    
    Loop
    
    End
    
    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

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    01.12.2007
    Beiträge
    7
    hi,
    danke auch dir roboterheld, aber mittlerweile klappts bei mir

    weiß eventuell einer von euch wie ich ein ganzes array senden kann? also senden is ja leicht, aber wie funktioniert denn das empfangen?

    Code:
     Do
               If Twi_wait() = &H80 Then
                Received_data(i) = Twi_data
                Incr I
               End If
      Loop Until Twi_data = Received_data(i - 1) and twi_data = 255
    meint ihr das könnte so klappen? er schreibt die empfangenen bytes solang in das array bis zweimal 255 gesendet wird... oder wie würdet ihr das machen? und wie kann man strings verschicken? müsste ja auch so ähnlich gehn ....


    edit: ok das hat geklappt

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2007
    Beiträge
    386
    für master :

    Config Sda = Portb.5

    Config Scl = Portb.7

    Dim X As Byte , Slave As Byte

    X = 0 'reset variable

    Slave = &H40 'slave address of a PCF 8574 I/O IC

    I2creceive Slave , X 'get the value

    Print X 'print it





    Dim Buf(10)as Byte

    Buf(1) = 1 : Buf(2) = 2

    I2creceive Slave , Buf(1) , 2 , 1 'send two bytes and receive one byte

    Print Buf(1) 'print the received byte

    End

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad