Forum: Mikrocontroller und Digitale Elektronik Senden über serielle Schnittstelle funktioniert teilweise nicht


von Henning (Gast)


Lesenswert?

Hallo Community,

hier ein (für mich jedenfalls) recht kurioses Problem, bei dem ich Eure 
Hilfe benötige!

Ich hole erst mal aus:

Ich benutze einen µC (deRFmega128 von DresdenElektronik), das AVR Studio 
und den MAC Layer von Atmel in der Version 2.4.2. Hier speziell die PAL 
- API.
Diese API stellt eine Funktion bereit, mit der Daten über die Serielle 
Schnittstelle empfangen und gesendet werden können. Das Empfangen 
funktioniert tadellos. Von HTerm gesendete Daten können vom µC erkannt 
und verarbeitet werden. Nun zum kuriosen Teil des Ganzen: Das Senden an 
den PC funktioniert nur teilweise.

Rufe ich die Funktion zum Senden von Daten zum Beispiel aus einer Timer 
- Routine oder einer undendlichen While - Schleife aus auf, so kann ich 
die Daten auch wunderbar im HTerm sehen. Rufe ich die Funktion jedoch 
aus einem switch - case oder einem if - Konstrukt heraus auf, so 
passiert gar nichts. Auch Debugging hat mich hier nicht weitergebracht. 
Ich habe die Funktion schon einmal komplett durchgesteppt und mir alles 
genau angeschaut, aber ich kann einfach nicht entdecken wo dort etwas 
verloren geht. Als Rückgabewert gibt die Funktion die tatsächlich 
übermittelten Bytes zurück. Dieser Rückgabewert entspricht auch 
tatsächlich der Anzahl an Bytes, die ich übertragen will.

Ich habe schon vermutet, dass der Puffer vielleicht nicht richtig 
geleert wird, oder sowas ähnliches, aber wenn ich die Daten mit einem 
Timer alle paar Sekunden zum Beispiel losschicke, dann kommen sie nicht 
stoßweise an, sondern immer schön einzeln, Byte für Byte...

Der zweite Gedanke der mir kam, war dass vielleicht irgendwelche 
Interrupts etwas kaputt machen. Also habe ich die Funktion in cli() und 
sei() "eingepackt". Leider mit dem gleichen Ergebnis.

Auch Delays konnten das Problem nicht beheben. Den Tipp hatte mir ein 
Arbeitskollege gegeben.

Der Code, den ich benutze ist ein adaptiertes Beispiel von Atmel, dass 
sich Wireless UART nennt. Ich habe den entsprechenden Teil des Codes mal 
angehängt:
1
static void app_task(void){
2
  uint8_t number_of_bytes_received = 0;
3
  uint8_t opcode[2] = {0x00, 0x00};
4
  char r_byte;
5
  uint8_t return_value = (uint8_t)('r');
6
7
  /* Überprüfen ob Daten über die serielle Schnittstelle empfangen worden sind */
8
  number_of_bytes_received = pal_sio_rx(SIO_CHANNEL, sio_rx_data, MAX_APP_DATA_LENGTH);
9
10
  /* Wenn Daten empfangen worden sind, dann decodieren */
11
  if(number_of_bytes_received){
12
    r_byte = (char)sio_rx_data[0];
13
    
14
    switch(r_byte){
15
      /*Hier werden vorher noch ein paar anderen Cases abgearbeitet*/
16
      case 'c':
17
        /* bevor wir dem PC sigalisieren, dass wir fertig sind, halten wir die ActiveNode an */
18
        opcode[0] = TRANSMITTER_OFF;
19
      
20
        /* PC signalisieren, dass wir fertig sind */
21
        pal_sio_tx(SIO_CHANNEL, &return_value, sizeof(return_value));
22
        break;
23
    }
24
  }
25
}

Hat vielleicht jemand eine Ahnung, wie das zustande kommt? Ich habe 
wirklich schon ne Menge versucht, aber nichts hat mich weitergebracht. 
Auch google war nichts in der Richtung bekannt.

Mit freundlichen Grüßen,
Henning

von Stefan B. (stefan) Benutzerseite


Lesenswert?

IMHO ist die gezeigte Funktion ist nur fürs Empfangen zuständig.

Senden tut die Funktion lediglich einen festen Rückgabewert ('r') und 
das auch nur in einem bestimmten Fall (hier: (number_of_bytes_received 
!= 0) && ((char)sio_rx_data[0] == 'c')).

"Als Rückgabewert gibt die Funktion die tatsächlich übermittelten Bytes 
zurück." sehe ich nicht. Die Funktion selbst hat keinen Rückgabewert 
(static void app_task(void); Prototyp).

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.