Forum: Mikrocontroller und Digitale Elektronik STM32 - UART unit32_t


von Daniel (Gast)


Lesenswert?

Hallo community,

ich bin gerade dabei den STM32L432KC Mikrocontroller kennen zu lernen 
und möchte nun die serielle Ausgabe über die UART Schnittstelle nutzen 
um aktuelle ADC Werte eines Potentiometers alle 2 Sekunden auszugeben.
Der Timer dazu und das Auslesen der ADC Werte funktionieren bereits.
Ich speichere den ADC Wert als unit32_t und wandle den Wert dann in die 
Voltage Dimension um.
Nun zu meinem Problem. Wie ist es mir möglich den unit32_t 
uwInputVoltage über die UART Schnittstelle zu senden? Die Funktion 
HAL_UART_Transmit erwartet sich uint8_t?

1
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
2
{
3
   uint32_t uhADCxConvertedValue = 0;
4
   uint32_t uwInputVoltage =0;
5
    if (HAL_ADCEx_Calibration_Start(&Adc1, ADC_SINGLE_ENDED) != HAL_OK)
6
       {
7
8
         Error_Handler();
9
       }
10
     if (HAL_ADC_Start(&Adc1) != HAL_OK)
11
       {
12
13
         Error_Handler();
14
       }
15
      uhADCxConvertedValue = HAL_ADC_GetValue(&Adc1);
16
                  /* Convert the result from 16 bit value to the          voltage dimension (mV unit) */
17
    /* Vref = 3.3 V */
18
      uwInputVoltage = uhADCxConvertedValue * 3300;
19
      uwInputVoltage = uwInputVoltage/ 0xFFF0;
20
      
21
      HAL_UART_Transmit(&huart2((uint8_t*)(&uwInputVoltage), 4,100);
22
      
23
}
Danke!

von oh weh (Gast)


Lesenswert?

Daniel schrieb:
> Nun zu meinem Problem. Wie ist es mir möglich den unit32_t
> uwInputVoltage über die UART Schnittstelle zu senden?

Indem du (d)eine uint32_t - Variable in 4 Bytes aufteilst und
diese der Reihe nach veschickst, beim Empfänger wieder
zusammensetzt.

von oh weh (Gast)


Lesenswert?

Das war die einfachste, unzuverlässige Methode, es gibt viele
Möglichkeiten mehr die wohl meine Nachredner aufzeigen wollen.

von Kevin M. (arduinolover)


Lesenswert?

Ich nehme mal an du möchtest das in einem Terminal Programm ausgeben? In 
dem Fall musst du deinen Wert in eine ASCII kodierte Zeichenkette 
umwandeln und diese dann Byte weise aussenden. Genaugenommen möchte die 
HAL_UART_Transmit() auch keinen uint8_t sondern einen Zeiger auf einen 
solchen.

ein Beispiel:
1
void sendUART(uint32_t value)
2
{
3
  char buffer [20];
4
  uint32_t len
5
  len = sprintf(buffer, "Wert: %d V\r\n", value);
6
  
7
  HAL_UART_Transmit(&huart2,(uint8_t*)buffer, len,100);
8
}

von Daniel (Gast)


Lesenswert?

Hallo Kevin,

danke für deine Antwort!
Gibt es eine andere Möglichkeit den Wert in eine ASCII kodierte 
Zeichenkette zu wandeln?
Die Aufgabe die ich lösen möchte verbietet den Gebrauch von Standard C 
Rotinen wie sprintf oder malloc

Kevin M. schrieb:
> Ich nehme mal an du möchtest das in einem Terminal Programm
> ausgeben? In
> dem Fall musst du deinen Wert in eine ASCII kodierte Zeichenkette
> umwandeln und diese dann Byte weise aussenden. Genaugenommen möchte die
> HAL_UART_Transmit() auch keinen uint8_t sondern einen Zeiger auf einen
> solchen.
>
> ein Beispiel:
> 1void sendUART(uint32_t value)
> 2{
> 3  char buffer [20];
> 4  uint32_t len
> 5  len = sprintf(buffer, "Wert: %d V\r\n", value);
> 6
> 7  HAL_UART_Transmit(&huart2,(uint8_t*)buffer, len,100);
> 8}

von Cyblord -. (cyblord)


Lesenswert?

Daniel schrieb:
> Gibt es eine andere Möglichkeit den Wert in eine ASCII kodierte
> Zeichenkette zu wandeln?
> Die Aufgabe die ich lösen möchte verbietet den Gebrauch von Standard C
> Rotinen wie sprintf oder malloc

Dann musst es halt nachprogrammieren. Zumindest teilweise.

1.) Aufteilen in Bytes (Stellenwerte mit Division und Modulo)
2.) Konvertieren jedes Bytes in ein  ASCII Zeichen (addieren eines 
festen Offsets laut ASCII Tabelle)
3.) Einen Buffer Byte für Byte damit füllen.
4.) Nullbyte als Terminierung anhängen.
5.) Fertig ist der String.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Daniel schrieb:
> Die Aufgabe die ich lösen möchte verbietet den Gebrauch von Standard C
> Rotinen wie sprintf

Die Aufgabe bestimmt nicht, sondern irgendwelche Ressentiments einer 
Person.
Falls es um den möglichen Pufferüberlauf geht, dann kann man einfach 
snprintf nehmen.

von W.S. (Gast)


Lesenswert?

Cyblord -. schrieb:
> Fertig ist der String.

Tja.

Es ist irgendwie bedrückend, mit ansehen zu müssen, wie unbeholfen hier 
so manche Programmierer sind. Alle wollen irgend etwas ganz Grandioses 
machen, aber sie haben keine Ahnung von den Grundlagen.

Manchmal möchte man all diesen Leuten sagen "übergib dein Projekt an ein 
passendes Ingenieurbüro und zahle deren Salär, fertig! Alternative: 
Lerne selbst, mit Messer und Gabel zu essen."

Aber dann fühlen sich genau diejenigen maßlos beleidigt, die es am 
nötigsten haben.

W.S.

von Walter T. (nicolas)


Lesenswert?

Daniel schrieb:
> Die Aufgabe die ich lösen möchte verbietet den Gebrauch von Standard C
> Rotinen wie sprintf oder malloc

Ich nehme an es handelt sich um eine Schulaufgabe?

von Kevin M. (arduinolover)


Lesenswert?

Du darfst die HAL benutzen aber keine Standard C Funktionen? Sehr 
seltsam, das klingt ja fast nach Hausaufgabe ;)

Beschreib doch vielleicht etwas näher was genau damit gemacht werden 
soll, vielleicht kann man das dann eleganter lösen. Ansonsten wüsste ich 
spontan auch nichts, außer es wie von Cyblord vorgeschlagen selbst zu 
implementieren.

Wo da der mehrwert liegt erschließt sich mir allerdings nicht so ganz. 
Wenn es um eine Übungsaufgabe geht wäre es sinnvoller den UART ohne HAL 
zu benutzen :D

von oh weh (Gast)


Lesenswert?

Kevin M. schrieb:
> Sehr seltsam, das klingt ja fast nach Hausaufgabe

Oder nach System-Troll.

von Nop (Gast)


Lesenswert?

Walter T. schrieb:
> Daniel schrieb:
>> Die Aufgabe die ich lösen möchte verbietet den Gebrauch von Standard C
>> Rotinen wie sprintf oder malloc
>
> Ich nehme an es handelt sich um eine Schulaufgabe?

Da printf u.U. malloc im Hintergrund nutzt und malloc bei embedded 
generell eher skeptisch zu sehen ist, ist die Aufgabe nicht unbedingt 
absurd. Gibt genug Industrieprojekte, wo dynamische Allozierung auf dem 
Heap schlichtweg verboten ist und auch kein Codereview bestünde.

von Walter T. (nicolas)


Lesenswert?

Ich gehe davon aus, dass man in einem Umfeld, bei dem ein Code-Reviews 
stattfinden, Low-Level-Code eher nicht von den Anfänger-Kollegen gemacht 
wird. Und das man dann auch eher Kollegen als das Internet fragt.

Aber beim Thema Schulaufgabe handelt es sich ja auch um eine Frage, 
keine Feststellung.

von Kevin M. (arduinolover)


Lesenswert?

Nop schrieb:
> Da printf u.U. malloc im Hintergrund nutzt und malloc bei embedded
> generell eher skeptisch zu sehen ist, ist die Aufgabe nicht unbedingt
> absurd.

Naja sprintf nutzt aber keinen dynamischen Speicher, daher bekommt es ja 
einen Buffer der vorher in fester Größe angelegt wurde. Wenn man ganz 
sicher seien möchte und seinem Stack nicht traut kann man ihn noch 
global anlegen. Und mit snprintf kann man wie schon angemerkt auch einen 
out of bounds Zugriff verhindern, auch wenn es nicht wirklich ein 
Problem ist die benötigte Buffergröße zu bestimmen.

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.