Hallo,
ich bin grad beim Programmieren eines MSP430, habe eine while Schleife,
die unendlich läuft und in welcher ich immer Daten auf meine serielle
Schnittstelle ausgebe. Nun habe ich das Problem, dass wenn ich mit dem
Debugger händisch arbeite, die Daten perfekt an meinem PC ankommen, wenn
ich aber auf run klicke ( ==> soll heißen Programm läuft ) dann kommen
nurmehr fetzen von Daten an.
Nun schließe ich daraus, dass die Schnittstelle mit dem Schreiben der
Daten nicht mehr nachkommt und deshalb möchte ich irgendwie die
Geschwindigkeit der Schleife bremsen. Doch habe ich noch nichts wirklich
passendes finden können.
Nun wende ich mich an euch, in der Hoffnung, dass mir hier jemand helfen
kann.
Danke
Stef
Stef wrote:
> Nun schließe ich daraus, dass die Schnittstelle mit dem Schreiben der> Daten nicht mehr nachkommt
Auf einem µC hat die Serielle Schnittstelle ja normalerweise
eine Form von 'Ich arbeite noch'-Status. Wenn du also vor dem
Schreibvorgang diesen Status überprüfst, und solange wartest
bis die Schnitstelle 'frei' meldet, kann dieser Fall nicht
auftreten.
Genauer gesagt muss es ein Uart statusregister geben, das ein bit
enthaelt, das den TxReady zustand enthaelt. Das bit abfragen und warten.
Ein Interrupt ist zwar praktischer
Danke für die Tipps, ich versuche es im Moment aber mit einer zweiten
while Schleife, die so lange verzögern sollte, bis die Schnittstelle
wieder "frei" ist.
Ist zwar kein schönes programmieren, aber vielleicht klappt es.
Sonst werde ich euch noch um genauere Informationen bitten müssen.
So, der Versuch mit meiner Schleife ist gescheitert, nun werde ich den
Uart-Status abfragen müssen.
Ein paar Fragen dazu:
Wie genau sieht dieses Register aus:
Ist es: a) UART0 Interrupt Enable Register
b) UART0 Interrupt Flag Register
c) UART0 Module Enable Register
d) keines von den oben genannten
Ich weiß nicht, welches dieser Register den Status enthält.
Wie sieht dieses Statusbit aus??
Danke
Stef
@ Stef (Gast)
>So, der Versuch mit meiner Schleife ist gescheitert, nun werde ich den>Uart-Status abfragen müssen.
Wohl wahr.
>Ich weiß nicht, welches dieser Register den Status enthält.
Schon mal das Datenblatt gelesen?
MFg
Falk
When the transmitter is enabled (UTXEx = 1), data should not be written
to
UxTXBUF unless it is ready for new data indicated by UTXIFGx = 1.
Violation
can result in an erroneous transmission if data in UxTXBUF is modified
as it
is being moved into the TX shift register.
Ich hab das nun so probiert, jedoch ohne Erfolg
( ja, wahrscheinlich ist es lächerlich, wie ich es probiert habe, aber
ich
kenne mich noch nicht aus)
if(UTXE0=1)
{
UTXIFG0=0;
else
UTXIFG0=1;
}
Doch muss ersten bei If ein modifable value her, zweitens muss auch
UTXIFG0 ein modifable value sein, und bei else erwartet mein Compiler
ein Statement.
Kann mir nicht jemand ein Beispiel geben??
Danke
Stef
Stef wrote:
> Ich hab das nun so probiert, jedoch ohne Erfolg> ( ja, wahrscheinlich ist es lächerlich, wie ich es probiert habe, aber> ich> kenne mich noch nicht aus)>> if(UTXE0=1)> {> UTXIFG0=0;> else> UTXIFG0=1;> }>
Du sollst nicht UTXIFG setzen, sondern abfragen ob es 0 oder 1
ist! Nur dann wenn es 1 ist, darfst du einen neuen Wert zur
Schnittstelle geben.
Irgendwas in der Art
1
//
2
// Warte in einer Schleife solange, bis UTXIFG0 zu 1 wird
3
//
4
while(UTXIFG0!=1)
5
;
Was ich jetzt nicht weiss ist, ob UTXIFG0 ein komplettes Register
oder nur ein Bit in einem Register ist.
Hi Stef,
ohne jetzt Deinen Controller zu kennen und ungetestet!
1
while(1)
2
{
3
while(UTXIFGx==1);//warten bis Schnittstelle fertig
4
UxTXBUF=Daten;//Daten ist das Byte, das übertragen werden soll
5
}
Dass du vorher die UART richtig initialisieren musst ist Dir klar, oder?
Viele Grüße
P.S.: was die Zeile "if(UTXE0=1)" tut weißt Du aber schon auch, oder??
@ Stef (Gast)
>Doch muss ersten bei If ein modifable value her, zweitens muss auch>UTXIFG0 ein modifable value sein, und bei else erwartet mein Compiler>ein Statement.
Du solltest dir schnellstens eine gutes Buch über C besorgen.
>Kann mir nicht jemand ein Beispiel geben??
void putc(char data) {
while(UTXIFG0 != 1); // warte auf UART Transmitter
U0TXBUF = data; // Daten senden
}
MfG
Falk
Danke für die zahlreiche Hilfe, aber es funktioniert immer noch nicht:
Hier ist ein Teil von meinem Code:
while(i < 20 ) /* Schleife, um unsigned char auszugeben */
{
{
while(UTXIFG0 == 1); //warten bis Schnittstelle fertig
TXBUF0 = answer1[i]; //Daten ist das Byte, das
übertragen werden soll
}
i++;
}
Und diese while(i<20) Schleife befindet sich in meiner Endlosschleife.
Danke für weitere Anregungen
Stef
Stef wrote:
> Danke für die zahlreiche Hilfe, aber es funktioniert immer noch nicht:>> Hier ist ein Teil von meinem Code:>>> while(i < 20 ) /* Schleife, um unsigned char auszugeben */> {> {> while(UTXIFG0 == 1); //warten bis Schnittstelle fertig
Denkst du eigentlich auch selber mit?
Falk hat weiter oben einen Ausschnitt aus dem Datenblatt
gepostet. Darin steht eindeutig, dass UTXIFG0 erst dann zu 1
wird, wenn die Schnittstelle fertig ist. Das heist aber auch
im Umkehrschluss, dass solange gewartet werden muss, solange
UTXIFG0 nicht 1 ist!
while( UTXIFG0 != 1 )
;
UTXIFG0 kann man nicht einfach so abfragen. Das ist nur eine numerische
Konstante, die den Wert eines Bits in einem Register beschreibt.
Es muss geprüft werden, ob dieses Bit im zugehörigen Register IFG1
gesetzt ist.
Eine korrekte Abfrage davon sieht so aus:
while (!(IFG1 & UTXIFG0)); // USART0 TX buffer ready?
bzw. so für die zweite UART:
while (!(IFG2 & UTXIFG1)); // USART1 TX buffer ready?
Im Gegensatz zur hier im Forum und bei AVRs sehr verbreiteten
Bitshift-Schreibweise ist es bei der MSP430-Programmierung üblich, daß
eine ein Bit beschreibende Konstante wie UTXIFG0 nicht die Bitnummer,
sondern den Bitwert enthält.
Wäre es die Bitnummer, würde die Abfrage so aussehen:
while (!(IFG1 & (1 << UTXIFG0)));
Aber das ist bei den üblichen MSP430-Compilern und den damit gelieferten
Headerdateien definitiv nicht so realisiert.
Auszug aus msp430x14x.h von Rowley Crossworks:
#define UTXIFG0 (0x80)
Auszug aus io430x14x.h von IAR Embedded Workbench
enum {
...
UTXIFG0 = 0x0080,
...
};
@Falk Brunner (falk)
Sag mal hast du den ein gutes Buch parat.
Habe auch grad angefangen mit c.
VHDL war meine erste sprache. geht schon ganz gut
Uart, adc ausgabe an pins bekomm ich schon hin.
habe nen Mega128 auf der Platine von Uhlrich Radig.
das Datenblatt von dem Mega hab ich ausgedruckt.
Sollte man auf alle Fälle rein schauen,
in meinem sind auch c schnipsel drinne.
Wäre also nett wenn du ein gutes buch kennst!
hab keine lust Bücher zu kaufen die schrott sind.
Danke.
@ MockUp (Gast)
>@Falk Brunner (falk)>Sag mal hast du den ein gutes Buch parat.
Nein, aber schau dir mal die Buchempfehlungen an. Der Klassiker
Kernigham und Ritchi sowie die diversen Ableger sind ganz OK. Ich hab
hier "Programmieren in C" rumliegen, das reicht schon SEHR weit.
>Habe auch grad angefangen mit c.>VHDL war meine erste sprache. geht schon ganz gutVHDL ist aber was anderes.
Mfg
Falk
Stef wrote:
> So, es würde nun so weit funktionieren, nur noch , dass die einzelnen> Zeichen meines Charakters einzeln vervielfacht werden:>>
1
ggggeeeeeeewwwwwaaaaaaaeeeeeeeehhhllllltttttee
2
> eeerrrrrr Kaannnnnnnaaaaaaall::0
>>>> So sieht mein Code jetzt aus, vielleicht erkennt jemand von euch den> Feher:>>>
1
while(i<20)
2
>{
3
>do
4
>{
5
>TXBUF0=answer1[i];
6
>
7
>}
8
>while(!(IFG1&UTXIFG0));
9
>
10
>i++;
11
>}
12
>TXBUF0='0';
13
>
14
>
>>> Es müsste doch schon laufen, oder habe ich wieder einen Bock> abgeschossen?
Hast du.
Was ist eigentlich so schwer daran zu verstehen, dass man zuerst
abfragt, ob die Schnittstelle frei ist, und erst dann das Zeichen
auf den Weg bringt. Das sollte doch eigentlich klar wie
Klossbrühe sein.
Und wenn du dir endlich ein vernünftiges Einrückschema angewöhnen
würdest, dann würdest du auch sehen, dass du umgangssprachklich
ausgedrückt, folgendes programmiert hast:
Sende ein Zeichen, solange die Schnittstelle nicht frei ist.
So schreibst Du immer und immer wieder den auszugebenden Wert in das
TXBUF-Register ... und gibst diesen Wert dadurch auch immer wieder auf
der seriellen Schnittstelle aus. Daß das UTXIFG-Bit überhaupt mal
gesetzt wird, ist eher Zufall.
Du solltest ZUERST warten, bis das UTXIFG-Bit gesetzt wird und DANN erst
das Zeichen ausgeben:
1
while(!(IFG1&UTXIFG0));
2
TXBUF0=c;
Baue Dir am besten eine putc-Routine und rufe die von den entsprechenden
Stellen auf:
1
voidputc(charc)
2
{
3
while(!(IFG1&UTXIFG0));
4
TXBUF0=c;
5
}
Deine Ausgabeschleife ließe sich dann so formulieren:
Stef wrote:
> Danke für die Hilfe, habe meinen Fehler aber entdeckt:> Und zwar so müsste es nun endgültig richtig lauten:>>>
1
>while(i<20)
2
>{
3
>
4
>TXBUF0=answer1[i];
5
>while(!(IFG1&UTXIFG0));
6
>
7
>i++;
8
>}
9
>TXBUF0='0';
10
>
>>
Nein. Das ist immer noch falsch. Liest du eigentlich, was
wir hier so von uns geben?
>> Die Reihenfolge von TXBUF0= ...> und der while-Schleife ist ausschlaggebend!!
Das ist richtig.
Aber du musst zuerst abfragen, ob die Schnittstelle bereit
ist und erst dann das Zeichen senden!
Oder benutzt du zunächst mal das Auto deines Vaters und fragst
erst danach um Erlaubnis?
Abfragen ob die Schnittstelle frei ist:
Stef wrote:
> Ok, ist ein viel besserer Programmierstil.
Das hat nichts mit besserem Programmierstil zu tun.
Das ist eine Frage der Logik
> Aber im Moment bin ich froh, dass es nun läuft.
Bis es dann übermorgen, nach der 120-ten Programmergänzung
plötzlich nicht mehr läuft, weil du dich nicht an die einfachste
Sache der Welt halten kannst:
* Zuerst nachfragen, ob ein Gerät bereit ist einen
Befehl auszuführen und gegebenenfalls darauf warten,
dass es bereit wird.
* Dann dem Gerät den Befehl geben
Sorry, tut mir leid, aber meine Antwort hat sich auf Andreas Schwarz
bezogen. Die Sachen mit den Programmierstil und so
Wenn ich aber so schreibe:
1
while(!(IFG1&UTXIFG0));
2
TXBUF0=answer1[i];
3
i++;
hänge ich bei meiner while Schleife endlos drinnen.
Deshalb habe ich veruschweise die while-Schleife hinter den TXBUF0
gestellt und es hat danach funktioniert!!
Ich sehe es von der Logik schon ein, aber warum habe ich dann eine
endlos Schleife, und andersherum nicht???
Nur aus den empirischen Resultaten habe ich die Struktur umgestellt.
> hänge ich bei meiner while Schleife endlos drinnen.> Deshalb habe ich veruschweise die while-Schleife hinter den TXBUF0> gestellt und es hat danach funktioniert!!
Was soll die völlig nutzlose Einrückung des auf die while-Schleife
folgenden Codes? Lass sowas sein, das fördert nicht die Lesbarkeit des
Codes.
Wenn es sich tatsächlich so verhält, wie Du beschreibst, dann lässt das
darauf schließen, daß Du möglicherweise die UART nicht korrekt
initialisierst.
Wie genau machst Du das?
Genau, jetzt endlich.
Das habe ich für eine andere Applikation vorher gebraucht, die jetzt
nicht mehr benötig wird.
Jetzt kann ich es endlich ausbessern.
Nochmals danke an alle für die tatkräftige Hilfe
Stef