Hallo, ich möchte ein Gerät über die UART mit der Funktion printf
Steuern.
Hierzu werden 12 Hex Zeichen übermittelt.
Beispiel 80 01 05 07 00 DD
Code:
printf(“\x80\x01\x05\x07\x00\xDD“);
Nur leider werden die beiden 00 nicht übertragen, bzw. wird die
Übertragung sogar danach beendet.
Wie kann ich die den Befehl Senden? Welche möglichkeiten gibt es sonst
noch?
Danke für eure Hilfe….
Geht nicht. printf versendet Strings und die \x00 ist das Zeichen für
Stringende in C.
Versende die 6 Zeichen einzeln mit 6 putc()-Aufrufen hintereinander.
Rukula schrieb:
> Nur leider werden die beiden 00 nicht übertragen, bzw. wird die> Übertragung sogar danach beendet.
Wie schon geschrieben sind die Strings mit 00 abgeschlossen:
string "hallo welt" sieht in der char-Array so aus:
'h','a','l','o','','w','e','l','t',0
> Wie kann ich die den Befehl Senden? Welche möglichkeiten gibt es sonst> noch?
Schreibe die Werte doch direkt in das UDR Register...
Diesen Code habe ich in der Schule schreiben müssen:
voidtxBuf_Write(unsignedcharparameter){// TX-Buffer mit Werte füllen
7
if(index_txBuf_W==Buf_max){// Damit Ringbuffer nicht überläuft
8
index_txBuf_W=0;
9
}
10
else{
11
index_txBuf_W++;
12
}
13
txBuf[index_txBuf_W]=parameter;
14
}
15
:
Das könnte bei geeigneter Wahl Puffergröße (256 Bytes statt 255
Integers) und der Indices (unsigned char hat den Wertebereich 0...255)
wesentlich kompakter und effizienter geschrieben werden:
Lothar Miller schrieb:
> Damit fallen die ganzen Abfragen nach Buf_max aus dem Code heraus,> weil der Index (als char) niemals größer als 255 werden kann.
wenn der Index 255 erreicht hat und dann wieder inkrementiert wird, wird
der Index dann automatisch 0 oder bleibt der 255??
denn Ansonsten bringts nichts, denn die Abfragen auf Buf_max bleiben
Danke für den Verbesserungsvorschlag
Der Index würde 256 werden.
Da aber nur die untersten 8 Bit "verwendet" werden:
1 0000 0000 => 0000 0000 => 0x00.
Also 255 + 1 ist bei nem Byte immer 0.
> Da I
Das wars, was ich sagen wollte, Du da ;-)
Dieses Prinzip funktioniert an allen Zweierpotenzgrenzen, nur muß man
sich dann selber um die Maskierung kümmern. Hier z.B. mit 16 Elementen:
voidtxBuf_Write(unsignedcharparameter){// TX-Buffer mit Werte füllen
7
txBuf[index_txBuf_W&0xf]=parameter;// nur 16 Speicherplätze, deshalb Maske über die unteren 4 Bits
8
index_txBuf_W++;// der Index darf ruhig weiterlaufen, es werden ja nur die unteren 4 Bits verwendet
9
}
10
// Abfrage, ob ein Element im Puffer
11
if(index_txBuf_W!=index_txBuf_R){
12
wert=txBuf[index_txBuf_R&0xf];
13
index_txBuf_R++;
14
}
15
:
Der Index sollte erst nach dem Eintragen oder Auslesen eines Wertes in
den Fifo erhöht werden. Denn sonst könnte ja zwischen Indexincrement und
Beschreiben des Puffers eine lesende ISR kommen, den bereits erhöhten
Schreibindex sehen, und auf das noch nicht geschriebene Element
zugreifen. Diesen Fehler zu finden dauert Wochen... :-/
Bei solchen Fifo-Geschichten sollte jede Codezeile darauf abgeklopft
werden, was wäre, wenn ein Interrupt käme.
Lothar Miller schrieb:
>> Da I> Das wars, was ich sagen wollte, Du da ;-)>> Dieses Prinzip funktioniert an allen Zweierpotenzgrenzen, nur muß man> sich dann selber um die Maskierung kümmern. Hier z.B. mit 16 Elementen:
sprich für 256 Elemente siehts so aus:
voidtxBuf_Write(unsignedcharparameter){// TX-Buffer mit Werte füllen
7
txBuf[index_txBuf_W&0xFF]=parameter;// nur 16 Speicherplätze, deshalb Maske über die unteren 4 Bits
8
index_txBuf_W++;// der Index darf ruhig weiterlaufen, es werden ja nur die unteren 4 Bits verwendet
9
}
10
// Abfrage, ob ein Element im Puffer
11
if(index_txBuf_W!=index_txBuf_R){
12
wert=txBuf[index_txBuf_R&0xf];
13
index_txBuf_R++;
14
}
Aber kriegt man dann nicht einmal Speicherprobleme auf einem 8-Bit MCU??
da ja index trotzdem noch inkrementiert wird?
> Der Index sollte erst nach dem Eintragen oder Auslesen eines Wertes in> den Fifo erhöht werden. Denn sonst könnte ja zwischen Indexincrement und> Beschreiben des Puffers eine lesende ISR kommen, den bereits erhöhten> Schreibindex sehen, und auf das noch nicht geschriebene Element> zugreifen. Diesen Fehler zu finden dauert Wochen... :-/
hhmmmm...
bei mir läuft es momentan nach folgendem Muster:
index_txBuf_W => txBuf[0] <= index_txBuf_R
neuer Wert kommt...
index_txBuf_W++
index_txBuf_W => txBuf[1]
Code erkennt dass W und R nicht mehr gleich sind...
index_txBuf_R++
index_txBuf_W => txBuf[1] <= index_txBuf_R
und so weiter...
wenn wir schon dabei sind, ich hab euch gleich den Quellcode im Anhang,
damit ihr mal darüber schauen könnt und eure Meinung und
Verbesserungsvorschläge sagen könnt.
p.s. sorry, wegen dem schlechten Styl, aber in der Schule lerne ich
leider nicht "richtiges und sauberes" Programmieren
> Das könnte bei geeigneter Wahl Puffergröße (256 Bytes statt 255> Integers) und der Indices (unsigned char hat den Wertebereich 0...255)> wesentlich kompakter und effizienter geschrieben werden:
Normalerweise Rischtisch, aber bedenke, mit einem UART könnte man auch 9
bits senden/empfangen (wollen)... ein "unsigned char" Puffer reicht dann
nicht mehr
Es ist schon ein Kreutz mit der 0 am Ende von C-Strings.
Für solche Fälle habe ich für mich mal eine Pascal-like-String-Library
geschrieben.
Der Unterschied zu C-Strings: Die Stringlänge wird nicht durch eine
Abschliessende 0 gekennzeichnet, sondern durch ein Längenbyte am Anfang
des Strings.
Dadurch ist von einem String immer die Länge bekannt, suchen der 0
entfällt, und alle Zeichen (incl. 0-Byte) sind gültig.
Dafür gibts dann andere Nachteile :-)
Vorteil: Wenn man Binär-Daten z.b. über Uart übertragen will,
funktioniert es besser, und man muss sich nicht um Nullen kümmern. Auch
einige Fkt sind schneller, z.b. strlen..
> hhmmmm...> bei mir läuft es momentan nach folgendem Muster:> index_txBuf_W => txBuf[0] <= index_txBuf_R> neuer Wert kommt...> index_txBuf_W++
Und hier passiert es: der Interrupt (z.B. TX-Int der SIO) kommt und der
Schreibpointer ist schon um eins hochgesetzt. Deshalb erkennt der
Interruptcode, dass W und R nicht mehr gleich sind...
Und liest schon mal das Zeichen, das erst nach Beenden der
Interruptroutine geschrieben wird:
> index_txBuf_W => txBuf[1]
Das ist das klassische Semaphorenproblem :-o
> Pascal-like-String-Library> Dafür gibts dann andere Nachteile :-)
Es passen z.B. nur 255 Zeichen in den String.
klaus schrieb:
>> Das könnte bei geeigneter Wahl Puffergröße (256 Bytes statt 255>> Integers) und der Indices (unsigned char hat den Wertebereich 0...255)>> wesentlich kompakter und effizienter geschrieben werden:>> Normalerweise Rischtisch, aber bedenke, mit einem UART könnte man auch 9> bits senden/empfangen (wollen)... ein "unsigned char" Puffer reicht dann> nicht mehr
hä? Die Größe eine einzelnen Array Elementes hat doch nix mit der
Größe/Anzahl speicherbarer Elemente zu tun. Das ganze würde genauso
funktionieren mit einem Puffer der 32bit Werte enthält (sodenn man sie
in eins an die UART weitergeben kann).