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:
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"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
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







Zitieren

Lesezeichen