PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : TWI/I2C für Mega8 in Assembler



nOm3X
08.05.2007, 15:27
Hallo,

ich will ein PCF8574 über TWI/O2C mit dem Mega8 ansteuern.
Das ganze soll aber Hardwaremäßig erfolgen (Kein Software I2C).
Ich möchte auch in Assembler bleiben!

Ich finde echt nichts Vernünftiges.

Mit einer gescheiten Anleitung wie ich das anstellen muss bin ich zufrieden, ich verlange noch nicht mal fertigen Quellcode (währe auch cool).

Danke

PS: mit dem Datenblatt bin ich noch nicht weitergekommen.

PicNick
08.05.2007, 15:53
Guck mal
https://www.roboternetz.de/wissen/index.php/TWI_Praxis_Multimaster
(+Download-Link)
Nicht erschrecken vor Bascom:
Die eigentlichen TWI-Funktionen sind in der Lib, also Assembler.

Vielleicht kannst du was abspicken

Hanni
08.05.2007, 20:02
Dazu gibt es Applikation Notes von Atmel.

www.atmel.com

Ich hab aber keine Ahnung, ob die das Ganze in Assembler oder C realisieren.

Grüße,
Hanni

nOm3X
09.05.2007, 12:23
Guck mal
https://www.roboternetz.de/wissen/index.php/TWI_Praxis_Multimaster
(+Download-Link)
Nicht erschrecken vor Bascom:
Die eigentlichen TWI-Funktionen sind in der Lib, also Assembler.

Vielleicht kannst du was abspicken
Den hab ich auch schon entdeckt.
Aber danke, da werd ich mich wohl dran versuchen müssen.


Dazu gibt es Applikation Notes von Atmel.

www.atmel.com

Ich hab aber keine Ahnung, ob die das Ganze in Assembler oder C realisieren.

Das iss leider alles in C. Aber danke.

Gruß nOmeX

Gock
09.05.2007, 12:51
Nicht alles in C!
In den Datenblätter der Conroller mit TWI interface (zb Mega32) findest DU C und Assembler Code für die Implementierung. Dummerweise sind alle Codes, die ich im Netz gefunden habe nicht interrupt basiert. Macht aber nicht unbedingt was aus.
Die AppNoter von Atmel zum Thema ist in C.
Gruß

nOm3X
11.05.2007, 09:59
Hi


Dummerweise sind alle Codes, die ich im Netz gefunden habe nicht interrupt basiert.
Ich brauch auch eigentlich keine Interruptsteuerung, hauptsache mein pcf8574 reagiert.


In den Datenblätter der Conroller mit TWI interface (zb Mega32) findest DU C und Assembler Code für die Implementierung.
Stimmt, und da hab ich mich auch durchgequählt.


.include "m8def.inc"

.def temp1 = r16
.def temp2 = r17
.def temp3 = r18

ldi temp1, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse
out SPL, temp1
ldi temp1, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse
out SPH, temp1

ldi temp1, 0xFF ; Port B & C als Ausgang schalten
out DDRB, temp1
out DDRC, temp1

;================================================= ==========================

ldi temp1, 12
out TWBR, temp1
ldi temp1, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
out TWCR, temp1 ; Sende Start condition
wait1:
in temp1,TWCR ; Warten bis das TWINT Flag gesetzt ist.
sbrs temp1,TWINT ; Das bedeutet das die START Condition gesetzt ist
rjmp wait1

in temp1,TWSR ; TWI Statusregister abfragen
andi temp1, 0xF8 ; Prescalerbits Maskieren
; sbrs temp1, TWSTA ; Startcondition prüfen
; brne ERROR

ldi temp1, 0x40 ; Wert ins DatenRegister laden (Adresse?)
out TWDR, temp1
ldi temp1, (1<<TWINT) | (1<<TWEN) ; TWINT löschen um Übertragung zu starten
out TWCR, temp1

wait2:
in temp1,TWCR ; Warten bis das TWINT Flag gesetzt ist.
sbrs temp1,TWINT
rjmp wait2

in temp1,TWSR ; TWI Statusregister prüfen.
andi temp1, 0xF8 ; Prescaler maskieren
sbrs temp1, TWEA ; Wenn kein Acknowledge kommt in ERROR springen.
brne ERROR

ldi temp1, 0x40 ; Daten in TWDR laden.
out TWDR, temp1
ldi temp1, (1<<TWINT) | (1<<TWEN) ; TWINT löschen um Übertragung zu starten
out TWCR, temp1

wait3:
in temp1,TWCR ; Auf TWINT Flag warten
sbrs temp1,TWINT
rjmp wait3

in temp1,TWSR ; TWSR Status prüfen
andi temp1, 0xF8 ; Prescaler maskieren
sbrs temp1, TWEA ; Wenn kein Acknowledge kommt in ERROR springen
brne ERROR

ldi temp1, (1<<TWINT)|(1<<TWEN)|(1<<TWSTO) ; Stop condition
out TWCR, temp1

main:
ldi temp1, 0x04 ; Indikator Ausgang für main-Schleifen
out PORTB, temp1
rjmp main

ERROR:
ldi temp1, 0x01 ; Indikator Ausgang für ERROE-Schleife
out PORTB, temp1
rjmp ERROR

Hab auch ein plausiebles Oszzi-Bild, leider bekomme ich aber keinen Acknowledge zurück.

Kann mir einer nochmal BITTE BITTE helfen?

Danke

Gruß nOm3X

Edit: Hab Kommentare reingemacht. (so in ertwa übersetzt was im Datenblatt ist.)

Gock
11.05.2007, 10:27
Hi!
Ein paar Komentare im Code könnten schon helfen, hab nämlich keine Lust, Zeile für Zeile mit dem Datenblatt zu vergleichen.
Wenn ich das aber richtig sehe, dann ist 0x40 die Slaveadresse (???). Wenn ja, dann wäre das natürlich falsch.
Gruß

nOm3X
11.05.2007, 11:52
Warum ist das Falsch? Ich muss dem PCF8574(P) die HEX 40 Schicken oder?

Gock
11.05.2007, 12:04
Die Slaveadresse muss die Form haben:
0.1.0.0.(A2).(A1).(A0).R/W
0x40 ist aber: 1.0.0.0.0.0.0.0 !
Kann also nicht sein!
Oder?

bax
11.05.2007, 15:51
Hi,

der prinzipielle Fehler ist, das Du am TWEA Bit nicht ablesen kannst, ob der Slave ein Ack gesendet hat. Das bekommst Du nur heraus, wenn Du das Statusregister TWSR auswertest. Also jedes mal, wenn die Warteschleife mit dem TWINT gelaufen ist prüfen, ob der Istzustand der gewollte ist, nach dem START-Request z.B. macht es nur Sinn weiterzumachen, wenn eine 0x08 im TWSR steht. Sonst springst Du in Deine Error-Schleife und läßt Dir dort das TWSR an einem Port anzeigen, dann kannst Du einfacher debuggen.

Das TWEA Bit steuert nur, ob das eigene TWI ein ACK sendet oder nicht, es spielt im Master Transmitter Mode keine Rolle.

greetz Rajko

Gock
11.05.2007, 18:59
Da kann ich Bax nur zustimmen.
Warum hast Du nicht einfach alles abgeschrieben, steht doch alles da?
Und wenn DU dann noch die richtige Adresse benutzt, sollte es eigentlich funktionieren...
Gruß