Moin Moin!
folgendes habe ich vor über TWI zu realisieren:
1. Master schickt einem Slave z.Bsp. ein Byte (ne 25)
Master geht wieder offline und hört als Slave den Bus ab
Slave empfängt und führt eine Aktion aus
2. ist ein Befehl für den Slave (25) eingetroffen soll er zum Master werden
und dem vorherigen Master, der jetzt Slave ist, ein Byte zurück schicken
Nun habe ich mir mal den Multimaster TWI Code aus RN Wissen angeschaut
und herumprobiert. Ich bin soweit gekommen, dass ich mit beiden Controllern jeweils als Master senden und als Slave empfangen kann.
Jetzt ist nur noch das Problem das ich keine automatische Kommunikation hin bekomme. Also ich drücke zu 1. einen Taster => Slave (Controller2) zeigt mir an das er was empfangen hat.
Aber ich kann jetzt mit dem Befehl leider nicht automatisch antworten.
In dem Progbeispiel unten sendet der zweite Controller aller 1seck den Wert den er eigentlich erst nach dem Befehl vom anderen Controller bekommen sollte.
Dann versteh ich auch folgen Code noch nicht so richtig:
For Temp = 1 To 1
Twi_mst_buff(temp) = 25
Next
in Verbindung mit:
Twi_mt_data = Varptr(twi_mst_buff(1))
Code:
$regfile = "m8def.dat"
$crystal = 14318181
$include "MyTWI.bas"
$baud = 9600
$hwstack = 80
$swstack = 80
$framesize = 80
Const Tmr_c_prescale = 64
Const Tmr_c_preload = 131
Const Tmr_c_divis = 1000 '250 alt
Declare Sub Twi_show_state(byref State As Byte)
'-----------------2x20 LCD Display an Port c =>Conector -------------------------------------------------------------------------------------------------
Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portb.2 , Rs = Portb.0 ' Pinbelegung "LCD-Port)"
' SV2 1 2 3 4 6 8 ' Pinbelegung SV9 Board
Config Lcd = 20 * 4
'Config Porta = Output
Config Lcdbus = 4
Initlcd
Cursor Off
Locate 1 , 1
Lcd "1 mS Ticker"
Cls
'------------------------------------------------------------------------------- Configuration DS1820
Config 1wire = Portb.1
Dim Id1(8) As Byte
Dim Id2(8) As Byte
Dim Ar1(2) As Byte
Dim Ar2(2) As Byte
Dim Temp1 As Byte
Dim Temp2 As Byte
Id1(1) = 1wsearchfirst()
Id2(1) = 1wsearchnext()
'-------------------------------------------------
' lokale I2C Adresse (als Slave)
'-------------------------------------------------
Const Mn1_adr = &H6E
'-------------------------------------------------
' fremde I2C Adresse (als Master)
'-------------------------------------------------
Const Mn2_adr = &H6A
Dim Slv_byte As Byte 'sende Byte (irgendwas)
Dim Twi_mst_buff(24) As Byte 'Buffer für Masterfunktionen
Dim Twi_slv_buff(24) As Byte 'Buffer für Slavefunktionen
'-------------------------------------------------
Config Timer0 = Timer , Prescale = Tmr_c_prescale 'Timer 1mS
On Timer0 Interrupt_ticker ' Timer for Timer Queue
Dim Timeout As Byte
Dim Timediv As Word
'-------------------------------------------------
Dim Temp As Byte , Temp3 As Byte , Temp4 As Byte
Twi_slv_addr = Mn1_adr 'lokale I2C-Adresse
Twi_sr_data = Varptr(twi_slv_buff(1)) 'datenbuffer empfang
Twi_st_data = Varptr(twi_slv_buff(1)) 'datenbuffer senden
Twar = Twi_slv_addr + 1 'I2C Adress Mega32 + GCA
Config Twi = 400000 'I2C Speed
On Twi Twi_mst_slv_isr , Nosave 'ISR f. TWI
Gosub Twi_sense 'Aktivieren Slave-Funktion
Enable Timer0 'Timer
Enable Interrupts 'Generell
'---------------------------------------------
'
'---------------------------------------------
Do
'****************************************************************************** Sensor 1
1wreset 'reset
1wwrite &H55 'Match Rom command
1wwrite Id1(1) , 8 'Id von Sensor 1
1wwrite &H44 'Convert T
'300 'warten bis convert T fertig ist
1wreset 'reset
1wwrite &H55 'match rom command
1wwrite Id1(1) , 8 'id von sensor 1
1wwrite &HBE
Locate 1 , 14
Ar1(1) = 1wread(2)
Temp1 = Makeint(ar1(1) , Ar1(2))
Temp1 = Temp1 / 2 'Ar(1)
Lcd "Out1:" ; Temp1
'******************************************************************************* Sensor2
1wreset 'reset
1wwrite &H55 'Match Rom command
1wwrite Id2(1) , 8 'Id von Sensor 2
1wwrite &H44 'Convert T
' 300 'warten bis convert T fertig ist
1wreset 'reset
1wwrite &H55 'match rom command
1wwrite Id2(1) , 8 'id von sensor 2
1wwrite &HBE 'scratchpad lesen
Locate 2 , 14
Ar2(1) = 1wread(2)
Temp2 = Makeint(ar2(1) , Ar2(2))
Temp2 = Temp2 / 2
Lcd "Out2:" ; Temp2
'******************************************************************************* I2C Betrieb
'Locate 1 , 1
' Lcd "1 mS Ticker " ; Timediv
'Locate 4 , 10
'Lcd Twi_sr_data
If Twi_slv_flag = &H60 Then Temp4 = 25
If Twi_slv_flag <> 0 Then
'-----------------------------------------------------------------
' Ergebnis als SLave auswerten
' Vorsicht, der Bus ist solange blockiert
'-----------------------------------------------------------------
Select Case Twi_slv_flag
Case &H60 :
Locate 1 , 1
Lcd ; "SLVrecv" ; 'es ist was empfangen worden Spc(30)
Locate 1 , 9
Lcd Hex(twi_slv_addr) ; " ";
For Temp = 1 To Twi_sr_cntr
Locate 1 , 11
Lcd Hex(twi_slv_buff(temp)); 'print der Daten Twi_slv_buff(temp)
Next
Case &HA8 :
Locate 2 , 1
Lcd ; "SLVtran" ; 'es ist was abgeholt worden Spc(30)
Locate 2 , 9
Lcd Hex(twi_slv_addr) ; " ";
For Temp = 1 To Twi_st_cntr
Locate 2 , 11
Lcd Twi_slv_buff(temp); 'print der Daten Hex(twi_slv_buff(temp));
Next
Case &H70 :
Locate 3 , 1
Lcd ; "SLAVE GCA :" ; 'ein General Call ist gekommen Spc(30)
Locate 3 , 10
Lcd Hex(twi_slv_addr) ; " ";
For Temp3 = 1 To Twi_sr_cntr
Print Hex(twi_slv_buff(temp)); 'print der Daten
Next
'Case Else:
'Print Chr(7) ; 'Irgendein Fehler
' Call Twi_show_state(twi_slv_flag) 'Print status-text
End Select
'Locate 4 , 1
'Lcd Twi_slv_buff(temp) ; Twi_sr_cntr ; Temp3
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
For Temp4 = 1 To Twi_sr_cntr
Locate 4 , 15
Lcd Twi_slv_buff(temp4)
'-----------------------------------------------------------------
' Jede Sekunde was senden & empfangen
'-----------------------------------------------------------------
If Timeout = 1 Then
Gosub Master_transmit 'Senden in einer SUB
If Twi_mst_flag = 0 Then 'Hats geklappt ?
Timeout = 0 'ja
' else (sonst probieren wir's gleich nochmal)
End If
End If
'-----------------------------------------------------------------
Locate 4 , 1
Lcd Temp3 'Twi_slv_buff(temp) ; Twi_sr_cntr ;
Next
Loop
End
'----------------------------------------
' 1 mS Ticker
'----------------------------------------
Interrupt_ticker: ' Timer for Timer Queue
Timer0 = Tmr_c_preload
Incr Timediv
If Timediv = Tmr_c_divis Then
Timeout = 1 'eine Sekunde ist rum
Timediv = 0
End If
Return
'
'----------------------------------------
$include "Twi_show_state.bas"
'----------------------------------------
Run_wait_master:
Gosub Mst_start 'aufruf
Select Case Twi_mst_flag 'ergebnis ?
Case Twi_m_sent:
Locate 3 , 1 'gesendet
Lcd "<<MASTsent:" ; Hex(twi_mst_addr) ; " ";
Print
For Temp = 1 To Twi_mt_cntr
Locate 3 , 14
Lcd Twi_mst_buff(temp);
Next
Print
Twi_mst_flag = 0
Case Twi_m_recv:
Locate 4 , 1 'geholt
Lcd ">>MASTread:" ; Hex(twi_mst_addr) ; " ";
Print
For Temp = 1 To Twi_mr_cntr
Locate 4 , 14
Lcd Twi_mst_buff(temp); 'Hex(twi_mst_buff(temp))
Next
Print
Twi_mst_flag = 0
'Case Else: 'irgendein Problem
'Print Chr(7) ; Hex(twi_mst_addr) ; " ";
'Call Twi_show_state(twi_mst_flag)
End Select
Return
'----------------------------------------
' Beispiel 8 byte senden,
' dann mit Rep.Start von gleicher adresse 3 Byte empfangen
'----------------------------------------
Master_transmit:
' sende buffer (mit testdaten) füllen
For Temp = 1 To 1
Twi_mst_buff(temp) = Temp1 'Slv_byte
Next
Twi_mst_addr = Mn2_adr 'I2C adresse
Twi_mt_cntr = 1 '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
Ich weiss nicht wie ich die empfangenen Daten aus "Twi_sr_cntr" weiter verwenden kann, in eine Variable bekomme.
HILFE
Danke MAT
Lesezeichen