Forum: Compiler & IDEs Funktion bekommt keinen Wert übergeben


von Kai L. (kcl_93)


Lesenswert?

Hallo Leute,

ich bin gerade dabei ein Programm für einen ATmega644 zu schreiben, das 
unter anderem über UART Daten an den PC senden soll. Dabei werden immer 
3 Bytes als größeres Frame gesehen und versendet. Diese 3 Bytes 
enthalten eine 16Bit-Variable, einen 5Bit langen Befehl und 3 Bits zur 
Synchronisation.
Zu diesem Zweck habe ich mir eine Funktion geschrieben, die mir diese 3 
Bytes aus dem Befehl und den Daten zusammenbauen soll:

1
void daten_senden(uint8_t befehl, uint16_t daten)
2
{
3
  char frame[3];
4
  /*
5
            Aufbau: Byte    Bits    Funktion
6
                    1       1       Identifikator für erstes Byte (muss 1 sein)
7
                            2-6     Befehlsbits (1-31)
8
                            7-8     Datenbits 1-2
9
                    2       1       Identifikator für Daten-Bytes (muss 0 sein)
10
                            2-8     Datenbits 3-9
11
                    3       1       Identifikator für Daten-Bytes (muss 0 sein)
12
                            2-8     Datenbits 10-16
13
            */
14
  frame[0] = 0b10000000;
15
  frame[0] += (befehl<<2);
16
  frame[0] += (uint8_t)(daten>>14);
17
  frame[1] = (uint8_t)(daten>>7);
18
  daten = daten<<9;
19
  frame[2] = (uint8_t)(daten>>9);
20
  uart_putc(frame[0]);
21
  uart_putc(frame[1]);
22
  uart_putc(frame[2]);
23
}

Diese Funktion wird im Hauptprogramm aufgerufen, wobei der Befehl als 
Konstante übergeben wird:

1
#define PING_RET   2
2
3
//...
4
5
int maint()
6
{
7
   //...
8
   daten_senden(PING_RET, 1);
9
   //...
10
}

Mein Problem ist, dass egal was ich beim Aufruf der Funktion als 
Parameter übergeben möchte immer nur (0, 0) ankommt. Ich habe auch schon 
versuch die Konstanten vorher in einer Variable zu speichern und die 
dann zu übergeben aber das hat auch nichts geändert.
Könnt ihr mir sagen, was ich da falsch gemacht habe???

gruß,

Kai L.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Das Problem liegt wohl in den //... Stellen

von Kai L. (kcl_93)


Angehängte Dateien:

Lesenswert?

Hier einmal der ganze Code.

von Karl H. (kbuchegg)


Lesenswert?

Humpf.
Das ist jetzt im Gegenzug wieder relativ viel Tobak auf einmal.

Kannst du keinen Mittelweg machen?
Ein EINFACHES Testprogramm, welches nur 1 Befehl enthält und den sendet 
und du an der Gegenstelle dir ansiehst, was ankommt?
Wer ist eigentlich die Gegenstelle? Kann es sein, dass dein Problem von 
dort kommt bzw. dort entsteht?

Hintergrund: Ich finde es immer wieder recht faszinierend, dass da 
manchmal Code-Monster auftauchen, die scheinbar alle von einer gewissen 
Basisfunktionalität abhängen und es so aussieht, als sei diese 
Basisfunktionalität nie einzeln getestet und debuggt worden. Sondern im 
Gegenzug ist man davon ausgegangen, dass das schon funktionieren wird 
und dann hat man halt erst mal das Code-Monster produziert. Mit dem 
Endeffekt, dass nichts funktioniert und man nicht weiß, wo man mit der 
Fehlersuche anfangen soll.
Eine derartige Entwicklungsstrategie ist keine gute Idee.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Kann das mal wer kontrollieren?
1
void daten_empfangen()
2
{
3
  uint16_t empfangen;
4
  
5
  empfangen = uart_getc();
6
  if(!(empfangen & 0xff00))  //Prüfen ob Byte erfolgreich gelesen wurde
7
  {
8
    if(byte_empfangen == 0 && !(empfangen & 0x0080)) //Prüfen ob Befehlsbit korrekt gesetzt gesetzt ist
9
    {
10
      daten_senden(ERROR, 0);  //Error-Nachricht senden
11
      return; //Byte wird verworfen bis das nächste gültige Byte kommt
12
    }
13
    else if(empfangen & 0x0080)
14
    {
15
      daten_senden(ERROR, FRAME_ERROR);  //Error-Nachricht senden
16
      return; //Byte wird verworfen bis das nächste gültige Byte kommt
17
    }
18
19
....

Im Kontext gesehen, müsste meiner Meinung nach dieses immer zu einem 
gemeldeten Fehler führen, solange byte_empfangen 0 ist. Da es von Anfang 
an 0 ist, kommt er da aber auch nie heraus. byte_empfangen kann nie 
größer werden, denn egal ob das 7. Bit gesetzt ist oder nicht, es mündet 
immer in einem der beiden Zweige, in denen ein Fehler gesendet wird und 
ein vorzeitiger Ausstieg gemacht wird.

Da FRAME_ERROR aber auf 0 #defined ist, ist er in der Situation, dass 
immer ein (0, 0) zurück geschickt wird, egal was die Gegenstelle als 
Kommando sendet. Womit die Ausgangsfrage erklärbar wäre. Nur halt mit 
einer ganz anderen Begründung, als der nach der gefragt wurde.

Mein Fazit: viel zu viel Code auf einmal geschrieben, ohne die 
grundlegenden Basisdinge, wie zb hier die UART Protokollkommunikation 
ausreichend und für sich alleine getestet zu haben. Auf dem AVR keine 
vernünftigen Möglichkeiten für Test-Ausgaben zu haben (und seien es nur 
ein paar LED), tut dann noch sein übriges.

: Bearbeitet durch User
von Kai L. (kcl_93)


Lesenswert?

Du hast Recht, was deine Vermutung mit der Empfangen-Funktion betrifft. 
Wenn ich die Abfrage nach dem 7. Bit korrigiere funktioniert es.
Ich hatte die Basisfunktionalität in Auszügen bereits getestet, indem 
ich Daten gesendet und mit Teraterm ausgewertet hab. Nur die 
Empfangsfunktion hatte ich ausgelassen, bis ich mit dem C#-Programm am 
PC weiter gekommen bin. Dabei hab ich auch parallel an dem Programm für 
den uC weiter gearbeitet, wenn mir danach war ;)
Jetzt hab ich folglich zurecht die Rechnung für dieses unsystematische 
Vorgehen bekommen. Vielen Dank für deine Mühen! :)

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.