Forum: Mikrocontroller und Digitale Elektronik UART array auslesen


von max (Gast)


Lesenswert?

Hallo

Ich habe die UART implementiert. STM32F303
Ich würde gerne wissen, wofür der Timeoutparameter in dieser Funktion 
gut ist, bzw. wofür dieser gebraucht wird. Ich erkenne nämlich keinen 
Unterschied, wenn dieser 100 oder 1000000 ist.

 uint8_t aaa='z';
     HAL_UART_Transmit(&huart2, &aaa, sizeof(aaa),100);

zudem würde ich gerne wissen, warum ich so Zeichen senden kann, aber 
folgendes nicht funktioniert

uint8_t array[] = {1, 2, 3, 6, 5, 4};
     HAL_UART_Transmit(&huart2, &array, sizeof(array),100);

Ich wäre um Hilfe sehr dankbar

von max (Gast)


Lesenswert?

Ich habe das Problem jetzt gelöst.
1
 uint8_t array[] = {'m', 'a', 'x', 'd', 'e', 'n', 'g', 'e', 'r'};
2
 HAL_UART_Transmit(&huart2, &array[0], sizeof(array), 100);

Jedoch würde ich trotzdem gerne wissen, wofür die Timeout ist.
Das habe ich leider nicht gefunden.
1
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

Zudem wollte ich wissen, wie man jetzt zb ein double-Wert zB 1.3256 
überträgt, wenn man diese Funktion nutzen möchte?
Geht das irgendwie? Das Problem ist das uint8t, die die Variable oder 
das Array haben muss. Ich kann ja nicht einfach die Funktion ändern.
Sorry für die blöde Frage.

max

von Tippgeber (Gast)


Lesenswert?

max schrieb:
> Zudem wollte ich wissen, wie man jetzt zb ein double-Wert zB 1.3256
> überträgt, wenn man diese Funktion nutzen möchte?
> Geht das irgendwie? Das Problem ist das uint8t, die die Variable oder
> das Array haben muss. Ich kann ja nicht einfach die Funktion ändern.

Du hast zwei Probleme: Du tippst Deine Programme ohne Konzept und ohne 
Überlegung vor Dich hin und Du kannst kein C. Beides solltest Du lernen.

Tipp1: Wandle die float-Zahl z.B in ein passendes, für die Übertragung 
eher geeignetes Format. Denk dabei auch an den Empfänger, der irgendwie 
wissen muss, was da wann ankommt. Stichwort: Protokoll

Tipp2: Lies die Dokumentation und überlege, wie serielle Übertragung 
funktioniert. Wozu könnte man dort ein timeout brauchen?

von PittyJ (Gast)


Lesenswert?

Timeout:
https://developer.mbed.org/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/stm32l4xx__hal__uart_8c_source.html

Ab Zeile 619

Doublewert:
snprintf() benutzen.
Ein C Buch wäre für dieses Basics ganz praktisch.

von max (Gast)


Lesenswert?

Ich weiss nicht, warum ihr immer gleich einen runter macht, nur weil es 
irgendwo einmal hängt... Motivierend ist das nicht gerade. Wenn ich 
nicht weiss, wo der Motor im Auto sitzt, heisst das ja auch nicht 
gleich, ich könne nicht autofahren.

Aaaalso

Was weiss ich über die UART?
Es gibt eine asynchrone und synchrone UART. Die synchrone UART hat keine 
Start und Stop Bits und synchronisiert sich über eine weitere Leitung 
(Taktleitung). Diese ist hier aber unwichtig, da ich die Schnittstelle 
RS-232 nutze, die asynchron ist. Die Uebertragung erfolgt byteweise und 
es werden für die Synchronisierung Start und Stopbits benötigt.

Die zeichenweise Uebertragung funktioniert ja und ich kann ja mit der 
verwendeten fertigen Funktion Zeichen übertragen.
Ein double oder float-Wert ist ja schlussendlich auch nichts anderes als 
eine Zusammensetzung aus einzelnen Bytes. Ein double-Wert hat glaub ich 
13 Zeichen und float-Wert 22. Wenn eine Uebertragung von einem Zeichen 
also 1ms dauert, dauert die Uebertragung von einem float-Wert zB 22ms.

Herausgefunden habe ich:

The value corresponding
to a timeout of 2 character times (for example 22 x bit duration) must 
be programmed in the RTO register. when the receive line is idle for 
this duration, after the last stop bit is received,
an interrupt is generated, informing the software that the current block 
reception is completed.

Bit 23 RTOEN: Receiver timeout enable
This bit is set and cleared by software.
0: Receiver timeout feature disabled.
1: Receiver timeout feature enabled.
When this feature is enabled, the RTOF flag in the USART_ISR register is 
set if the RX line is idle (no reception) for the duration programmed in 
the RTOR (receiver timeout register).

Das verstehe ich so:
Im RTO Register definiere ich die Zeit.
Wenn RTOEN = 1 ist, bleibt die RX Leitung leer für die programmierte 
Zeit im RTOR.

Aber warum muss diese für diese Zeit leer bleiben??
Hat das mit der Synchronisierung zu tun?
Der Link zeigt weder die Einheit des Timeout, noch erklärt dieser wofür 
das gut ist.

von Tippgeber (Gast)


Lesenswert?

max schrieb:
> Wenn ich
> nicht weiss, wo der Motor im Auto sitzt, heisst das ja auch nicht
> gleich, ich könne nicht autofahren.

Schlechter Vergleich. Du fährst es nicht, Du baust ein Auto. (Auto = 
Programm)

max schrieb:
> When this feature is enabled, the RTOF flag in the USART_ISR register is
> set if the RX line is idle (no reception) for the duration programmed in
> the RTOR (receiver timeout register).
>
> Das verstehe ich so:
> Im RTO Register definiere ich die Zeit.
> Wenn RTOEN = 1 ist, bleibt die RX Leitung leer für die programmierte
> Zeit im RTOR.

Das IF (Wenn) ist bei Deiner Übersetzung an die falsche Stelle geraten. 
Wenn die RX-Leitung für die programmierte Dauer leer bleibt, wird RTOEN 
gesetzt. Ja, es hat mit der Synchronisation zu tun:

max schrieb:
> when the receive line is idle for
> this duration, after the last stop bit is received,
> an interrupt is generated, informing the software that the current block
> reception is completed.

von Tippgeber (Gast)


Lesenswert?

Tippgeber schrieb:
> wird RTOEN
> gesetzt.

Falsch abgeschrieben: RTOEN meint RTOF-Flag

von Tippgeber (Gast)


Lesenswert?

Was mir gerade auffällt:

Außerdem hat RTOR, RTOF nichts mit Deinem timeout zu tun, denn Du 
sendest ja. Die für Dich entscheidende Stelle im link ist:

> if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK)

von max (Gast)


Lesenswert?

Ok danke

if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != 
HAL_OK)

Das heisst in dem Fall, dass wenn ich ein Timeout von 1 eingebe (1ms), 
dann wartet die UART bis die Zeit abgelaufen ist und das Flag gesetzt 
ist. Dann ist das Senden abgeschlossen und es kann das nächste Zeichen 
gesendet werden. Die ideale Zeit bei bei einer Baudrate von 9600 wäre 
8bit + 2 bits (start stop) = 10 --> 10/9600 s = ca. 1ms.
Richtig?

Was meinst du mit:
Tipp1: Wandle die float-Zahl z.B in ein passendes, für die Übertragung
eher geeignetes Format. Denk dabei auch an den Empfänger, der irgendwie
wissen muss, was da wann ankommt. Stichwort: Protokoll

Ich muss ja, wenn ich mit anderen Devices kommuniziere immer den Typ und 
den Endian angeben. Aber das was ich möchte ist, die Werte nur zu 
visualisieren, sprich an den PuTTY schicken.

Um jetzt nicht alles zu verkomplizieren und den float Wert der zB 22 
Zeichen hat, durch einen Algorithmus selbst aufwändig von einer 
Gleitkommazahl in die Gleitkommadarstellung umzurechnen, kann ich ja 
auch einfach die double Werte in einen String umwandeln und dies der 
Funktion übergeben. Oder ist das nicht so einfach?

von Tippgeber (Gast)


Lesenswert?

max schrieb:
> UART_FLAG_TXE

Ich kenne die STM32F3xx nicht so gut, um hier als Experte durchzugehen. 
Trotzdem meine ich, dass dieses Flag dafür steht, dass der Sendebuffer 
voll bzw. leer ist. Da die HAL-Funktion blockierend sein soll, (ich habe 
jetzt die Funktion nicht eingehend analysiert, sondern mal auf den 
Begleittext vertraut) muss nach einer gewissen Zeit (timeout) das Warten 
auf das Flag abgebrochen werden. D. h., wenn das Senden aus irgendeinem 
Grund nicht klappt, soll nach Ablauf von timeout mit einer Fehlermeldung 
abgebrochen werden.

max schrieb:
> Ich muss ja, wenn ich mit anderen Devices kommuniziere immer den Typ und
> den Endian angeben. Aber das was ich möchte ist, die Werte nur zu
> visualisieren, sprich an den PuTTY schicken.

Dir fehlt noch immer ein Konzept. Das muss klar sein, bevor Du über 
konkrete Umsetzungen (á la putty) sprichst.

- Kannst Du den Empfänger beeinflussen oder verwendet dieser bereits ein 
feststehendes Protokoll? (Putty spricht z. B. nur ASCII, soweit ich 
weiß)

- Wem willst Du was mitteilen und wie stellst Du sicher, dass der 
Empfänger weiß, wann was kommt und dass er auch bei Übertragungsfehlern 
entweder diese bemerkt, die Werte ignorieren oder neu anfordern oder im 
besseren Fall sogar diese berichtigen kann.

Wenn Du das weißt, dann kannst Du an die technische Umsetzung gehen. Die 
wird wesentlich einfacher sein, weil Du dann genau weißt, was Du 
brauchst.

max schrieb:
> kann ich ja
> auch einfach die double Werte in einen String umwandeln und dies der
> Funktion übergeben.

Das wäre u. U. Teil einer Lösung, aber noch nicht die Gesamtlösung.

von max (Gast)


Lesenswert?

klar, ein Protokoll benötige ich, wenn ich mich jetzt durch das Manual 
arbeite und wirklich die Bits so hin und her schiebe, dass letztlich 
gesendet und empfangen werden kann. Dann muss ich sehen, dass dieses und 
jenes Bit gesetzt ist, bevor ich sende und empfange. Das muss ich genau 
planen dann. Nur dann brauche ich ein Protokoll.

Das Protokoll ist doch schon in dieser HAL-Transmit Funktion schon drin. 
Ich kann ja ein Zeichen senden und muss nichts empfangen.

Ich kann so auch was senden, auch wenn ich von der UART 0.000% Ahnung 
habe, ich muss nämlich nur eine Variable oder ein Array mit diesen 
Zeichen übergeben. Den Rest macht mir die Funktion.

Deshalb verstehe ich deinen Einwand nicht.

Ich kann doch:
1. Den Double Wert mittels einer Funktion in einen String wandeln
2. diesen String dann portionieren, sofern notwendig
3. die einzelnen Zeichen des Strings dann in einen Array uebertragen
4. den Array dann der Funktion Transmit übergeben

Ich weiss nicht, ob wir einander vorbei reden
Kann ja auch sein, dass ich komplett etwas falsch verstehe, was ich mir 
jedoch nicht vorstellen kann, da ja die Funktion genau ein Zeichen des 
Typs uint8_t (char) benötigt. Und das uebergebe ich mit diesem Ansatz 
auch..

von max (Gast)


Lesenswert?

Also ich kann ja kein C :D, aber ich habs jetzt trotzdem hinbekommen mit 
der Fkt Transmit.

Da muss ich jetzt noch lachen, dass das mit dem Auto ein schlechter 
Vergleich ist. Aber dein Argument oder deine Behauptung ist dann auch 
schlecht.

Ich habe bis jetzt noch kein Protokoll gebraucht und denke du hast 
selbst keine Ahnung was du da schreibst und willst.

von batman (Gast)


Lesenswert?

Hast aber schon nen kleinen Sprung in der Schüssel oder? :)

von max (Gast)


Lesenswert?

Nein, alle Schuesseln noch ganz. Hab extra wegen dir nochmals in der 
Kueche nachgeschaut..

Ich weiss ja nicht woher du kommst, aber bei uns ist freie 
Meinungsaeussserung. Nichts fuer ungut. ;)

von Tippgeber (Gast)


Lesenswert?

max schrieb:
> Also ich kann ja kein C :D, aber ich habs jetzt trotzdem hinbekommen mit
> der Fkt Transmit.

Du hast lediglich ein Teilproblem gelöst, dessen Lösung hier schon steht 
und das ganz offensichtlich war.

max schrieb:
> Ich habe bis jetzt noch kein Protokoll gebraucht und denke du hast
> selbst keine Ahnung was du da schreibst und willst.

Angesichts Deiner dümmlichen Beleidigungen sollte Dir niemand mehr 
helfen.


Aber einen Tipp für alle anderen Interessierten hab ich doch noch:

https://www.datenschutzbeauftragter-info.de/osi-modell-so-kommunizieren-rechner/
(beispielhaft für viele Fundstellen im Netz) Mit der UART ist man auf 
der physikalischen Ebene bzw. maximal im data-link-Layer.



Bei einer Kommunikation müssen Sender und Empfänger immer irgendwie 
synchronisiert werden.

Für alle Harry-Potter-Fans: Stell Dir vor, Du bist der Empfänger. Du 
bist in einem dunklen Wald an einen Baum gefesselt und kannst nur 
geradeaus sehen. Du siehst auch nur einen Meter weit. Allerdings weißt 
Du, dass der andere Dich rufen hört.

Ständig huschen Gestalten mit einem Zettel in der Hand an Dir vorbei. 
Manchmal bleiben sie direkt vor Dir stehen und Du kannst die Botschaft 
des anderen (acht Bits) richtig lesen. Manchmal stehen sie zu weit weg 
oder neben Dir. Dann kannst Du nur Teile oder gar nichts von dem Zettel 
lesen. (Übertragungsstörungen) Gelegentlich schläfst Du auch ein oder 
bemerkst nicht einmal, dass da ein Bote war. (Ausfall der Übertragung) 
Bei UART kann das nicht passieren, aber bei anderen Übertragungen: Es 
kommt vor, dass ein Bote schneller als der vorher gestartete ist und Dir 
seinen Zettel vor dem anderen zeigt.

Wie lautet jetzt die Botschaft an Harry? Was müssen der 
Nachrichtenschreiber und Harry tun, damit es zu einer zuverlässigen 
Übertragung kommt?

Jetzt klarer, wozu man ein Protokoll braucht?

von Tippgeber (Gast)


Lesenswert?

max schrieb:
> aber bei uns ist freie
> Meinungsaeussserung.

Beleidigungen bzw. üble Nachrede gehören nicht zur freien 
Meinungsäußerung.

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.