PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Einem Atmega8 drei I²C-Slave Adressen zuweisen?



Bammel
18.06.2010, 16:57
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

Kampi
18.06.2010, 17:18
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?

Bammel
18.06.2010, 19:07
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.

Kampi
18.06.2010, 20:01
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.

Bammel
18.06.2010, 20:13
ne das geht nicht. ich kann oder will den master nicht verändern.

uwegw
18.06.2010, 22:53
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.

yaro
19.06.2010, 00:04
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

Bammel
19.06.2010, 10:46
@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.

Bammel
19.06.2010, 15:31
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.

Bammel
19.06.2010, 20:32
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.

Bammel
19.06.2010, 23:35
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.