-
so...
leider komme ich nicht weiter. Jetzt ist es auch noch so, dass noch nicht mal das alte Programm funktioniert, mit dem orginalcode läuft alles noch, jedenfalls bei einme der Slavs.
Ich weiss nicht mehr weiter...Irgend eine Idee?
Gruß & Danke MAT
-
Keep cool, das kriegen wir schon hin.
Ich hab nur leider dieser Tage jobmäßig den A.. offen. Aber ich bin dran !
-
Schön von einer Unterstüzung zu lesen! Ich komme immer nur am WE dazu etwas zu machen (der job eben) und das wurmt mich...
Ok bin mal gespannt und werd am we mich noch mal melden.
MAT
-
Hallo Robert,
inzwischen kommunizieren meine Master/Slaves recht gut miteinander.
Doch leider hab ich noch das Problem das ich nicht richtig mit dem Overlay umgehen kann.
Ich habe die Variable Datensingle in dem die Temperatur aus dem ds1820 drin steht (23.55). Nun wollte ich diese senden:
Auszug:
Code:
Dim Datensingle As Single
Dim Datenbyte (4) As Byte At Datensingle Overlay
und dann so rausschicken:
Code:
Master_transmit:
' sende buffer (mit testdaten) füllen
For Temp = 1 To 4
Twi_mst_buff(1) = Datenbyte 'Temp1 'Temperatur Sensor1
Next
'
'Print "Datenbyte" ; Datenbyte
Twi_mst_addr = Mn2_adr 'I2C adresse
Twi_mt_cntr = 4 '8 ' erstmal 8 Byte senden
Twi_mt_data = Varptr(twi_mst_buff(1)) ' adresse Daten
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
Return
doch leider kommt nicht der richtige Wert heraus, was mache ich falsch?
MAT
-
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
-
Mmmhh.
Bei der Kellerzentrale werden ja erstmal Bytes gesendet.
Und da kriegt der Master offenbar schon kein ACK.
Bis zu diesem ACK macht eigentlich die TWI-Hardware alles alleine.
d.h. man müsste wohl erstmal sicherstellen, das elektrisch auch alles o.k. ist.
Ideal wäre dazu, einen anderen, dzt. funktionierenden Slave dort mal anzuschliessen, wo die Kellerzentrale drauf steckt. Die Sinnhaftigkeit der Daten wäre ja mal wurst, Hauptsache, er ACKed seine Adresse
(oder eben auch nicht)
-
Das Spielchen habe ich schon durch... Teilweise hatte es auch funktioniert und das wundert mich! Ich werde mal dennnoch einen anderen Slave kreieren.
melde mich später wieder!
Danke Dir schon jetzt mal :)
-
Hallo Robert,
heute bin ich dazu gekommen einen Mega32 mit einem gekürzten Code einzubauen. Also die Hardware ist funktionstüchtig und auf dem Mega wird nur ein ADC ausgelesen, also nur der Code für den ADC siehe oben.
das Gleiche werde ich jetzt auch noch mit nem Mega 644p versuchen. Ansonsten gibt es in meinem Code von oben ein Problem, doch wo nur?
Kannst Du bitte noch einmal darüber schauen?
Danke und Gruß
MAT
-
Hmmm,
habe jetzt die Programmteile wo irgend ein IRQ angesprungen werden kann (außer TWI) herausgenommen aber trotz allerdem geht es nicht :(
Irgend eine Idee?
-
Update:
* habe die Hardware nochmal überprüft => ist i.O.
* mitterweilen wird von Zeit zu Zeit Daten versendet, jetzt ist es so, dass öffters hintereinander ein Timeout bei dem Slave entsteht
Werde weiter suche und auf Hilfe hoffen!
MAT