PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mikrokontroller bei I2C als Slave und Master ,möglich?



tranh85bo
22.10.2009, 19:17
Hallo , zusammen
Ich habe 2 Platine und 2 Ultraschallsensoren. Ein Platin(Platin A) ist für Steuerung von ein Mikrokopter , ein Platin (Platin B) ist für Filtieren und Auslesen für die Werte(Abstand) , die aus Ultraschallsensoren kommen .Jetzt will ich die gefilterte Werte von dem Platin B mit der Ultraschallsensoren zur verbleibende Platin A übertragen .Das heisst , das Platin B spielt die Rolle als Master bezogen auf Ultraschallsensoren und als Slave bezogen auf Platin A . Das Platin A hat die Kommunikationen mit 4 weitere Motoren via I2C .Deswegen kann ich nicht das Platin A als Slave setzen sonst ist Platin A auch Master und Slave .Die Frage ist ob ich ein Platin sowohl als Master als auch als Slave einstellen?

Mit freundlichen Grüssen.
Vielen Dank

Jaecko
22.10.2009, 19:57
Sowas nennt sich Multimaster und ist eigentlich gängig. D.h. jeder ist Slave, bis er selbst was senden will. Da muss man halt dann vorher noch irgendwie sicherstellen, dass nie 2 gleichzeitig senden. Oder vorher den Bus prüfen, ob was los ist.
Mit den Bascom-eigenen Befehlen weiss ich nicht, obs da geht. Aber mit "nacktem" Zugriff auf die TWI-Register gehts sicher.

tranh85bo
22.10.2009, 21:24
Vielen Dank für schnelle Anwort ! Ich werde gleich probieren .Aber bei Multimasterbetrieb muss man die Adresse von Masters zuweisen ?

Mit freundlichen Grüssen

mat-sche
23.10.2009, 16:38
hi,

lese Dir das mal durch: http://www.rn-wissen.de/index.php/TWI_Praxis_Multimaster

läuft bei mir sehr stabil im Multimasterbetrieb!

tranh85bo
05.11.2009, 14:51
hi,
Ich habe das Programm durchgelesen .Ich habe viele nicht verstanden. Kannt jemand von euch mir erklären ?


'-------------------------------------------------
' Die eigene I2C Adresse (als Slave)
'-------------------------------------------------
Const Mn1_adr = &H6A

'-------------------------------------------------
' fremde I2C Adresse (als Master)
'-------------------------------------------------
Const Mn2_adr = &H6E


In diesen Abschnitt heißt es, unsere Atmega32 hat sowohl masteradresse als auch Slaveadresse ? Ich glaube jeder braucht und darf nur 1 Adress haben.



On Twi Twi_mst_slv_isr, Nosave 'ISR f. TWI

Gosub Twi_sense 'Aktivieren Slave-Funktion



Diese 2 Funktionnen (Twi_mst_slv_isr und Twi_sense) wird in Assemler geschrieben und ich verstehe nicht . Wenn ich in C oder Bascom schreiben will , wie ist die Vorgehenweise.





If Twi_slv_flag <> 0 Then
'-----------------------------------------------------------------
' Vorsicht, der Bus ist solange blockiert
'-----------------------------------------------------------------
Select Case Twi_slv_flag
Case &H60 : Print Spc(30) ; "SLAVE recv:" ; 'es ist was empfangen worden
Print Hex(twi_slv_addr) ; " ";
For Temp = 1 To Twi_sr_cntr
Print Hex(twi_slv_buff(temp)); 'print der Daten
Next
Case &HA8 : Print Spc(30) ; "SLAVE tran:" ; 'es ist was abgeholt worden
Print Hex(twi_slv_addr) ; " ";
For Temp = 1 To Twi_st_cntr
Print Hex(twi_slv_buff(temp)); 'print der Daten
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) ; 'Irgendein Fehler
Call Twi_show_state(twi_slv_flag) 'Print status-text
End Select
Print
Twi_slv_flag = 0 'quittieren
Twi_slv_stat = 0 '
Gosub Twi_sense 'Slave wieder scharfmachen
'und Bus freigeben
End If


in diese Funktion wird Daten auf dem Slave empfangt oder aus der gesendet aber ich seh keine Funktion um die Daten zu holen oder zu übertragen .Soweit ich verstehe ,die Funktion gibt nur die Daten aus dem Bildschirm oder durch RS232.

Und ich habe eine allgemein Frage über i2c :
Wenn ich ein mit TWI hardware unterstützte Platin (Platen C) hat,kann ich das in eine andere System hängen um das Status von System auslesen.Das System hier meine ich noch ein Master (Platin A) und Slave (Platin B ) . Sie kommunizieren sich mit einander . Mit Platin C kann ich das Status in dem System (Platin A und B) bekommen .
z.B : Platin A spricht platin B an . Platin B anwortet mit SLA+W . Kannt Platin C das Status SLA+W lesen?

Ich danke euch im Voraus

Mit freundlichen Grüssen

mat-sche
05.11.2009, 18:08
hi,

ich versuche es dir zu erklären:



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
Declare Sub Twi_show_state(byref State As Byte) ' Fehleranzeige für TWI übertragung ' verwiesen und nicht ein Wert übergeben
Const Mn1_adr = &H6A 'lokale I2C Adresse (als Slave), alle geraden Zahlen von &H02 - &HFE
'Const Mn2_adr = &H6A 'fremde I2C Adresse (als Master) wir in der Sub mit übergeben

Dim Twi_mst_buff(24) As Byte 'Buffer für Masterfunktionen
Dim Twi_slv_buff(24) As Byte 'Buffer für Slavefunktionen
Dim Tempo As Byte , Twi_daten 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 = 100000 'I2C Speed
On Twi Twi_mst_slv_isr , Nosave 'ISR f. TWI aktivieren

Gosub Twi_sense 'Aktivieren Slave-Funktion
'Enable Timer2 'Timer
'Generell Enable Interrupts


hier werden die "globalen" Funktionen festgelegt. Das ein TWI Teilnehmer eine Master/Slavefunktion erfüllen kann, muss er einmal eine Adresse als Master haben und eine als Slave.

Dim Twi_mst_buff(24) As Byte => ist ein Array wo dann die Daten reingeschrieben werden.

Twi_st_data = Varptr(twi_slv_buff(1)) & Twi_sr_data = Varptr(twi_slv_buff(1)) => Daten für Slave sende und empfangsdaten, hier wird nur die Adresse mit varptr übergeben.

On Twi Twi_mst_slv_isr , Nosave das ist eine Interruptroutine die benötigt wird für das senden und empfangen als slave oder master. nicht weiter zu beachten.

Hier ist der Abschnitt für das Senden als Master:


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 Tempo = 1 To Twi_sr_cntr 'Daten aus Twi_sr_cntr in den puffer schreiben
Print Hex(twi_slv_buff(temp)); 'print der Daten
Twi_daten = Twi_slv_buff(temp)
Next


Nach dem etwas über TWI reinkommt (Twi_slv_flag = &H60 bedeutet das was empfangen wird ) und für die Adresse bestimmt ist, werden die Daten in den Twi_slv_buff(24) geschrieben. Dann stehen die Daten die empfangen werden hintereinander in dem Array und können ausgelesen werden.
=> diese Funktion ist wichtig wenn der Kontroller als Slave angesprochen wird!






'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++ TWI
Run_wait_master:
Gosub Mst_start 'aufruf
Select Case Twi_mst_flag 'ergebnis ?
Case Twi_m_sent: 'gesendet
Print "<<<<<<MASTER sendet:"
Print Hex(twi_mst_addr ) ; " " ; Spc(30);
For Temp = 1 To Twi_mt_cntr
Print "twi_mst_buff(temp):" ; Hex(twi_mst_buff(temp)) ; Spc(30);
Next
Print
'Reset Twi_error
Twi_mst_flag = 0
Case Twi_m_recv: 'geholt
Print ">>>>>>MASTER read:" ;
Print Twi_mst_addr ; " ";
For Temp = 1 To Twi_mr_cntr
Print Twi_mst_buff(temp); 'Hex(twi_mst_buff(temp));
Next
Print
'Reset Twi_error
Twi_mst_flag = 0
Case Else: 'irgendein Problem
'Set Twi_error
'Print "Twi_error" ; Twi_error
Print "fehler" ; Chr(7) ; Hex(twi_mst_addr) ; " ";
Call Twi_show_state(twi_mst_flag)
End Select
Return

'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++ TWI 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
Twi_mt_cntr = Send_byte '8 ' erstmal 8 Byte senden
Twi_mt_data = Varptr(speicherpointer(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
End Sub
Return


Hier ist der Abschnitt für das Senden als Master:
Sub Master_transmit(byref Slave_adress As Byte , Byref Send_byte As Byte , Byref Speicherpointer As Byte)

In der Sub werden folgende Daten festgelegt:
*Twi_mst_addr = &H61 => ist die TWI-Adresse des Slavs an die Daten gehen sollen
*Twi_mt_cntr = => wieviel Byte sollen gesendet werden
*Twi_mt_data = Varptr(speicherpointer(1)) => die zu übertragenden Daten, aber nur die Adresse der Daten wo sie im Ram liegen, nicht die Daten an sich.
*Gosub Run_wait_master und jetzt wird mit den Infos in die Senderoutine gesprungen => siehe im Code.

Du kannst nicht direkt die Informationen zwischen zwei Platinen über eine dritte auslesen. Du musst diese an den Bus hängen und diese abhorchen:
1. den Startpunkt einer Sendung von Daten detektieren
2. die Adresse in dem Sendeframe herausfiltern und
3. die Daten auswerten

Dabei musst du alle Start/Stop/daten... zeitrichtig auswerten, nicht so einfach!
Als Erklärung auch noch hier einiges:
https://www.roboternetz.de/phpBB2/viewtopic.php?p=409315#409315
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=41096&highlight=

Wenn Du dann die Übertragung verstanden hast, solltest Du dir ein protokoll oder Ähnliches ausdenken, um die Daten ordentlich zu senden/empfangen und diese dann weiter zu verarbeiten. Schau mal nach SNAP-Protokoll.

Gruß MAT

tranh85bo
09.11.2009, 17:23
Danke für deine Erklärung!Aber ich bin so doof ](*,)

Ich hab nochmal überlegt . Jeder Kontroller hat nur 1 Adresse als Slaveadresse und die andere ist die Adresse von andere Kontroller.In diesem Fall ist &H6A Adresse als Slave und &H6E ist Adresse von anderem.Der &H6A kann Daten zu dem schicken oder empfangen.

Ich denke,dass Twi_sense,Mst_start in Library-Funktion schon fertig geschrieben sind .Aber die Code ist in Assembley geschrieben und ich kann nur grob verstehen.

Wenn man ein Daten senden oder empfangen will, soll man die in TWDR schreiben oder lesen .Oder man kann die fertige Funktion in Bascom benutzen wie i2cbwrite ,i2crbyte ..... Aber ich seh keine hier oder ist der auch in Funktion-library geschrieben.

Wenn ich irgendwas falsch verstehe ,kannst du mir nochmal erklären?



Mit freundlichen Grüssen

mat-sche
10.11.2009, 13:25
hi,

ließ Dir noch mal meinen Beitrag und die Beschreibung auf RN-Wissen zum Thema TWI-Multimaster durch.
Die TWI Funktionen werden nicht durch Bascom High Level Befehle durchgeführt und auch nicht in den Registern.

"Ich denke,dass Twi_sense,Mst_start in Library-Funktion schon fertig geschrieben sind .Aber die Code ist in Assembley geschrieben und ich kann nur grob verstehen.
"

ja richtig, es wird eine Lib für die Sende-Empfangsroutinen benutzt und Du brauchst Dich eigentlich nicht darum zu kümmern.Zum Senden wird die TWISendesub genutzt und für den Empfang die Empfangsroutine.

Spiele einfach mal mit dem Bsp. aus :http://www.rn-wissen.de/index.php/TWI_Praxis_Multimaster

Gruß