Forum: Mikrocontroller und Digitale Elektronik TWI atmega8 Denkfehler TWINT


von Black-Devel (Gast)


Lesenswert?

Hi @ all,

ich hab da ein paar bauteile die mal über TWI ansteuern wollte , also 
hab ich mich rangesetzt und gelesen.
irgentwie bin ich auf ein problem gestoßen das ich nicht verstehe:

Bsp.
Master transmitter Mode
ich will die start-condition senden.   also :
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

jetzt muss gewartet werden bis das TWINT flag von der hardware gestzt 
wird ( es wird auf 0 gesetzt ( wir erinnern uns das ich es eben mit 
meinem Code auf 1 gesetzt habe ))

jetzt kommen wir zum problem, überall wo ich nachgelesen haben kommt 
jetzt die warteschleife um zu sehen ob das flag gesetzt wurde :
        while(!(TWCR & (1<<TWINT)));

nach den beschreibungen soll die Schleife warten bis dercontoller fertig 
ist und TWINT wieder auf null gesetzt hat, ABER die schleife läuft doch 
die ganze zeit rund wenn TWINT 0 is.

das heist : ich setzte das ding 1
            die harware macht es wieder zur 0
            und dann läuft es in einer endlosschleife

aber so steht das überall
http://www.mikrocontroller.net/articles/AVR_TWI

wo ist mein FEHLER ?

thx im vorraus

von spess53 (Gast)


Lesenswert?

Hi

>jetzt muss gewartet werden bis das TWINT flag von der hardware gestzt
>wird ( es wird auf 0 gesetzt ( wir erinnern uns das ich es eben mit
>meinem Code auf 1 gesetzt habe ))

Du hast es gelöscht:

The TWINT Flag must be cleared by software by writing a logic one to it.

MfG Spess

von Black-Devel (Gast)


Lesenswert?

ja das is klar

ich habe es ge"cleared" auf eins gesetzt

die hardware arbeitet und setzt das flag wieder , dann ist es 0

und darauf soll die schleife warten.
aber die läuft endlos wenn es null ist

von spess53 (Gast)


Lesenswert?

Hi

>ich habe es ge"cleared" auf eins gesetzt

Nein. Durch Beschreiben mit einer 1 wird es auf Null gesetzt. Ist so 
üblich bei vielen AVR-Bits.

MfG Spess

von Black-Devel (Gast)


Lesenswert?

ok das heißt also wenn ich per software versuche das bit auf 0 zu setzen
setzt die hardware das bit auf 1 und andersrum ?

von spess53 (Gast)


Lesenswert?

Hi

Nein. Das Beschreiben mit einer Null hat keine Wirkung. Ich denke, es 
ist an der Zeit, das du dich mal mit dem Datenblatt beschäftigst.

MfG

von Black-Devel (Gast)


Lesenswert?

ok denke ich habs halbwegs verstanden.

aber wiso läuft mein programm dann immer endlos in dieser schleife fest?

egal was is ob das senden von start klapt oder nicht irgend wann muss 
die schleife sich doch verändern oder?

von spess53 (Gast)


Lesenswert?

Hi

>aber wiso läuft mein programm dann immer endlos in dieser schleife fest?

Bin ich überfragt. Ich habe das in Assembler programmiert. Wie sieht 
deine Hardware aus?

MfG Spess

von Steffen H. (avrsteffen)


Lesenswert?

Black-Devel schrieb:
> Master transmitter Mode
> ich will die start-condition senden.   also :
>   TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

Wenn du wie hier eine START Bedingung gesendet hast, musst du jetzt auf 
das TWINT = '1' ? pollen. Denn die Hardware setzt das TWINT auf '1' wenn 
es eine Aktion ausgeführt hat.

Das heißt für dich:
Wenn TWINT Bit == '1' dann kannst du nächste Aktion ausführen!

Also:
1
while(!(TWCR & (1<<TWINT)));

Steffen

von Black-Devel (Gast)


Lesenswert?

da mein programm aber immer in der schleife stecken bleibt muss ich doch 
davon ausgehen, dass das senden von start nich abgeschlossen wurde und 
ich nicht die nächste aktion ausführen kann, oder?

von spess53 (Gast)


Lesenswert?

Hi

>Wenn du wie hier eine START Bedingung gesendet hast, musst du jetzt auf
>das TWINT = '1' ? pollen. Denn die Hardware setzt das TWINT auf '1' wenn
>es eine Aktion ausgeführt hat.

Macht er doch:

>while(!(TWCR & (1<<TWINT)));

MfG Spess

von Steffen H. (avrsteffen)


Lesenswert?

Es war schon etwas verwirrend nach obiger Beschreibung. Hat Black-Devel 
es jetzt so gemacht, oder hat er es nur so gelesen..
Wollte nur nochmal Klarheit schaffen Spess.

Dann hat er den TWI vieleicht nicht richtig initialisiert oder keine 
Pullup-Widerstände an SCL, SDA gegen Vcc.

Steffen

von Black-Devel (Gast)


Lesenswert?

muss ich am mega8 externe pull_up's oder kann ich auch die internen 
nehmen?

von spess53 (Gast)


Lesenswert?

Hi

>Dann hat er den TWI vieleicht nicht richtig initialisiert oder keine
>Pullup-Widerstände an SCL, SDA gegen Vcc.

Oder er versucht es zu simulieren:

Two-wire Serial Interface (TWI)
TWI is not supported.

MfG Spess

von Black-Devel (Gast)


Lesenswert?

also ich habs aufm mega8(hardware) getestet und ich bin immer in dr 
schleife hängen geblieben.

habe interne pull-up's verwendet

von spess53 (Gast)


Lesenswert?

Hi

>muss ich am mega8 externe pull_up's oder kann ich auch die internen
>nehmen?

Für Versuche mit kurzen Leitungen ja. Für den praktischen Einsatz um 
eine Zehnerpotenz zu gross.

MfG Spess

von Black-Devel (Gast)


Lesenswert?

ja ich wollte es ja auch nur auf einem kleine board testen.
ich werds alles nochmal durchgehen und austesten .

wenn ich noch probleme habe melde ich mich nochmal


danke erstaml

von Steffen H. (avrsteffen)


Lesenswert?

Laut Datasheet sollte es auch mit internen Pullups gehen.

>>Note that the internal pull-ups in the AVR pads can be enabled by setting
>>the PORT bits corresponding to the SCL and SDA pins, as explained in the
>>I/O Port section. The internal pull-ups can in some systems eliminate the
>>need for external ones.

Allerdings hat es so bei mir noch nie funktioniert. Habe die Pullups 
immer als Externe dran.

Steffen

von spess53 (Gast)


Lesenswert?


von Steffen H. (avrsteffen)


Angehängte Dateien:

Lesenswert?

spess53 schrieb:
> Dann sieh dir mal die I2C-Spezifikation an:

Meinst du das hier?
Deswegen hat es bei mir nie funktioniert mit den internen Pullups.

Ich nehm meist 4,7k bei 5V als Pullup.

Steffen

von spess53 (Gast)


Lesenswert?

Hi

>Meinst du das hier?

Ja. Auch.

MfG Spess

von Michael D. (etzen_michi)


Lesenswert?

Ich habe letztens auch das TWI des ATmega8 in Betrieb genommen und habe 
das gleiche Problem gehabt.

Daher das ich es nicht mit Pollen des Register lösen konnte habe ich ein 
Flag-Byte mit verschiedenen Bits für verschiedene "Ereignisse".

Somit setze ich beim starten des TWI "Flag&= ~(1<<TWI);"
und sobald ich einen Interrupt bekomme (TWCR|= 1<<TWIE) setze ich 
"Flag|= 1<<TWI;".

Somit brauche ich nur while((Flag&= 1<<TWI)==0) {}; zu warten.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.