Forum: Mikrocontroller und Digitale Elektronik STM32 - Probleme mit der UART im RX-Interrupt mode


von M. G. (ixil96)


Angehängte Dateien:

Lesenswert?

Hallo,

ich verwende einen STM32L010 Mikrocontroller mit einem RN2483A (LoRa 
Modul) bei 57600 Baud - ohne ext. Quarz.

An und für sich funktioniert die Kommunikation, aber sobald ich das 
RN2483 Modul in den sleep mode versetze und nach 5 Minuten wieder 
aufwecke, wird keine Rx-Interrupt Routine mehr ausgelöst wenn Daten auf 
der Rx-Leitung anstehen.

Messung mit dem Oszi zeigt aber saubere Daten (siehe Bild) nur der 
Controller bekommt es irgendwie nicht mit - also kein Einsprung in die 
ISR.

Lege ich das RN2483A Modul aber nicht schlafen, dann funktioniert alles 
und die ISR wird ausgeführt wenn Daten kommen.

Das erfolgreiche Aufwachen des RN2483A Moduls wird mit OK bestätigt.

Hat jemand eine Idee was hier das Problem sein kann?

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Wie sieht denn die UART Leitung aus wenn das RN2483 schläft?
Immernoch idle high?

von Zod M. (do0zy)


Lesenswert?

M. G. schrieb:
> Lege ich das RN2483A Modul aber nicht schlafen, dann funktioniert alles
> und die ISR wird ausgeführt wenn Daten kommen.

nachdem die Daten deinem Screenshot nach immer noch von dem Modul 
gesendet werden, liegt die Vermutung nahe, dass du in der uC Software 
einen Fehler in der "Schlafen legen Befehl" Routine machst.
Ohne deinen Code zu sehen kann dir da aber niemand weiterhelfen.

von M. G. (ixil96)


Lesenswert?

Mw E. schrieb:
> Wie sieht denn die UART Leitung aus wenn das RN2483 schläft?
> Immernoch idle high?

Ja

von M. G. (ixil96)


Lesenswert?

D. W. schrieb:
> M. G. schrieb:
>> Lege ich das RN2483A Modul aber nicht schlafen, dann funktioniert alles
>> und die ISR wird ausgeführt wenn Daten kommen.
>
> nachdem die Daten deinem Screenshot nach immer noch von dem Modul
> gesendet werden, liegt die Vermutung nahe, dass du in der uC Software
> einen Fehler in der "Schlafen legen Befehl" Routine machst.
> Ohne deinen Code zu sehen kann dir da aber niemand weiterhelfen.

Ja das war auch meine erste Vermutung. Doch das Modul legt sich schlafen 
(Strommessung bestätigt das) und nach dem Aufwecken erhalte ich ein OK - 
somit stimmt hier alles.

von Zod M. (do0zy)


Lesenswert?

M. G. schrieb:
> Ja das war auch meine erste Vermutung. Doch das Modul legt sich schlafen
> (Strommessung bestätigt das) und nach dem Aufwecken erhalte ich ein OK -
> somit stimmt hier alles.

Du hast glaub ich nicht verstanden, was ich meinte. War auch schlecht 
formuliert von mir..

Dein Mikrocontroller schickt das Modul in den Schlafmodus. Dafür wirst 
du wahrscheinlich eine Funktion geschrieben haben. Wenn du diese 
Funktion nicht aufrufst scheint ja alles glatt zu laufen. Aber sobald du 
die Schlafenlegen Funktion mit ins Spiel bringst, löst der uC keinen 
Interrupt mehr aus.
Also könnte es sein, dass du in diesem Teil deines Programmcodes einen 
Fehler hast, der dazu führt, dass nicht mehr in die ISR gesprungen wird.

Allerdings ist meine Glaskugel heute sehr staubig und ich hab keine Lust 
mehr die heute Abend noch zu putzen..wenn du deinen Code nicht posten 
möchtest, wirds also schwierig an der Stelle zu debuggen.

von Stefan F. (Gast)


Lesenswert?

M. G. schrieb:
> wird keine Rx-Interrupt Routine mehr ausgelöst wenn Daten auf
> der Rx-Leitung anstehen.

M. G. schrieb:
> Doch das Modul legt sich schlafen
> (Strommessung bestätigt das) und nach dem Aufwecken erhalte ich ein OK -

Für klingt das nach einem Widerspruch.

von M. G. (ixil96)


Lesenswert?

Das ist meine Routine für den sleep mode:
1
void rn2483_sleep(void)
2
{
3
    //uint8_t rn2483_go_in_sleep[] = {"sys sleep 864000000\r\n"};  
4
    len_of_data1 = strlen((char*)rn2483_go_in_sleep);
5
    if (HAL_UART_Transmit(&huart2, rn2483_go_in_sleep, len_of_data1, 10) != HAL_OK)
6
    {
7
      Error_Handler();
8
    }
9
}

und damit wecke ich das Modul auf:
1
void wakeupRN2483(void)
2
{
3
    MX_USART2_UART_Init_28800();    // change to 28800 Baud for sending BREAK condition
4
5
    /********************** RN2483 wake up *********************/
6
    if (HAL_UART_Transmit(&huart2, byte080, 1, 10) != HAL_OK)    // low signal 226µs at least
7
    {
8
      Error_Handler();
9
    }
10
11
    MX_USART2_UART_Init();      // change to 57600 Baud
12
13
    if (HAL_UART_Transmit(&huart2, byte55, 1, 10) != HAL_OK)    // send 0x55
14
    {
15
      Error_Handler();
16
    }
17
}

und hier die beiden UART Inits:
1
static void MX_USART2_UART_Init(void)
2
{
3
  huart2.Instance = USART2;
4
  huart2.Init.BaudRate = 57600;
5
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
6
  huart2.Init.StopBits = UART_STOPBITS_1;
7
  huart2.Init.Parity = UART_PARITY_NONE;
8
  huart2.Init.Mode = UART_MODE_TX_RX;
9
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
10
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
11
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
12
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
13
  if (HAL_UART_Init(&huart2) != HAL_OK)
14
  {
15
    Error_Handler();
16
  }
17
}
18
19
static void MX_USART2_UART_Init_28800(void)
20
{
21
  huart2.Instance = USART2;
22
  huart2.Init.BaudRate = 28800;
23
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
24
  huart2.Init.StopBits = UART_STOPBITS_1;
25
  huart2.Init.Parity = UART_PARITY_NONE;
26
  huart2.Init.Mode = UART_MODE_TX_RX;
27
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
28
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
29
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
30
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
31
  if (HAL_UART_Init(&huart2) != HAL_OK)
32
  {
33
    Error_Handler();
34
  }
35
}

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Vielleicht musst du nach dem Senden ein bisschen Warten bevor du die 
Baudrate umstellst.

von M. G. (ixil96)


Lesenswert?

Ich denke ich habe den Fehler gefunden!

Nach der erneuten Initialisierung der UART für 57600 Baud
1
MX_USART2_UART_Init();      // change to 57600 Baud

fehlt diese Zeile
1
HAL_UART_Receive_IT(&huart2, rxData, 1);               // receive 1 byte in interrupt mode

Aber das werde ich erst morgen testen.

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.