Archiv verlassen und diese Seite im Standarddesign anzeigen : Einem Atmega8 drei I²C-Slave Adressen zuweisen?
Hallo,
wie der Titel schon sagt, möchte ich einem Atmega8 drei I²C-Adressen zuweisen. Ist dies möglich wenn ja wie?
Es geht darum das ich, wenn das nicht funktioniert drei Atmegas nehmen muss was ich aber vermeiden wollte da diese nur ein paar berechnungen machen müssen und im prinzip unterfordert sind.
Gruß, Bammel
Naja müssen die Adressen dauerhaft aktiv bleiben? Weil ansonsten kannste ja einfach eine abfrage machen die je nachdem welches Ereigniss du abfragst die Variable in der du die Adresse speicherst mit einer von den dreien Adressen füllt.
Oder wäre das nichts?
Sowas hatte ich mir auch gedacht ich könnte nacheinander die adresse ändern. der ganze µC macht eigentlich ncihts anderes als jeweils ein byte über den I²C zu empfangen und den wert an eine art soft-pwm weiterzugeben.
Naja im grunde genommen kannste einem Controller theoretisch gesehen soviele Adressen zuweisen bis der Speicher voll ist bzw. du halt an die Adressgrenze des TWI kommst.
Im TWI Protokoll tuste ja eigtl nichts weiteres als die Variable wo die Adresse drin ist aufzurufen.
Kannst es dann ja quasi so machen das du Controller 1-3 hast und Controller 1 ist halt der Master und Controller 2 und 3 die Slaves. Und dann verbindeste je einen Pin von Controller 2 und 3 mit einem Pin von Controller 3 und in Controller 1 machste dann einfach eine Abfrage. Also wenn der Pin wo Controller 2 anliegt high ist die Adresse X und wenn der Pin wo Controller 3 anliegt high ist ist die Adresse Y.
ne das geht nicht. ich kann oder will den master nicht verändern.
Mit der Hardware-Schnittstelle (TWI) funktioniert das nicht. Aber bei einer Software-Implementierung ist es kein großartiger Mehraufwand gegenüber nur einer Adresse. Denn dort muss man sowieso nach jedem Byte prüfen, ob es die eigene Adresse war.
Besserwessi
18.06.2010, 22:55
Beim Mega8 wird das schwierig - da müßte man das TWI Interface wohl schon weitgehend in Software machen, zumindest den Addressvergleich.
Man könnte aber auf einen Mega88 oder Mega168 ausweichen. Da kann man einige Adressbits maskieren, sodaß der µC auf 2, 4 oder 8 Adressen anspricht, halt so das 1,2, 3 .. Bits der Adresse ignoriert werden.
Oder, wenn du keine anderen Bausteine dran hast, aktivierst du den "general call" (oder so ähnlich), sodass er auf alle Adressen anspricht. (einfach 0x00 in das Adress-Register schreiben.
Gruß, Yaro
@yaro: das generelle freischalten wäre schlecht ich halte mir die option auf das noch weitere teilnehmer dazukommen. zudem muss ich auch immer wissen welches empfangene byte zu welcher slaveadresse gehört.
@uwegw: wie würde der code den ungefähr aussehen?
mein bisheriger code mit nur einer adresse sieht wie folgt aus:
Call Twi_init_slave
'-------------------------------------------------------------------------------
'***| Hauptprogramm |************************************************* **********
'-------------------------------------------------------------------------------
Do
Newbyte = 0
'schauen ob TWINT gesetzt ist
Twi_control = Twcr And &H80 ' Bit7 von Controlregister
If Twi_control = &H80 Then
Twi_status = Twsr And &HF8 ' Status
'wurde ein Byte geschickt?
If Twi_status = &H80 Or Twi_status = &H88 Then
Command = Twdr ' neue Daten merken
Newbyte = 1 ' merken das ein neues Byte da ist
End If
'TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht
Twcr = &B11000100 ' TWINT löschen, erzeugt ACK
End If
'wenn ein neues Byte gekommen ist verarbeiten
If Newbyte <> 0 Then
'Register zuordnen -> Befehl
Select Case Command
Case 1
Gosub Motor1
Case 2
Gosub Motor2
Case 3
Gosub Motor3
End Select
End If
Loop
End
'-------------------------------------------------------------------------------
'***| Motor 1 |************************************************* ****************
'-------------------------------------------------------------------------------
Motor1:
Index = 1
'1 Byte holen / gibt an wieviele bytes geholt werden sollen hier im beispiel max. 10 "i2cbyte(1 bis 10)"
Gosub I2c_rx
'PWM1 = i2cbyte(1)
Return
'-------------------------------------------------------------------------------
'***| Motor 2 |************************************************* ****************
'-------------------------------------------------------------------------------
Motor2:
Index = 1 '1 Byte holen
Gosub I2c_rx
'PWM2 = i2cbyte(1)
Return
'-------------------------------------------------------------------------------
'***| Motor 3 |************************************************* ****************
'-------------------------------------------------------------------------------
Motor3:
Index = 1 '1 Byte holen
Gosub I2c_rx
'PWM3 = i2cbyte(1)
Return
'-------------------------------------------------------------------------------
'***| I2C-BUS Daten Empfangsroutinen |******************************************
'-------------------------------------------------------------------------------
I2c_rx:
For N = 1 To Index
'erstes Byte empfangen
Newbyte = 0
Do
Twi_control = Twcr And &H80
If Twi_control = &H80 Then
Twi_status = Twsr And &HF8
If Twi_status = &H80 Or Twi_status = &H88 Then
I2cbyte(n) = Twdr
Newbyte = 2
End If
Twcr = &B11000100
End If
If Newbyte = 2 Then Exit Do
Loop
Next N
Return
'-------------------------------------------------------------------------------
'***| TWI: Slavekonfiguration |*************************************************
'-------------------------------------------------------------------------------
Sub Twi_init_slave
Twsr = 0 ' status und Prescaler auf 0
Twdr = &HFF ' default
Twar = &H22 ' Slaveadresse setzen I2C-RX-Adr:Hex22
Twcr = &B01000100 ' TWI aktivieren, ACK einschalten
End Sub
ich hatte mir nun gedacht das ganze so abzuändern das ich die routine in der hauptschleife einfach dreimal hintereinander aufrufe und vorher die slaveadresse (Twar) ändere!?
würde das so funktionieren oder wie sollte der code ungefähr aussehen?
@besserwessi: einen anderen µC kann ich natürlich nehmen zum testen wäre natürlich der atmega8 am schönsten da ich diesen hier habe. wobei ich demnächst eh bei reichelt bestellen werde da könnte ich mir einen anderen mitbestellen. ist der atmega88 nicht sogar pinkompatibel mit dem atmega8
gruß und danke schon mal,
Bammel
Besserwessi
19.06.2010, 13:08
Der Mega88 ist pinkompatibel mit dem Mega8. Die Programme muß man aber neu übersetzen und ggf. leicht anpassen, weil sich einige Register-Adressen geändert haben.
Wenn das Programm kurz ist, geht auch der Mega48 als günstigere Version.
Ich habe gerade mal folgendes Datenblatt rausgesucht:
http://www.atmel.com/dyn/resources/prod_documents/doc8271.pdf
auf seite 245 abschnitt 21.9.6 (TWAMR) ist das beschreiben was du sagtest. dann müsste ich das also nur setzten. nur bekomme ich dann trotzdem heraus welche adresse das nun genau war? da müsste ich doch dann nur das ignorierte bit aus dem TWAR register auslesen!? geht das den überhaupt so?
ich würde auch in dem falle evtl den atmega328 verwenden. naja dazu mache ich mir dann mal gedanken.
Besserwessi
19.06.2010, 18:14
Die tatsächliche Slave Adresse ist in TWDR, als erste Byte der Nachricht.
ich dachte im TWDR wären nur die empfangen oder zu sendenden daten drinne?
Besserwessi
19.06.2010, 20:54
Die Adresse wird auch so ähnlich wie ein Datenbyte übertragen und landet dann auch in TWDR. TWAR ist nur für die Slave-Adresse auf die der µC ansperchen soll, verändern tut sich da nur was, wenn der µC reinschreibt.
Stimmt also muss ich wenn ich ein byte empfangen ahbe bzw. wnen eine adresse angekommen ist erstmal prüfen welche adresse das war das kann ich ja im ersten bit. und dnan darf ich die daten erst per TWDR auslesen.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.