Forum: Mikrocontroller und Digitale Elektronik STM32: Ein Zeichen aus dem UART lesen


von Nick (Gast)


Lesenswert?

Ich möchte ein Zeichen aus dem UART lesen und ausgeben.
Benutze ein Nucleo Board.
Ausgegeben wird das auf CoolTerm.
Es wird aber nichts ausgegeben.
Was ist an meiner getchar-Funktion falsch?
Oder ist der code in der while-Schleife falsch?

So sieht mein Code aus.

char getchar() {
  char data[1];
  HAL_UART_Receive(&huart2, (void*)data, 1, HAL_MAX_DELAY);
  return data[0];
}

while (1)
  {
    HAL_UART_Transmit(&huart2,(uint8_t *) "Test",4,HAL_MAX_DELAY);
    HAL_UART_Transmit(&huart2,(uint8_t *) getchar(),1,HAL_MAX_DELAY);
  }

von Codi (Gast)


Lesenswert?

Hi,

da fehlt die initialisierung der UART

von c-hater (Gast)


Lesenswert?

Codi schrieb:
> Hi,
>
> da fehlt die initialisierung der UART

Und die Stelle, an der getchar() benutzt wird...

von c-hater (Gast)


Lesenswert?

c-hater schrieb:
> Codi schrieb:
>> Hi,
>>
>> da fehlt die initialisierung der UART
>
> Und die Stelle, an der getchar() benutzt wird...

Kommando zurück, im zweiten Anlauf habe ich den Aufruf gesehen...

von c-hater (Gast)


Lesenswert?

c-hater schrieb:

> Kommando zurück, im zweiten Anlauf habe ich den Aufruf gesehen...

Trotzdem ist der Fehler genau hier. getchar liefert ein char, gefordert 
von ist aber offensichtlich ein Zeiger auf ein char.

Schwachsinn, das Problem durch einen cast lösen zu wollen...

von Heinz M. (subi)


Lesenswert?

Hast du schon getestet RX und TX am PC direkt zu verbinden und damit vom 
PC auf den PC eine Nachricht zu senden?

Funktioniert das senden vom µC auf den PC ohne auf dem µC zu empfangen? 
Ich bin grad selbst am Empfangen dran, jedoch mit DMA. Ist ziemlicher 
Mist, da sollte senden erst mal sauber funktionieren.

Probier erstmal die Hex Zahlen von ASCII fest in ein Array zu schreiben 
und das zu senden.

Danach den Empfangenen Hexwert direkt ohne Umwege wieder senden.

Dann würde ich erst anfangen mit Interpretationen.

Die üblichen Verdächtigen:
- Richtiger COM Port?
- Gleiche Einstellungen µC und PC?
- RX/TX gekreuzt?

von Nick (Gast)


Lesenswert?

c-hater schrieb:
> c-hater schrieb:
>
>> Kommando zurück, im zweiten Anlauf habe ich den Aufruf gesehen...
>
> Trotzdem ist der Fehler genau hier. getchar liefert ein char, gefordert
> von ist aber offensichtlich ein Zeiger auf ein char.
>
> Schwachsinn, das Problem durch einen cast lösen zu wollen...

Was soll ich anders machen?

von Nick M. (Gast)


Lesenswert?

Nick schrieb:
> Was soll ich anders machen?

Als Gefummle fällt mir die Lösung ein:

char* getchar() {
  static char data;
  HAL_UART_Receive(&huart2, (void*)data, 1, HAL_MAX_DELAY);
  return &data;
}

Ist das UART_Receive blocking?

von c-hater (Gast)


Lesenswert?

Nick M. schrieb:

> Als Gefummle fällt mir die Lösung ein:

Das wird immerhin funktionieren, ist aber weit jenseits von "schön"...

von c-hater (Gast)


Lesenswert?

c-hater schrieb:

> Das wird immerhin funktionieren

Nein, wird es nicht. Hier greift dann quasi das umgekehrte Problem. 
Funktionieren würde es so:

>   HAL_UART_Receive(&huart2, &data, 1, HAL_MAX_DELAY);

Wie wäre es, wenn du erstmal die Sprache lernst, bevor du sie benutzt?

von Nick M. (Gast)


Lesenswert?

c-hater schrieb:
> Das wird immerhin funktionieren, ist aber weit jenseits von "schön"...

Darum schrub ich ja "Gefummle". Entscheident ist auch, ob das 
HAL_UART_Receive blocking ist.
Wenn nicht, dann ist mein Vorschlag richtiger Mist. :-)))

von Nick M. (Gast)


Lesenswert?

Nick M. schrieb:
> HAL_UART_Receive(&huart2, (void*)data, 1, HAL_MAX_DELAY);

Oh Mist!
Natürlich
> HAL_UART_Receive(&huart2, &data, 1, HAL_MAX_DELAY);

von Nick (Gast)


Angehängte Dateien:

Lesenswert?

Keine Ahnung, ob das HAL_UART_Receive blocking ist oder nicht.
Ich weiß auch nicht, was das blocking zu bedeuten hat.
So, sieht mein jetziger Code aus und es funktioniert immer noch nicht. 
Siehe Anhang.

void getchar() {
  uint8_t data;
  HAL_UART_Receive(&huart2, &data, 1, 100);
  HAL_UART_Transmit(&huart2, &data,1,100);
}

  while (1)
  {
    uprints("Test\n");
    getchar();
  }

von Nick M. (Gast)


Lesenswert?

Nick schrieb:

Oh Mann! Kauf dir ein C-Buch, arbeite das durch!

> void getchar() {
>   uint8_t data;
>   HAL_UART_Receive(&huart2, &data, 1, 100);
>   HAL_UART_Transmit(&huart2, &data,1,100);
> }

Du empfängst also kein Zeichen vonm UART, denn an den wird nichts 
gesendet. Das nicht empfangene Zeichen schickst du dann wieder dir 
selbst.
Und das rufst du immer wieder auf und es passiert immer wieder das 
Gleiche:
Empfange nichts, schick das Nichts weg
Empfange nichts, schick das Nichts weg
Empfange nichts, schick das Nichts weg

Nick schrieb:
> while (1)
>   {
>     uprints("Test\n");
>     getchar();
>   }

Wer ist schneller? Der STM oder seine serielle Schnittstelle? Du 
ballerst die Schnittstelle mit "Test" zu, empfänst nicht, schickst das 
nichts weg, ... ad infinitum.
Wohin geht uprints? Ist das das gleiche wie huart2? Warum schickst und 
empfängst du von huart2? Hängt da ein gekreuztes Kabel dran?

Und google nach blocking transmit.

von Nick (Gast)


Lesenswert?

Ich will einfach nur wissen, was ich am Code verändern muss.

von Nick M. (Gast)


Lesenswert?

Nick schrieb:
> Ich will einfach nur wissen, was ich am Code verändern muss.

Und was kommt als nächstes?
Es wurde hier schon gesagt. Versuch die Änderungen anhand deiner 
Unterlagen zu C nachzuvollziehen.
Lies dazu:
static, den '&' operator, Rückgabewerte von Funktionen.
Und lass das casting weg, das ist für dich nix.

Andere werden dir möglicherweise den kompletten code posten, ich nicht. 
Weil von dir keine Initiative kommt. Du hast ganz offensichtlich die 
Antworten und Tips hier nicht gelesen.

von Rainer V. (a_zip)


Lesenswert?

Nick schrieb:
> Ich will einfach nur wissen, was ich am Code verändern muss.

...ist ja gut...du dafst das auch wissen wollen...ganz schön frech!
Gruß Rainer

von Nick (Gast)


Lesenswert?

Was ist die Lösung?

von Nick M. (Gast)


Lesenswert?

42, wie immer.

von NichtWichtig (Gast)


Lesenswert?

RTFM!

von W.S. (Gast)


Lesenswert?

Nick schrieb:
> Keine Ahnung, ob das HAL_UART_Receive blocking ist oder nicht.
> Ich weiß auch nicht, was das blocking zu bedeuten hat.

Tja.

Du willst irgend eine fremde Funktion benutzen, ohne darüber auch nur 
das Geringste zu wissen, was auch das "blockierend" einschließt.

Meinst du nicht, daß du vielleicht zunächst mal versuchen solltest, 
das zu deinem Chip gehörige Referenzmanual zur Hand zu nehmen und dort 
das Kapitel über die UART's zu lesen?

Und auch das Kapitel, das sich mit dem Aufsetzen diverser Bestandteile 
des betreffenden Chips befaßt?

Also den Systemtakt, die Takte für die diversen Peripherie-Cores, die 
Verwendung der diversen Pins des Chips für die verschiedenen Zwecke.

Und dann wäre es Zeit, sich mal darüber klar zu werden, wie das 
Empfangen von Zeichen über einen UART im allgemeinen passiert: Entweder 
sendet da niemand etwas, weswegen der UART auch nix empfangen kann, oder 
es wird was gesendet, aber aus Sicht der CPU mit ihren 72 MHz Takt oder 
noch viel mehr ist das Hereinkommen der Bits in den UART ausgesprochen 
langsam.

Kurzum, man sollte begreifen, daß man von einem Zeichen per UART bis zum 
nächsten Zeichen ziemlich lange warten muß (aus Sicht der CPU). Nun kann 
man ja so verfahren, daß man den UART fragt, ob er denn etwas da hat, 
was man abholen kann und es ggf. dann eben abholen und wenn nix da ist, 
entweder drauf warten oder in der Zwischenzeit irgend etwas anderes 
machen.

Jetzt solltest du auch kapiert haben, was es mit dem Blockieren auf sich 
hat.

Dir rate ich, all solche Dinge SELBST zu schreiben, damit du sie dann 
auch selbst kapiert hast - und eben NICHT elleweil nur irgendwelche 
dir nicht bekannten Fremdfunktionen benutzen zu wollen. Irgendwelches 
Zeugs von ST ist schließlich kein Betriebssystem, das von sich aus die 
Peripherie wie beim PC verwaltet.

W.S.

von NichtWichtig (Gast)


Lesenswert?

Wobei doch die HAL als Source vorliegt und es ein leichtes ist dort zu 
Lesen und zur Laufzeit durch zu tracen. Zumindest mit dem AtollicStudio.

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.