-
        

Ergebnis 1 bis 3 von 3

Thema: I2C problem ??

  1. #1

    I2C problem ??

    Anzeige

    Hallo !
    Ich möchte meine Ampeln steuern ich habe dazu einen Master und mehrere Slave. Der I2C allein im Programm funzt, die Ampelschleife auch, nur beides zusammen nicht.
    Problem:
    Ich möchte immer einen Slave "anstoßen" dann soll das Programm laufen.
    Bei mir kann ich zwar den Slave "anstoßen" und das Programm beginnt, allerdings kann ich dann nichts mehr tun als warten bis die Ampelschleife durch ist + ca. 5 Secunden und dann kann ich die nächste Ampel schalten.
    Code:
    $regfile = "m8def.dat"                                      'ATmega8-Deklarationen
    $crystal = 3686400                                          'Quarz: 3,6864 MHz
    $baud = 9600                                                'Baudrate zum PC: 9600 Baud
    '
    Declare Function Twistart() As Byte
    Declare Function Twisend(byval Databyte As Byte) As Byte
    Declare Function Twireceive(byref Databyte As Byte) As Byte
    Declare Sub Twistop()
    Declare Sub Schleife
    '
    Dim I As Byte                                               'Für temporären Gebrauch
    Dim Command As Byte                                         'Aktuelles UART-Kommando
    Dim Adree As Byte                                           'Für die jeweilige EEPROM-Adresse
    Dim Sbuffer As String * 20                                  'Nimmt die zu brennenden Daten auf
    Dim Buffer(20) As Byte At Sbuffer Overlay                   'Vereinfacht den Zugriff auf sBuffer
    Dim Slad As Byte                                            'Slaveadresse
    '
    Twsr = &B00000000                                           'Bits1+0=00: TWI-Vorteilung 1
    Twbr = 0                                                    'IC2-Bitrate 230400Hz bei 3,6864MHz
                    'BitRate=AvrClock/(16+2*TWBR*4^TwiPrescale)
    '----------------------------------------------------------
    Do                                                          'Hauptschleife
      Inputbin Command                                          'Warte auf "Kommando"-Byte aus der UART
      Select Case Command
      Case "A"                                                  'UART-Kommando "Write": EEPROM schreiben
        Slad = &B10100000
        GoSub Schleife
      Case "B"
        Slad = &B10100010
        GoSub Schleife
      End Select
    
    Sub Schleife()
        Sbuffer = "1"
        Adree = 1                                               'Initiale EEPROM-Adresse (EE-Adresse wird 0 als Vereinfachung ignoriert)
        While Buffer(Adree) <> 0                                'Solange kein String-Ende
          If Twistart() <> &H08 Then Exit While
          I = Twisend(Slad)                                     'Slave-Adresse im Schreibmodus senden (Bit0=0)
          If I = &H20 Then GoTo Writedone                       'NO ACK: EEPROM brennt noch, später noch mal probieren
          If I <> &H18 Then Exit While
          If Twisend(0) <> &H28 Then Exit While                 'HighByte der EEPROM-Adresse senden (bei uns immer 0)
          If Twisend(adree) <> &H28 Then Exit While             'LowByte der EEPROM-Adresse senden
          If Twisend(&B00000001) <> &H28 Then Exit While        'Aktuelles String-Byte senden
          Printbin Buffer(adree) ; 1                            'Aktuelles Byte zum Debuggen auch zur UART ausgeben
          Incr Adree                                            'EEPROM-Adresse erhöhen
    Writedone:
          Twistop
        Wend
        Print "<Schreiben fertig>";
    Loop
    End Sub
    '----------------------------------------------------------
    Function Twistart() As Byte
      Twcr = &B10100100                                         'START-Signal erzeugen
      Do: Loop Until Twcr.twint = 1                             'Warten bis fertig
      Twistart = Twsr And &B11111000                            'Status-Code zurückgeben
    End Function
    '----------------------------------------------------------
    Function Twisend(ByVal Databyte As Byte) As Byte
      Twdr = Databyte                                           'Byte ins Datenregister
      Twcr = &B10000100                                         'TWI-Operation starten
      Do: Loop Until Twcr.twint = 1                             'Warten bis fertig
      Twisend = Twsr And &B11111000                             'Status-Code zurückgeben
    End Function
    '----------------------------------------------------------
    Function Twireceive(ByRef Databyte As Byte) As Byte
      Twcr = &B10000100                                         'TWI-Operation starten
      Do: Loop Until Twcr.twint = 1                             'Warten bis fertig
      Databyte = Twdr
      Twireceive = Twsr And &B11111000                          'Status-Code zurückgeben
    End Function
    '----------------------------------------------------------
    Sub Twistop()
      Twcr = &B10010100                                         'STOP-Signal erzeugen
    End Sub
    Code:
    $regfile = "m8def.dat"
    $crystal = 3686400
    
    'Config Portd = Output
    
    Dim Twi_status As Byte
    Dim Twi_data As Byte
    
    Declare Sub Twi_init_slave                                  'Declaration der Sub bzw. Funktionen
    Declare Function Twi_wait() As Byte
    Declare Sub Ampelschleife
    Dim X As Integer
    Dim Y As Integer
    
    Ddrb = &B00111111                                           'Pins PB0 - PB5: Ausgang
    Ddrd = &B11110011                                           'Eingang PD2-PD3
    Portd = &B00001101                                          'Pullup von Pin PD2 - PD3 aktivieren
    
    Enable Int0
    Enable Int1
    Config Timer1 = Timer, Prescale = 1024                      'Timer-Takt ist Quarz/1024
    Enable Timer1                                               'Timer1-Overflow-Interrupt ein
    Enable Interrupts
    
    Twi_data = 0
    Call Twi_init_slave
    '---------------------------------------------------------
    'Hauptschleife
    Do
       Twi_status = Twi_wait()
       If Twi_status = &H80 Then
          Portd 0# = Twi_data
       End If
       If Portd.0 = 0 Then
       GoSub Ampelschleife
       End If
    Loop
    '----------------------------------------------------------
    'Unterprogramme
    Sub Twi_init_slave()                                        'Twi als Slave aktivieren
       Twsr = 0
       Twdr = &HFF
       Twcr = &B00000100
       Twar = &B10100010                                        'Slaveadresse
       Twcr = &B01000100
    End Sub
    
    Function Twi_wait() As Byte
       Local Twcr_local As Byte
       Twi_wait = &HF8
       'warten Twint gesetzt
       Twcr_local = Twcr And &H80
       If Twcr_local = &H80 Then
          Twi_data = Twdr
          Twi_wait = Twsr And &HF8
          Twcr = Twcr Or &B10000000
       End If
    End Function
    '----------------------------------------------------------
    Sub Ampelschleife()
    Timer1 = 1
    Do
    X = Timer1
     If X = 0 Then
        Exit Do
     End If
       Select Case X
             Case 2                                             'Hauptschleife: LED's blinken lassen
                Portd 0.6 = 1
                Portd 0.5 = 1
             Case 5000
                Portd 0.7 = 1
                Portd 0.6 = 0
                Portd 0.5 = 0
             Case 30000
                Portd 0.7 = 0
                Portd 0.6 = 1
             Case 35000
                Portd 0.5 = 1
                Portd 0.6 = 0
       End Select
       Disable Timer1
    Loop
    End Sub
    '----------------------------------------------------------
    Danke für eure Antworten und Hilfe
    MfG Schnassi

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

    beim Master sollte der Wert für TWBR mind. 10 sein, da Atmel sonst nicht garantiert, das es immer funktioniert ! Siehe Datenblatt eines bel. AVR.

    Beim Slave gibts da mind. einen Verschreiber beim setzen des PortD's.
    Die Function TWI_Wait() wartet nicht, sondern läuft gleich durch, oder ist das mit der Hauptschleife verknüpft ?!

  3. #3
    Hallo !
    Danke erst einmal für die Antwort. Ich werde die Werte erst einmal ändern und schauen was passiert. Ich habe die Grundschleife vom Master aus dem AVR - Buch übernommen und war froh überhaupt ein kleinen Lichtblick zu haben. Beim Slave habe ich den Schreibfehler oben im Code entdeckt, aber in meinen Programm ist der nicht. (wird wohl beim kopieren pasiert sein, da ich dort noch kleinigkeiten gelöscht habe).
    Mfg Schnassi

Berechtigungen

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