ja danke ich werd mal ausprobieren, ob die sache bei meinem board ebenfalls funktioniert
gruß Green Hell
Druckbare Version
ja danke ich werd mal ausprobieren, ob die sache bei meinem board ebenfalls funktioniert
gruß Green Hell
Hallo zusammen,
ich bin Neuling auf dem Gebiet der uC. Seit neustem beschäftige ich mich mit dem TWI. Der Code von bhm hat mir schon seehr viel geholfen, allerdings hab ich ihn teilweise noch nicht ganz durchschaut. Wer hat Lust, mir folgende Zeilen (den Knackpunkt der Funktion) zu erklären:
Auszug aus Master-Receiver von bhm's TWI-Lib
Meine Fragen dazu:Code:while (1) { // endlos, verlassen via break in if TW_Status
if (len<lenmax) {
TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT); //receive, ACK,
} else {
TWCR = _BV(TWEN) | _BV(TWINT); //receive, NACK,
}
waitTWINT();
if (TW_STATUS != TW_MR_DATA_ACK) break; // LOOP VERLASSEN
*Data++ = TWDR; len++; // Daten verarbeitet
}
- was hat es mit der Längengeschichte (Variablen len und lenmax) auf sich
- gesamte funktionsweise der while-Schleife
Toll wäre eine kurzer, verständlicher Abriss über die Schritte, die in der while-Schleife passieren. Das würde mir sehr weiterhelfen und zum Gesamtverstädnis beitragen.
Vielen Dank im voraus für Euere Hilfe!
Schau,
"len" sind die empfangenen Bytes, am Anfang "1"
"lenmax" die gegebene Anzahl, wieviele es werden dürfen
Data* zeigt auf den datenbuffer
while(1) heißt, von sich aus hört die Schleife nicht auf.
if (len < lenmax) // noch nicht genug bytes
TWCR = _BV(TWEA) | _BV(TWEN) | _BV(TWINT);
wenn ein Byte kommt, ACK zurückschicken
sonst
TWCR = _BV(TWEN) | _BV(TWINT);
auch empfangen, aber KEIN Ack zurück
Dann warten, was passiert
Beim empfang MIT ACK
*Data++ = TWDR // Daten speichern (pointer+1)
len++ // mitzählen
Beim empfang OHNE ACK (also letztes Byte) --> break, schleife exit.
Nach der Schleife wird auch noch das letzte (nicht "geackte" Byte gespeichert
Und STOP abgesetzt. aus.
Der Witz dabei ist, daß der Master receiver das letzte geholte byte NICHT "Acked", damit der Slave weiß, das war das letzte.
(Der steht sonst nämlich da wie die Kuh vor dem neuen Tor)
logo ?
EDIT: Ich weiß, ich hab auch schon elegantere Schleifen gesehen, aber was soll's
Danke PicNick für die super schnelle und ideotensichere Antwort. C-Code beherrsche ich schon, mir ging es eher um das Verständnis der einzelnen Registerwerte, d.h. was macht der uC wenn der und der Wert drin steht .... - das ist noch meine Schwachstelle und das muss ich noch lernen/üben.
Aber deine Erklärung ist super. VIELEN DANK !!!
Ah so-
Die TWCR Register sind für sich allein nicht eindeutig, was er macht, hängt davon ab, welchen zustand die TWI grad hat. also
Als Master sagt man am Anfang START INT/ EN / STA, das ist neutral
ist das ok,
Schickt man mit adresse->TWDR und INT/ EN die Adresse weg
schreibt man die Slaveaddresse + W (also die "gerade" adresse)
ist man dann Master transmitter
da geht es immer Daten --> TWDR und INT/ EN
schreibt man die Slaveaddresse + R (also die adresse + 1)
ist man dann Master receiver
da geht es immer umgekehrt, INT/ EN , TWDR --> Daten
sagt man auch EA/ dazu, schickt er ein ACK zurück, sonst eben nicht
(dazwischen natürlich immer warten, ob ein INT zurückkommt)
Hallo PickNick,Zitat:
Zitat von PicNick
gute Erklärung, hätte ich nicht besser gekonnt ;-)
Das mit der eleganten Programmierung liegt wahrschenlich daran, dass ich eher aus der Pascal-Welt komme und natürlich auch bei C Pascal denke.
Insofern ist
schon ein Zugeständniss!Code:while (1) {
..
if (irgendwas) { break; }
}
Eigentlich müsste es sauber strukturiert so aussehen ;-)
aber das scheint selbst mir etwas -hm- geschwätzig. Aber ob *(buf++) oder *buf++ oder *(&(*buf)++) oder doch buf[i++] besser oder gar eleganter ist werde ich wohl nie lernen.Code:int ende;
ende =0;
while (ende==0) {
..
if (irgendwas) { ende =1; }
}
Meine Anforderung an meine C-Programme ist, dass sie a) einigermaßen funktionieren (ist oft genug nicht der Fall) und b) ich sie nach 3 Monaten noch oder wieder verstehe (scheint hier gelungen zu sein :-) ).
ciao bernd
Deine Anforderungen klingen vernünftig, ich möcht' fast sagen, das ist genau das, worauf's ankommt.
Ich bin überzeugt, wenn ein Programmierer in die Hölle kommen sollte, muß er dort alle seine Programme nach-dokumentieren. Und das tut man sich dann leichter :mrgreen:
uff! gut, dass ich kein Programmierer bin (jedenfalls keiner der das für Geld macht ;-)) und auch nicht in die Hölle komme :twisted: (das ist jedenfalls der Plan)Zitat:
Zitat von PicNick
ciao .. bernd
Wie sieht denn nun zum Beispiel eine typische main.c mit den Funktionen drin aus für Master und Slave?!
Genauer gesagt möchte ich mittels TWI die ADC eingänge eines Anderen Mega32 an den Master übermitteln. Der Master soll also den Slave immer wieder abfragen. Wie stelle ich das an?
Kann mir bitte jemand helfen?
Grüße Sebastian
--