Forum: Mikrocontroller und Digitale Elektronik STM32 USART4 funktioniert nicht


von Daniel D. (duco)


Lesenswert?

Hallo zusammen,

folgendes Problem:
Ich versuche per STM32 einen Fingerprinter anzusteuern per USART (4).
Die USARTs 1 und 2 sind im Einsatz und funktionieren.

Ich habe (wie auch bei den anderen USARTs) mit CubeMX gearbeitet.
Ich sende meine Daten an das FP-Modul (FPM) und erhalte als "Antwort" 
nur eine "0" anstatt sinnvollen Daten. Das wars, es herrscht keine 
Kommunikation mehr. Das FPM ist eingeschaltet, zieht Strom. Egal, ob 
dieses angeschlossen ist oder nicht, ich erhalte immer den selben 
Ablauf.

Zum Senden und Empfangen nutze ich die HAL Funktionen. Ich habe bereits 
mit und ohne IT getestet, immer dasselbe Ergebnis.

Hat Jemand eine Idee, wo der Fehler ist? Ich sende immer jeweils ein 
Byte pro Befehl.

IDE: Eclipse
OS: Win10

// Initialisierung von USART4
uint8_t fp_hw_Init(uint16_t bRate, uint8_t isr)
{
  /*
   * Asynchron
   * 8 Data Bits
   * 1 Stop Bit
   * 0 Parity Bits
   * Rx/Tx Enabled
   */
  uint8_t ret = FP_OKAY;
  __HAL_RCC_USART4_CLK_ENABLE();

  Set_GPIO(FP_TX_PORT, FP_TX_PIN, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL);
  HAL_GPIO_WritePin(FP_TX_PORT, FP_TX_PIN, GPIO_PIN_RESET);

  Set_GPIO(FP_RX_PORT, FP_RX_PIN, GPIO_MODE_INPUT, GPIO_NOPULL);

  huart4.Instance = USART4;
  huart4.Init.BaudRate = bRate;
  huart4.Init.WordLength = UART_WORDLENGTH_8B;
  huart4.Init.StopBits = UART_STOPBITS_1;
  huart4.Init.Parity = UART_PARITY_NONE;
  huart4.Init.Mode = UART_MODE_TX_RX;
  huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart4.Init.OverSampling = UART_OVERSAMPLING_16;
  huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart4) != HAL_OK)
  {
    Error_Handler();
    ret = FP_ERROR;
  }else{
    ret = fp_hw_SetIRMode(isr);
  }

  return ret;
}

uint8_t fp_hw_SetIRMode(uint8_t isr){

  uint8_t ret = FP_OKAY;

  if(isr == FP_INTERRUPT_ON)
    NVIC_EnableIRQ(USART4_5_IRQn);
  else if(isr == FP_INTERRUPT_OFF)
    NVIC_DisableIRQ(USART4_5_IRQn);
  else
    ret = FP_ERROR;

  return ret;

}

von Nico W. (nico_w)


Lesenswert?

Welcher Chip ist es denn? Gibt ein paar mehr STM32.


Sicher dass dein USART kein UART ist? Beim ersten schellen Suchen eines 
Datenblattes war dem nämlich so. Also ggf. nicht nur das RefMan in die 
Hand nehmen.

von Daniel D. (duco)


Lesenswert?

Chip: STM32L071RBTx

CubeMX betitelt diese Pins als USART Pins. Kann CubeMX sich dort 
täuschen? Ich bin davon ausgegangen, dass die Software weiß was Sie tut.

Danke!

von pegel (Gast)


Lesenswert?

Funktioniert denn das FPM am USB-Seriell Wandler?

Ich habe auch mal so ein Modul aus China bestellt und ein Datenblatt und 
die Software nach geordert, da das Modul anders als das gezeigte war.

Angegeben waren 5V Versorgung. Hat nach einschalten ein paar Sekunden 
funktioniert, dass wurde das Ding sehr heiß bis nichts mehr ging, außer 
die Beleuchtung.

Bei genauer Betrachtung war kein 3V3 Regler aufgelötet!

Mit 3V3 lief das Ding einwandfrei.

von Daniel D. (duco)


Lesenswert?

pegel schrieb:
> Funktioniert denn das FPM am USB-Seriell Wandler?

Das habe ich noch nicht getestet. Ein Bekannter nutzt dasselbe FPM, nur 
mit einem Atmel MC, daran angeschlossen funktioniert das FPM super. Also 
ich habe meins auch mal an seinem MC gehabt, von daher funktioniert das 
FPM definitiv. Daher auch der Gedanke daran, dass etwas am USART4 nicht 
stimmt.

von pegel (Gast)


Lesenswert?

Für den USART kannst du den Schleifentest durchführen.
Also RX-TX verbinden, senden und sehen was ankommt.

von Stefan F. (Gast)


Lesenswert?

Niedrige Baudrate kombiniert mit LEDs an RxD und TxD kann auch 
aufschlussreich sein, wenn man keinen Logicanalyzer hat.

von Daniel D. (duco)


Lesenswert?

So, habe es jetzt ausprobiert. Der MC schickt weder etwas raus, noch 
reagiert er auf empfangenes. Ich habe erst den Schleifentest gemacht und 
anschließend mit LEDs und einem UART->USB-Kabel eine Kommuniaktion mit 
dem PC hergestellt. Der PC sendet (LED blinkt) und der MC empfängt 
nicht. Der MC sendet und gibt ein HAL_OK zurück, der PC empfängt nicht, 
die LED bleibt aus.

von pegel (Gast)


Lesenswert?

RX-TX und TX-RX hast du aber schon beachtet?

von pegel (Gast)


Lesenswert?

Ach so, auch der Schleifentest funktioniert nicht!?

Zeig mal deine .ioc Datei und sag uns die Pins die du benutzt in der 
Schaltung.

von Daniel D. (duco)


Angehängte Dateien:

Lesenswert?

ioc s. Anhang.

Nutze dementsprechend die Pins PA9/10. Habe es mal mit USART1 jetzt 
ausprobiert, funktioniert komischerweise jetzt auch nicht.


static void MX_USART1_UART_Init(void)
{

    __USART1_CLK_ENABLE();
  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}








static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pins : PA9 PA10 */
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF5_USART1;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

von pegel (Gast)


Lesenswert?

Ich verstehe auch nicht ganz warum du nicht alle HAL Funktionen für die 
Serielle benutzt.

Vom Init bis zum Callback macht er doch alles für dich Mundgerecht 
fertig.

von pegel (Gast)


Lesenswert?

Die .ioc ist für einen L071RZ angelegt.

von pegel (Gast)


Lesenswert?

Dürfte aber ausser anderem Speicher bzw. Linker Script keine 
Auswirkungen haben, oder?

von pegel (Gast)


Lesenswert?

Übrigens gibt es für das aktuelle CubeMX 5.1.0 auch eine neue L0 
HAL-Lib.
Nicht das es damit Probleme gab.

von Daniel D. (duco)


Lesenswert?

pegel schrieb:
> Ich verstehe auch nicht ganz warum du nicht alle HAL Funktionen für die
> Serielle benutzt.

Was meinst du?

pegel schrieb:
> Die .ioc ist für einen L071RZ angelegt.

Ich hab das mit einem zweiten Chip getestet, aber die Pinbelegung ist 
gleich, daher der andere Chipname.

pegel schrieb:
> Übrigens gibt es für das aktuelle CubeMX 5.1.0 auch eine neue L0
> HAL-Lib.

Ich nutze aktuell die v5.0.0

von pegel (Gast)


Lesenswert?

Daniel D. schrieb:
> Ich nutze aktuell die v5.0.0

Genau. Das steht in der .ioc drin.
Es ist aber dadurch auch eine neue Version der L0 HAL-Lib.
Falls darin ein Fehler sein sollte der USART betrifft,
wäre vielleicht ein Update einen Versuch wert.

von pegel (Gast)


Lesenswert?

Ich meine natürlich in der alten Version.

von Daniel D. (duco)


Lesenswert?

pegel schrieb:
> Falls darin ein Fehler sein sollte der USART betrifft,
> wäre vielleicht ein Update einen Versuch wert.

Habe ich probiert. Nutze v5.1.0, keine Änderung zu sehen.

Hier mal der Code zum senden/empfangen:
uint8_t data = 'a';
HAL_StatusTypeDef ret;
while (1)
{
  HAL_Delay(100);
  ret =  HAL_UART_Receive(&huart1, &data, 1, 1000);
  if(ret == HAL_OK){
    __ASM volatile ("nop");
    HAL_UART_Transmit(&huart1, &data, 1, 1000);
  }
}

von pegel (Gast)


Lesenswert?

Daniel D. schrieb:
> HAL_UART_Receive

ist eine blockierende Funktion. Die alle 100ms aufzurufen und ihr 1s 
Timeout zu erlauben ist vielleicht keine gute Idee.

Ich benutze die Interrupt Varianten für Sendung und Empfang.

von Daniel D. (duco)


Lesenswert?

pegel schrieb:
> ist eine blockierende Funktion. Die alle 100ms aufzurufen und ihr 1s
> Timeout

Inwiefern sollte dies ein Problem sein? Innerhalb der Funktion wird eine 
Sekunde gewartet, danach wird ein Delay von 100ms erzeugt (Welchen ich 
komplett auslassen könnte) und dann wird erneut die Funktion aufgerufen.

von Stefan F. (Gast)


Lesenswert?

Während der 100ms verpasst du empfangene Zeichen (falls es mehr als eins 
ist).

von Daniel D. (duco)


Lesenswert?

Stefanus F. schrieb:
> Während der 100ms verpasst du empfangene Zeichen (falls es mehr als eins
> ist).

Ach darauf wolltest du hinaus. Ich sende durchgehend vom PC aus jeweils 
1 Zeichen ('a'). In der einen Sekunde Timeout-Zeit sollte mindestens 
eines dieser As empfangen werden. Ich kann den Delay auch entfernen, 
kein Problem, kommt jedoch dasselbe bei rum.

von Stefan F. (Gast)


Lesenswert?

Daniel D. schrieb:
> Ich kann den Delay auch entfernen,
> kein Problem, kommt jedoch dasselbe bei rum.

Dachte ich mir schon. Dein Problem war ja, dass du gar nichts empfängst.

von pegel (Gast)


Lesenswert?

Dann mach es mal anders herum. Vergiss das Empfangen auf dem µC und 
sende jede Sekunde ein Zeichen zum PC Terminal Programm.

von Daniel D. (duco)


Lesenswert?

pegel schrieb:
> Dann mach es mal anders herum. Vergiss das Empfangen auf dem µC und
> sende jede Sekunde ein Zeichen zum PC Terminal Programm.

Es wird nichts übertragen. Ich rufe die Transmit Funktion auf und die 
LED an der Tx Leitung blinkt nicht mal. Der PC empfängt dementsprechend 
auch nichts.

von Daniel D. (duco)


Lesenswert?

Stefanus F. schrieb:
> Dachte ich mir schon. Dein Problem war ja, dass du gar nichts empfängst.

Ganz genau, das war eigentlich nur ein Test, um zu gucken ob eine 
Verzögerung etwas ändern würde.

von pegel (Gast)


Lesenswert?

Dann ist doch etwas Oberfaul.

Hast du ein anderes Board?
Am Besten ein Bluepill und USB-Seriell Wandler?

Dann können die Meisten hier spielen.

von pegel (Gast)


Lesenswert?

Mitspielen meinte ich.

von Daniel D. (duco)


Lesenswert?

pegel schrieb:
> Hast du ein anderes Board?
> Am Besten ein Bluepill und USB-Seriell Wandler?

Leider nein, versuche gerade das ganze ohne HAL, also reine 
Bit-Schieberei, zu realisieren.

von pegel (Gast)


Angehängte Dateien:

Lesenswert?

Ich vertraue jetzt mal blind auf CubeMX und HAL.

Ich habe ein Projekt für den STM32L071RB angelegt.
Mit HSI.
USART4 sendet mit 115200,8,n,1 an PA0.

Ich habe leider keinen L071 hier, aber probier mal ob da etwas kommt.

von Daniel D. (duco)


Lesenswert?

pegel schrieb:
> probier mal ob da etwas kommt

Doofe Frage meinerseits... was mache ich mit der Hex-Datei?

von Stefan F. (Gast)


Lesenswert?

Daniel D. schrieb:
> was mache ich mit der Hex-Datei?

Auf dein Board flashen!

von Daniel D. (duco)


Lesenswert?

Stefanus F. schrieb:
> Auf dein Board flashen!

Danke, hab ich gemacht. Wusste gar nicht, dass es diese Möglichkeit 
gibt.

pegel schrieb:
> Ich habe leider keinen L071 hier, aber probier mal ob da etwas kommt.

Nein, keine Reaktion.


Nur mal nebenbei, ich kann die Pins steuern, sprich ich kann die LED 
einfach zum Leuchten bringen, daher funktioniert zumindest die normale 
Funktion der Pins, was einen kompletten defekt ausschließt.

von Stefan F. (Gast)


Lesenswert?

Ich warte auf die Lieferung eines Boardes mit einem STM32L073, das wird 
voraussichtlich morgen kommen. Dann probiere ich dort mal den USART4 aus 
und melde mich wieder.

von Daniel D. (duco)


Lesenswert?

Danke dir, wäre sicherlich hilfreich!!

von Daniel D. (duco)


Angehängte Dateien:

Lesenswert?

Ich hab mal ein Diagramm der Register im Anhang.
Alle Bits die ich rot markiert habe sind auf 0 gesetzt, die grünen auf 
1.
Was mich stark wundert, ist dass CubeMX den Quellcode so generiert, dass 
das Bit UE im CR1 zum Enablen des UARTS auf 0 ist.
Habe ich dann nachträglich selbst eingeführt.

Ist irgendwas an den Registern auffällig? Die beiden mit schwarz 
durchgestrichenen zeigt mir der huart gar nicht an.

von Daniel D. (duco)


Lesenswert?

Ich habe weitere Tests durchgeführt*:

USART1:
Rx und Tx reagieren nicht.
Die LED die an Rx angeschlossen ist blinkt wenn ich vom PC aus Daten 
sende.
Die LED die an Tx angeschlossen ist blinkt NICHT wenn ich vom MCU aus 
Daten sende.


USART2:
Rx und Tx reagieren nicht.
Die LED die an Rx angeschlossen ist blinkt NICHT wenn ich vom PC aus 
Daten sende.
Die LED die an Tx angeschlossen ist blinkt NICHT wenn ich vom MCU aus 
Daten sende.
Nach den ersten ca. 220 Bytes die ich sende schlägt die Receive Funktion 
einmalig um auf HAL_OK und gibt an den Wert 254 empfangen zu haben, 
obwohl ich ein 'b' sende (ist glaube ich 98). Anschließend erhalte ich 
nur noch HAL_TIMEOUT.

USART4:
Rx und Tx reagieren nicht.
Die LED die an Rx angeschlossen ist blinkt NICHT wenn ich vom PC aus 
Daten sende.
Die LED die an Tx angeschlossen ist blinkt NICHT wenn ich vom MCU aus 
Daten sende.

USART5:
Rx und Tx reagieren nicht.
Die LED die an Rx angeschlossen ist blinkt NICHT wenn ich vom PC aus 
Daten sende.
Die LED die an Tx angeschlossen ist blinkt NICHT wenn ich vom MCU aus 
Daten sende.



Da die LED bei einem USART blinkt und bei den anderen nicht, wird 
offensichtlich eine andere Pin-Konfiguration durchgeführt.








*Jedes mal wurde CubeMX genutzt zur Initialisierung

von (Gast)


Lesenswert?

Blöde Frage, aber die GPIOs bekommen Clock und die Alternate Functions 
sind auch richtig gesetzt? Die Register kann man in der eclipse bei 
angehaltenem Prozessor inspizieren (Reiter "Peripherals").

von pegel (Gast)


Lesenswert?

Hm, die Versorgung liegt ja meist an den Ecken.
Du hast nicht zufällig den Chip verdreht aufgelötet?

von Stefan F. (Gast)


Lesenswert?

Du hast im Eröffnungsbeitrag geschrieben, dass USART 1+2 funktionieren. 
Das passt nicht zu deinem letzten beitrag.

Es wäre hilfreich gewesen, wenn du die Pins genau benannt hättest. An 
welchen Pin hast du welche Leitung vom USB-UART Adapter angeschlossen?

Am RxD Pin des µC  muss die LED völlig unabhängig von deiner Firmware 
flackern, denn das Signal kommt ja vom PC. Welche Spannung misst du dort 
in verbundenem Zustand ohne Datenübertragung und ohne LED?

Bist du ganz sicher, die Leitungen richtig zugeordnet zu haben?

Für die Daten vom PC zum µC:
Aus TxD vom USB Adapter kommen im Ruhezustand 3,3V oder 5V heraus und 
das muss mit dem RxD Eingang des Mikrocontrollers verbunden werden.

Für die andere Richtung:
Der TxD Ausgang des Mikrocontrollers liefert im Ruhezustand 3,3V und 
wird mit dem RxD Eingang des PC verbunden.

Hast du dein UART Kabel mit einem Loop-Back Test kontrolliert? Mach das 
mal, um ganz sicher zu sein.

Folge der Anleitung 
http://stefanfrings.de/mikrocontroller_buch2/Einblick%20in%20die%20moderne%20Elektronik.pdf 
Kapitel 6.

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Das Board ist angekommen, ich habe gleich als erstes deinen Fall 
geprüft. Sowohl USART2 als auch USART4 funktionierten auf Anhieb. Ich 
habe nur die folgenden Zeilen in die leere Hauptschleife eingefügt:
1
      // LED on
2
      HAL_Delay(500);
3
      WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BS_5);
4
5
      HAL_UART_Transmit(&huart2,(void*) "Hallo\n",6,100);
6
      HAL_UART_Transmit(&huart4,(void*) "Hallo\n",6,100);
7
8
      // LED off
9
      HAL_Delay(500);
10
      WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BR_5);

Alles andere hat CubeMX generiert. Dazu habe ich nicht viel machen 
müssen:

- SYS Debugging via SWD
- USART2 enabled, asynchronous 2400 Baud
- USART4 enabled, asynchronous 2400 Baud
- GPIO PA5 = output push/pull

Alles Andere habe ich auf den Standardvorgaben gelassen.

Das angehängte Bild ist vom Logic Analyzer, den ich mit PA0 (= USART4 
Tx) verbunden habe.

Folgende Software-Versionen habe ich verwendet:
- CubeMX v5.1.0
- STM32CubeL0 Firmware Package v1.11.2
- System Workbench for STM32, alle Plugins heute frisch aktualisiert

von Bauform B. (bauformb)


Lesenswert?

Daniel D. schrieb:
> Ich hab mal ein Diagramm der Register im Anhang.

> Ist irgendwas an den Registern auffällig?

Woher stammt denn das Bild? Das hat keinerlei Ähnlichkeit mit meinem 
Reference Manual (RM0377 für STM32L0x1). Das wäre evt. eine Erklärung 
dafür:

> Was mich stark wundert, ist dass CubeMX den Quellcode so generiert, dass
> das Bit UE im CR1 zum Enablen des UARTS auf 0 ist.

Wenn aber das Bild zu deinem Prozessor passt, warum ist SBK gesetzt? Und 
der Teiler im BRR passt zu einem CPU-Takt im kHz-Bereich?

von Daniel D. (duco)


Lesenswert?

Eigentlich wollte ich hier alle Beiträge noch beantworten, aber dann kam 
ich zu dem Punkt:

Stefanus F. schrieb:
> Am RxD Pin des µC  muss die LED völlig unabhängig von deiner Firmware
> flackern, denn das Signal kommt ja vom PC. Welche Spannung misst du dort
> in verbundenem Zustand ohne Datenübertragung und ohne LED?

Als ich mit dem Multimeter dran ging zum Prüfen wurden aufeinmal Daten 
versendet. Habe dann alles mögliche ausprobiert an der HW und habe jetzt 
am Ende herausgefunden, dass die LEDs, welche mir anzeigen sollten, ob 
die Leitungen genutzt werden, das Problem sind. Ich habe diese entfernt 
und seitdem funktionieren alle USARTs mit Senden und Empfangen außer 
USART1, der empfängt nichts sinnvolles oder gar nichts, kann aber 
wunderbar senden. Ich verstehe zwar nicht, warum es jetzt plötzlich 
geht, da ich zu Beginn auch keine LEDs verwendet habe und da nichts 
funktionierte, aber immerhin habe ich eine "Lösung".

Ich danke euch allen für die Unterstützung!

von Wissen Gschaftler (Gast)


Lesenswert?

Daniel D. schrieb:
> Ich danke euch allen für die Unterstützung!

Ja das hmma ja schon immer gewusst: wenn man LEDs anschliesst
funktionieren die UARTs und USARTs nicht. Steht doch auch
so im Datenblatt drin.

von Stefan F. (Gast)


Lesenswert?

Wissen Gschaftler schrieb:
> Ja das hmma ja schon immer gewusst: wenn man LEDs anschliesst
> funktionieren die UARTs und USARTs nicht. Steht doch auch
> so im Datenblatt drin.

Das stimmt so nicht. Der TxD Ausgang kann locker einige mA treiben, das 
genügt für eine simple Status LED. Mit 1kΩ Widerstand ist man da 
eigentlich auf der sicheren Seite.

Möglicherweise hat dein USB-UART Adapter sehr schwache Ausgänge oder 
recht hochohmige Schutzwiderstände.

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.