- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 2 von 2

Thema: I2C Master Slave Probleme

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    03.10.2004
    Alter
    57
    Beiträge
    50

    I2C Master Slave Probleme

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo zusammen,

    ich möchte über I2C Daten auslesen und senden.
    1. von einem Srf08 Ausgabe auf dem UART RS232
    2. von einem Slave Atmel8 ohne Quartz
    3. Display LCD03

    Mit dem Script vom Master kann ich den Srf08 auslesen.
    Nun habe ich das Script von RN Wissen für Slave genommen.

    Beim Slave soll eine LED Blinken, im selben Rhythmus wie die LED bei Master.
    Das macht es nicht.
    Beim Slave blinkt die LED schneller.
    Wenn das dann funktioniert möchte ich noch Tasten und Schalter auslesen.
    Diese sollte erst später besprochen werden.

    Die Displayansteuerung ist nicht implementiert.

    Das zweite Problem ist wenn der Slave angesteckt wird, dann misst der Srf08 nicht mehr.

    Hier mein Master Script:


    Code:
    $crystal = 16000000
    '$crystal = 3868000
    $regfile = "m8def.dat"
    $baud = 9600
    
    Declare Function Srf08_entfernung(byval Srf08_slaveid As Byte) As Integer
    Declare Sub Srf08_reichweite(byval Srf08_slaveid As Byte , Byval Reichweite As Word)
    Declare Sub Srf08_verstaerkung(byval Srf08_slaveid As Byte , Byval Srf08_verstaerkung As Byte)
    Declare Function Srf08_firmware(byval Srf08_slaveid As Byte) As Byte
    
    Declare Sub Addieren
    Declare Sub Subtrahieren
    
    Config Portb = Output
    
    Config Scl = Portc.5
    Config Sda = Portc.4
    
    Portc.1 = 1                                                 'Taster Addieren
    Portc.2 = 1                                                 'Taster Subtrahieren
    
    Const Adr_ta1_w = 6
    Const Adr_modul_led_w = &H40                                'Slave Adresse LED schreiben
    Const Adr_modul_led_r = &H41                                'Slave Adresse LED lesen
    Const Displ_w = 198                                         'Display Adresse zum Schreiben
    Const Displ_r = 199
    
    Led Alias Portb.5
    
    Dim Text As String * 20                                     'hier kommt der Anzeige-Text rein
    Dim Stemp As String * 20
    
    Dim B As Byte                                               'Variable zur Bestimmung der Textlänge
    Dim C As Byte                                               'Hilfsvariable für FOR Schleife
    Dim D As Byte                                               'D-Position auf dem Display
    Dim E As Byte                                               'E-Position auf dem Display
    Dim F As Byte                                               'Zählvariable für die Leuchtdauer des Displays
    Dim G As Byte                                               'Zählvariable auf 1Sekunde für die Ausgabe Srf08
    Dim Wert1 As Byte                                           'Wert1
    Dim Wertled1 As Byte                                        'WertLed1
    
    Dim Entfernung As Integer                                   'Srf08 Entfernung
    Dim V As Byte                                               'Srf08 Verstärkung
    
    Dim Tasblo(10) As Byte
    
    Dim Ledgr As Byte                                           'LEDgr zum Slave Senden
    
    Print
    Print "I2C-Mastermodul von Enterprise V1.1"
    Print
    
    
    Wait 3                                                      'Warte 3 Sekunden
    I2cinit
    Print "  "
    Print "SRF 08 Firmware Version: " ; Srf08_firmware(&He2)
    Print "  "
    
       Srf08_reichweite &HE2 , 1000                             'Reichweite in Zentimetern festlegen
    
    ' Verstärkungsfaktor ändern
    
    '  Srf08_verstaerkung &HE2 , 10                              'Verstärkungsfaktor
    
    V = 1
    G = 1
    
    Wert1 = 1
    Wertled1 = 1
    
    
    '*******************************************************************************
    '------------------- Hauptschleife ----------------------
    
    Do
       Waitms 100
    
       Toggle Led                                               ' LED Rot blinkt alle 100ms
    
       Toggle Wertled1                                          ' Der Wert1 ändert alle 100ms von 1 auf 254
       Gosub Slaveled1
    
    
    ' Srf08
       If G = 10 Then
          Entfernung = Srf08_entfernung(&He2)
          Srf08_verstaerkung &HE2 , V                           'Verstärkungsfaktor
    
          Print "Verstaerkung: " ; V ; "  " ; "Entfernung: " ; Entfernung ; " cm"
    '     V = V + 3
          G = 1
             Else
                G = G + 1
       End If
    
    Loop
    
    End
    
    ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    '*******************************************************************************
    '------------------------ Slave LED senden 1 ---------------------
    Slaveled1:
    
    I2cstart
    I2cwbyte Adr_modul_led_w
    I2cwbyte 0
    I2cwbyte Wertled1
    I2cstop
    
    Return
    
    '-----------------------------------------------------------------
    '-------------- SRF08 --------------------------------------------
    '-----------------------------------------------------------------
    
    Function Srf08_entfernung(byval Srf08_slaveid As Byte) As Integer
    Local Lob As Byte
    Local Hib As Byte
    Local Firmware As Byte
    Local Temp As Byte
    Local Srf08_slaveid_read As Byte
    
       Srf08_slaveid_read = Srf08_slaveid + 1
    
       'Messvorgang in starten
       I2cstart
       I2cwbyte Srf08_slaveid
       I2cwbyte 0
       I2cwbyte 81                                              'In Zentimetern Messen
       I2cstop
    
    Warteaufmessung:
       Waitms 1
       Firmware = Srf08_firmware(&He2)
       If Firmware = 255 Then Goto Warteaufmessung
    
       I2cstart
       I2cwbyte Srf08_slaveid
       I2cwbyte 2                                               'Leseregister festlegen
       I2cstop
    
    
       I2cstart
       I2cwbyte Srf08_slaveid_read
       I2crbyte Hib , Ack
       I2crbyte Lob , Nack
       I2cstop
    
    
       Srf08_entfernung = Makeint(lob , Hib)
    End Function
    
    
    
    'Messreichweite in cm festlegen
    Sub Srf08_reichweite(byval Srf08_slaveid As Byte , Byval Reichweite As Word)
    Local Wert As Word
    Local Temp As Byte
    
       Wert = Reichweite / 4                                    'Ungefähre Registerberechnung
       Temp = Low(wert)
    
       I2cstart
       I2cwbyte Srf08_slaveid
       I2cwbyte 2                                               'Register
       I2cwbyte Temp
       I2cstop
    
    End Sub
    
    
    'Verstärung  festlegen
    Sub Srf08_verstaerkung(byval Srf08_slaveid As Byte , Byval Srf08_verstaerkung As Byte)
       I2cstart
       I2cwbyte Srf08_slaveid
       I2cwbyte 1                                               'Register
       I2cwbyte Srf08_verstaerkung
       I2cstop
    
    End Sub
    
    
    
    Function Srf08_firmware(byval Srf08_slaveid As Byte) As Byte
    Local Firmware As Byte
    Local Srf08_slaveid_read As Byte
    
       Srf08_slaveid_read = Srf08_slaveid + 1
    
       I2cstart
       I2cwbyte Srf08_slaveid
       I2cwbyte 0                                               'Leseregister festlegen
       I2cstop
    
       I2cstart
       I2cwbyte Srf08_slaveid_read
       I2crbyte Firmware , Nack
       I2cstop
    
       Srf08_firmware = Firmware
    End Function

    Und hier das Slave Script:

    Code:
    $regfile = "m8def.dat"                                      ' the used chip
    '$crystal = 7372800                                          ' frequency used
    '$baud = 9600                                                ' keine baud rate angeben !
    
    Config Portd = Output                                       ' kompletter PortD als Ausgang
    
    Dim Twi_control As Byte                                     ' Controlregister lokale kopie
    Dim Twi_status As Byte
    Dim Twi_data As Byte
    
    Dim Neuesbyte As Byte                                       ' Bytemerker
    
    Declare Sub Twi_init_slave
    
    Twi_data = 0
    Call Twi_init_slave                                         ' TWI aktivieren
    
    ' alle LEDs ein
    Portd = 0
    
    ' Hauptschleife
    Do
        ' hier könnte ihr Code stehen
    
    
        ' Merker zurücksetzen
        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
    
            ' 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 an PortD ausgeben
        If Neuesbyte <> 0 Then
    '        Portd = Twi_data                                    ' Daten auf PortD ausgeben
             Print
             If Twi_data = 254 Then
                  Portd.0 = 0
               End If
    
        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
    Kann mir da jemand weiter helfen.


    mfg
    Enterprise

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    03.10.2004
    Alter
    57
    Beiträge
    50
    Hallo zusammen,

    habe meinen Fehler gefunden.
    Ich habe dann nochmals alles untersucht.
    Es lag dann an meinem I2C Bus Kabelanbruch.

    Durch das viele Testen habe ich jetzt zwei Slaves mit Atmel8.
    Der eine mit dem internen Takt und der andere mit 16Mhz

    Nun blinkt auf beide Slaves die Kontroll LED.


    Jetzt habe ich mal eine Frage?

    Die Hauptschleife wird alle 100ms durchlaufen.
    Wie muss jetzt das Programm aussehen, wenn man zu
    einem Slave LED's ein oder aus schalten möchte, vom Srf08 Daten holen,
    auf LCD03 anzeigen und die12er Tastatur abfragen und einen weitern Slave mit Taster und Schaltern und GP12D abfragen und zwei
    Motor Treiber ansteuern.
    Und eventuell Ausgabe auf dem Uart.

    Da bekomme ich ja Zeitprobleme mit dieser weiße?

    Wie muss ich an dieses Thema dran gehen?


    mfg
    Enterprise

Berechtigungen

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

Solar Speicher und Akkus Tests