PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : TWI aber wie?



Gerko
13.07.2007, 14:36
Hallo Leute!

Ich habe mir wiedermal ein kleineres Projekt vorgenommen. Ich will mein Wissen in der Assemblerprogrammierung wiedereinmal ein bischen auffrischen. Genauer gesagt habe ich vor mehrere Prozessoren miteinander reden zu lassen, damit ich nicht alles mit einem Steuern muss.

Im Datenblatt des ATmega8 habe ich dazu TWI (Two-wire Sirial Interface) gefunden. Nach dem was da so drinnen steht is das genau das nach dem ich suche.

Nur bei der Umsetztung happerts noch. Ich habe auch schon im Forum etwas geforscht, aber nichts passendes in Assembler gefunden.

Weiß irgendjemand wie soetwas funktioniert?
Wie muss ich z.B. die Register einstellen damit der Interrupt ausgelöst wird wenn Daten ankommen am Slave?

Danke schon mal im Voraus

Gerko

Chattychan
13.07.2007, 15:45
Hallo Gerko,

hab ich für RN-Control benutzt und klappt super:

http://homepage.hispeed.ch/peterfleury/avr-software.html#libs

Viele Grüsse
Thomas

bax
13.07.2007, 16:41
Hi, hier hast Du schon mal einen Anfang:

https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=18356

Wenn Du mehrere (also >2) AVR's kommunizieren lassen willst empfehle ich Dir, einen zum Master zu machen und diesen dann das Management über den IIC-Bus zu überlassen. Ich hab mich ewig damit aufgehalten, eine Multimaster-Routine zu schreiben, dabei gab es aber immer wieder Aufhänger auf dem Bus. Meine jetzige Lösung ist inzwischen auch hot-plug-fähig. Hab zur Zeit aber leider nicht die Zeit, die mal noch so aufzubereiten, das es Sinn macht die hier reinzustellen. :-s

greetz Rajko

uwegw
13.07.2007, 17:24
Ich hab nen Slave in C geschreiben, dürfte sich recht einfach auf Assembler übertragen lassen:
https://www.roboternetz.de/wissen/index.php/TWI_Slave_mit_avr-gcc

Eigentlich ist nen Slave ne recht simpele Sache: man schmeißt das TWI an (Adresse in TWAR, und in TWCR die Bits TWEA,TWEN und TWIE setzen.) und wartet auf den Interrupt. In der ISR liest man TWSR aus, und reagiert entsprechend der Tabelle im Datenblatt.

Gerko
13.07.2007, 18:50
Danke für so schnelle und viele Antworten, ich glaube der Zeitbetrag von bax wird mir am meisten helfen, muss mir das noch genau ansehen.
Wenn ich Fragen habe melde ich mich wieder :)

Hanni
14.07.2007, 07:14
Ansonsten wirf einfach mal einen Blick in die diversen Appnotes von Ateml, da gibt es auch etwas zum Thema TWI.

Grüße,
Hanni

PicNick
14.07.2007, 09:24
ich hab' ,ich auch mal mit der Materie ausgetobt, vielleicht willst du mal gucken
https://www.roboternetz.de/wissen/index.php/TWI_Praxis_Multimaster

Gerko
14.07.2007, 14:39
Ich hab mir das jetzt alles mal ziemlich genau angesehn, und versucht damit ein Programm zu schreiben.
Ich wusste zwar das es nicht leicht wird, aber gleich so kompliziert !!!

So initialisiere ich den TWI beim Slave:

; TWI einstellen
; TWI TWAR (nur SLAVE) Adress-Register
ldi temp, TWI_Slave_Adresse<<TWA0|TWI_General_Call_Enable<<TWGCE
out TWAR,temp
; TWI TWCR Control-REGISTER
ldi temp, 1<<TWINT|1<<TWEA|0<<TWSTA|0<<TWSTO|0<<TWWC|1<<TWEN|1<<TWIE
out TWCR,temp


und hier wollte ich versuchen einen programmtext zu schreiben um daten zu empfangen:

TWSI:
in temp, SREG
push temp

in temp, TWSR
andi temp, 0b11111000

????
????




TWI_Ende:
;das TWINT-Flag löschen ((logisch 1)
ldi temp, 1<<TWINT|1<<TWEA|1<<TWEN|1<<TWIE
out TWCR,temp

pop temp
out SREG, temp
reti

Dort wo die ???? stehn endet mein verständnis :(

Ich habe mir nochmal das Datenblatt vom ATmega8 hergenommen. Auf Seite 186 ist eine schöne Tabelle was bei den ???? so alles drinn stehn sollte. Ich kann zwar English, aber da hier dann andauernd so begriffe wie SLA, ACK, GCA, ... fallen setz ich da aus.

1. Stimmt es das das Register TWSR für die Überwachung des Zustandes auf dem Bus ist, also hier steht drinnen was jetzt als nächstes geschieht?
Wenn ja, dann hab ich das schon mal nicht komplett falsch verstanden.

2. Brauch ich wirklich alle diese Befehle, und wofür stehn die jetzt im einzelnen?

Die Datenbyts empfange ich wenn TWSR auf 0x80 steht oder? ich will allerdings immer 2 Bytes empfangen, wie mach ich das?

Ich weiß das sind jetzt ziemlich viele Fragen aufeinmal, aber ich hab mir fest vorgenommen das genauer zu verstehn.

EDIT: Ich glaub ich hab jetzt aus dem Datenblatt herausgelesen das 0x80 und 0x88 jeweils ankündigen ein Datenbyte übertragen zu haben, also würde das dann so aus sehn:


TWSI:
in temp, SREG
push temp

in temp, TWSR
andi temp, 0b11111000

cpi temp, 0x80
breq Datenbyte_empfangen

cpi temp, 0x88
breq Datenbyte_empfangen

rjmp TWI_Ende

Datenbyte_empfangen:
inc TWI_Anzahl_empfangen
cpi TWI_Anzahl_emfpangen, 0b00000001
rjmp Datenbyte1_emfpangen
cpi TWI_Anzahl_emfpangen, 0b00000010
rjmp Datenbyte2_empfangen

Datenbyte1_empfangen:
mov TWI_empfangen1, temp
rjmp TWI_Ende

Datenbyte2_emfpangen:
clr TWI_Anzahl_empfangen
mov TWI_emfpangen2, temp

;Daten verarbeiten...

rjmp TWI_Ende


TWI_Ende:
;das TWINT-Flag löschen ((logisch 1)
ldi temp, 1<<TWINT|1<<TWEA|1<<TWEN|1<<TWIE
out TWCR,temp

pop temp
out SREG, temp
reti

Wenn ich also die Anderen Status Codes weglassen kann wäre ich doch mit dem Slave schon fertig beim Programmieren oder?