HiRobert,

ich habe mal wieder ein kleines problem mit dem TWI-Multimasterbetrieb!

Inzwischen hole ich mir von 2 Slaves einige Daten ab, was auch gut geht:

Master:
Code:
Sub Aufrufen

If Twi_1 = 0 Then                                                               'Timerabfrage erst starten wenn die Uhr gestellt wurde
    If Timecount1 = 2 Then
    Gosub Daten_hofslave
    Timecount1 = 3
  End If
    If Timecount1 = 6 Then
    Gosub Daten_kellerslave
    Timecount1 = 7
  End If
    If Timecount1 = 9 Then
    Gosub Daten_kellerzentrale
    Timecount1 = 0
  End If
End If



Subprozeduren:

Daten_hofslave:
      If Send_flag = 0 Then
      Send_flag = 1
'(
      Slave_adress = &H6C                                                       'dann Slaveadresse (Empfänger) setzen
      Send_byte = 6                                                             'zu sendende Bytes
      Fenster_komando(1) = 5                                                    'Komando an den Slave 5= Slave schreibt momentan die Absenderadresse mit in die zu holenden Daten
      Fenster_komando(5) = &H6A                                                 'von wem kommt die Anfrage
      Call Master_transmit(slave_adress , Send_byte , Fenster_komando(1))       'obrige Daten werden der Sendesub übergeben
')
      Twi_mst_addr = &H6C                                                       'jetzt gleich wieder daten vom Slave holen
      Twi_mr_cntr = 7                                                           ' dann 7 Byte empfangen:1-4.=Temperatur_single, 5-6.=Licht_word, 7.=Absender_byte
      Twi_mr_data = Varptr(tout)                                                'Daten direkt in die Variablen schreiben, beginnend bei mit: dim Tout as  Single
      Gosub Run_wait_master
      End If
Return

Daten_kellerslave:
      If Send_flag = 0 Then
      Send_flag = 1
      Slave_adress = &H6E
      Send_byte = 6                                                             ' dann Slaveadresse (Empfänger) setzen
      Fenster_komando(1) = 5
      Fenster_komando(5) = &H6A                                                 ' Kommado
      Call Master_transmit(slave_adress , Send_byte , Fenster_komando(1))       'nach Tastendruck aus der select case Übergabe werden
     'Twi_sr_cntr = 0
      Twi_mst_addr = &H6E                                                       'Daten vom DS1307 &hD01 (Lesebefehl) holen =>
      Twi_mr_cntr = 6                                                           'dann 6 Byte empfangen:1.=T_vorl, 2.=T_rückl, 3.=Automatik, 4.=Portbrenner, 5.=Absender, 6.=Relwasser
      Twi_mr_data = Varptr(t_vorl)                                              ' empfangsbuffer
      Gosub Run_wait_master
      End If
Return

Daten_kellerzentrale:
       If Send_flag = 0 Then
      Send_flag = 1
      Slave_adress = &H5A
      Send_byte = 6                                                             ' dann Slaveadresse (Empfänger) setzen
      Fenster_komando(1) = 5
      Fenster_komando(5) = &H6A                                                 ' Kommado
      Call Master_transmit(slave_adress , Send_byte , Fenster_komando(1))       'nach Tastendruck aus der select case Übergabe werden
      'Twi_sr_cntr = 0
      Twi_mst_addr = &H5A                                                       'Daten vom DS1307 &hD01 (Lesebefehl) holen =>
      Twi_mr_cntr = 6                                                           ' dann 6 Byte empfangen:1-4=Single Bat-Spannung, 5.=Türkontakte, 6.=Absender
      Twi_mr_data = Varptr(batdata)                                             'Empfangsbuffer
      Gosub Run_wait_master
      End If
Return
Die Subs für die Daten_hofslave und Daten_kellerslave funktionieren ohne Weiteres. Aber für Daten_kellerzentrale bekomme ich immer ein: MT Sla W Transmitted Not Acked"
als Antwort. Was kann hier der Fehler sein??
Hier noch der Code vom Daten_kellerzentrale:
Code:
$regfile = "m644pdef.dat"
$crystal = 14745600

$include "MyTWI.bas"

$baud = 19200

$hwstack = 64
$swstack = 64
$framesize = 64

Ddrb = &B00000000                                                               'PortB als Eingang für die Funksensorüberwachung
Portb = &B11111111                                                              'PullUp's einschalten
Ddrc = &B00000000                                                               'PortB als Eingang
Portc = &B00000100
Ddrd = &B11111000
Portd = &B00000100

Config Adc = Single , Prescaler = Auto , Reference = Off
Start Adc

Config Timer1 = Timer , Prescale = 1024                                         'Timer1 (16bit, 65535) läuft mit Quarztakt/1024
Const Timervorgabe = 36735                                                      'Anfangswert ab der der Timer1 beginnen soll zu zählen (von 58336=>65535)
Enable Timer1                                                                   ' Schalte Überlaufinterupt von Timer1 ein
On Timer1 Timer_irq                                                             ' 1secint => Sprungmarke an die gesprungen wird, wenn timer1 übergelaufen ist => danach weiter Start ADC

Config Int0 = Rising                                                            'Interrupt zur Netzspannungsdedektion
On Int0 Int0_isr                                                                'Sprungmarke interrupt nach dem infrarot Signal anliegt
Enable Int0
Enable Interrupts
Dim Irq_z As Byte

'------------------------------------------------------------------------------- Programmvariablen
Dim Relon As Bit



'-------------------------------------------------------------------------------   Config TWI
Dim Batterie As Word
Dim Batspannung As Single
Dim Tuerkontakt As Byte
Dim Absender As Byte

Declare Sub Twi_show_state(byref State As Byte)                                 ' Fehleranzeige für TWI übertragung
Const Mn1_adr = &H5A                                                            'lokale I2C Adresse   (als Slave)
Dim Twi_mst_buff(24) As Byte                                                    'Buffer für Masterfunktionen
Dim Twi_slv_buff(24) As Byte                                                    'Buffer für Slavefunktionen

Dim Temp As Byte

Dim Slave_adress As Byte , Send_byte As Byte , Speicherpointer As Byte
Declare Sub Master_transmit(byref Slave_adress As Byte , Byref Send_byte As Byte , Byref Speicherpointer As Byte)       'Declarierung der Sub =>mit byref wird immer nur ein Zeiger auf die Speicherstelle
                                                                                          ' verwiesen und nicht ein Wert übergeben
Twi_slv_addr = Mn1_adr                                                          'lokale I2C-Adresse
Twi_sr_data = Varptr(twi_slv_buff(1))                                           'datenbuffer empfang
Twi_st_data = Varptr(batspannung)                                               'datenbuffer senden, von dort holt sich der Master die Daten

  Twar = Twi_slv_addr + 1                                                       'I2C Adress Mega32 + GCA
  Config Twi = 100000                                                           'I2C Speed
  On Twi Twi_mst_slv_isr , Nosave                                               'ISR f. TWI
  Gosub Twi_sense                                                               'Aktivieren Slave-Funktion
  Enable Interrupts                                                             'Generell



'############################################################################### Programmstart

Do


If Portd.7 = 1 Then Set Relon
If Pinc.2 = 0 And Portd.7 = 1 Then
 Portd.7 = 0
 Irq_z = 0                                                                      'Netzspannung wieder da?  Or Batmin = 0
 Enable Int0
 Reset Relon
End If

'******************************************************************************* Überwachung Batteriespannung
Batterie = Getadc(1)

Batspannung = Batterie * 4.5                                                    ' Potivoreinstellung 4,5V = 10V Battspannung
Batspannung = Batspannung / 920                                                 ' Spannung auf Wandlerrate umstellen
Batspannung = Batspannung * 2.22                                                ' Faktor für Umrechnung in tatsächlichen Bat-Wert 10V/4,5V
If Portd.7 = 1 Then                                                             ' Unterspannungsüberwachung
  If Batspannung =< 6.7 Then
     Portd.7 = 0
  End If
End If
If Relon = 1 Then                                                               ' Übermittlung das Netzausfall vorliegt => Meldung an Zentrale
  Tuerkontakt.7 = 1
  Else
  Tuerkontakt.7 = 0
End If

'******************************************************************************* Überwachung Türkontakte


If Pinb.0 = 1 Then
  Tuerkontakt.0 = 1
 Else
  Tuerkontakt.0 = 0
  End If
If Pinb.1 = 0 Then
  Tuerkontakt.1 = 1
  Else
  Tuerkontakt.1 = 0
  End If
If Pinb.2 = 1 Then
  Tuerkontakt.2 = 1
  Else
  Tuerkontakt.2 = 0
  End If
If Pinb.3 = 1 Then
  Tuerkontakt.3 = 1
  Else
  Tuerkontakt.3 = 0
  End If
If Pinb.5 = 1 Then
  Tuerkontakt.4 = 0
 Else
  Tuerkontakt.4 = 0
  End If
If Pinb.6 = 1 Then
  Tuerkontakt.5 = 1
  Else
  Tuerkontakt.5 = 0
  End If
If Pinb.7 = 1 Then
  Tuerkontakt.6 = 1
  Else
  Tuerkontakt.6 = 0
  End If


'******************************************************************************* TWI Slavefunktion, hier wird gehört, ob ein andere Master etwas sendet

If Twi_slv_flag <> 0 Then                                                       'ständige Abfrage ob als Slave Daten anliegen  =>Vorsicht, der Bus ist solange blockiert

         Select Case Twi_slv_flag
         Case &H60 :
                     Print ; "Slave empfängt" ;                                 'es ist was empfangen worden
                     Print Hex(twi_slv_addr) ; " ";                             'von Adresse in Hex
                     For Temp = 1 To Twi_sr_cntr                                'Daten aus Twi_sr_cntr in den puffer schreiben
                     Print Hex(twi_slv_buff(temp));                             'print der Daten
                     Next
         Case &HA8 :

                     Print ; "Slave sendet" ;                                   'es ist was abgeholt worden  Spc(30)
                     Print Hex(twi_slv_addr) ; " ";
                     For Temp = 1 To Twi_st_cntr
                     Print Twi_slv_buff(temp);                                  'print der Daten Hex(twi_slv_buff(temp));
                       Next

         Case &H70 : Print Spc(30) ; "SLAVE GCA :" ;                            'ein General Call ist gekommen
                     Print Hex(twi_slv_addr) ; " ";
                     For Temp = 1 To Twi_sr_cntr
                     Print Hex(twi_slv_buff(temp));                             'print der Daten
                       Next
         Case Else:
                     Print Chr(7) ; Hex(twi_mst_addr) ; " ";                    'Irgendein Fehler
                     Call Twi_show_state(twi_slv_flag)                          'Print status-text



         End Select
         Print
         Twi_slv_flag = 0                                                       'löschen marker
         Twi_slv_stat = 0                                                       'löschen marker
         Gosub Twi_sense                                                        'alles wieder enablen
                                   'und Bus freigeben
      End If
'*******************************************************************************



Print " IRQ-Zaehler " ; Irq_z
Print " Batspannung " ; Batspannung
Print " Relon " ; Relon
Loop
End

'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SUBROUTINEN
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Timerschaltung für Impulse Resetbaustein Netzüberwachung
Timer_irq:
Toggle Portd.6
Timer1 = Timervorgabe
Return

'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Interruptabfrage Netzausfall
Int0_isr:
Portd.7 = 1
Disable Int0
Return


'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$include "Twi_show_state.bas"
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Senderoutine TWI
Run_wait_master:
        Gosub Mst_start                                                         'aufruf
      Select Case Twi_mst_flag                                                  'ergebnis ?
      Case Twi_m_sent:                                                          'gesendet
               'Print "<<<<<<MASTER sent:" ;

               'Print Hex(twi_mst_addr ) ; " ";
               'Print "twi_mst_buff(temp):" ; Hex(twi_mst_buff(temp));
               For Temp = 1 To Twi_mt_cntr
               Next
               Print
               Twi_mst_flag = 0

      Case Else:                                                                'irgendein Problem
                'Print "Übertragungsfehler" ; Chr(7) ; Hex(twi_mst_addr) ; " ";
                Call Twi_show_state(twi_mst_flag)
      End Select
   Return


'############################################################################### Sendesub
Sub Master_transmit(byref Slave_adress As Byte , Byref Send_byte As Byte , Byref Speicherpointer As Byte)       'Sub in der die Adresse des Empfängers steht und der Zeiger aus der Callprozedur

   Twi_mst_addr = Slave_adress                                                  'I2C Adresse Slave
   Twi_mt_cntr = Send_byte                                                      '4 Byte senden
   Twi_mt_data = Varptr(speicherpointer(1))                                     'Daten senden => Varptr(Speicherpointer(1)) Speicherpointer = Zeiger auf eine
                                                                                 ' Speicherstelle, nicht auf den Wert, aus der Callsubroutine (Temperaturbyte(1))
   Twi_mr_cntr = 0

   'Twi_mr_cntr = 1                                          ' dann 3 Byte empfangen
   'Twi_mr_data = Varptr(twi_mst_buff(1))                    ' empfangsbuffer

   Gosub Run_wait_master                                                        ' auf gehts

   End Sub
   Return