Forum: Mikrocontroller und Digitale Elektronik Fehler in C Code ?


von Jochen K. (jogibear9988)


Lesenswert?

Hallo, Ich nutze den C Code von
Beitrag "Re: Software Profibus DP-Slave in C"

nun habe Ich das Problem das bei mir es einfach nicht funzt.

Dann habe Ich zum debuggen code unter default: eingefügt.

Nun ist mein Problem: Wenn Ich die pins am port A messe, dann liegt pin 
PA4 auf 5 Volt, alle anderen auf null. Doch in der Profibus.h ist sd1 
mit 0x10 definiert, daher hätte er doch gar nicht default springen 
dürfen, oder?

ich blicks nicht mehr...




code auschnitt:
(test ist eine globale variable)


  telegramm_type = uart_buffer[0];

  switch (telegramm_type)
  {
    case SD1: // Telegramm ohne Daten, max. 6 Byte

        if (uart_byte_cnt != 6) break;

        destination_add = uart_buffer[1];
        source_add      = uart_buffer[2];
        function_code   = uart_buffer[3];
        FCS_data        = uart_buffer[4];

        if (addmatch(destination_add)       == FALSE) break;
        if (checksum(&uart_buffer[1], 3) != FCS_data) break;

        process_data = TRUE;

        break;

    case SD2: // Telegramm mit variabler Datenlaenge

        if (uart_byte_cnt != uart_buffer[1] + 6) break;

        PDU_size        = uart_buffer[1];
        destination_add = uart_buffer[4];
        source_add      = uart_buffer[5];
        function_code   = uart_buffer[6];
        FCS_data        = uart_buffer[PDU_size + 4];

        if (addmatch(destination_add)              == FALSE) break;
        if (checksum(&uart_buffer[4], PDU_size) != FCS_data) break;

        process_data = TRUE;

        break;

    case SD3: // Telegramm mit 5 Byte Daten, max. 11 Byte

        if (uart_byte_cnt != 11) break;

        PDU_size        = 8;              // DA+SA+FC+Nutzdaten
        destination_add = uart_buffer[1];
        source_add      = uart_buffer[2];
        function_code   = uart_buffer[3];
        FCS_data        = uart_buffer[9];

        if (addmatch(destination_add)       == FALSE) break;
        if (checksum(&uart_buffer[1], 8) != FCS_data) break;

        process_data = TRUE;

        break;

    case SD4: // Token mit 3 Byte Daten

        if (uart_byte_cnt != 3) break;

        destination_add = uart_buffer[1];
        source_add      = uart_buffer[2];

        if (addmatch(destination_add)       == FALSE) break;

        break;

    default:
    if (test==0)
    {
      DDRA = 0b11111111;
      PORTA = uart_buffer[0]; //Clear all Outputs
    }
        break;

  }

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Jochen Kuehner schrieb:
> Doch in der Profibus.h ist sd1

Vielleicht eher SD1?

> mit 0x10 definiert, daher hätte er doch gar nicht default springen
> dürfen, oder?

Der ist sicher diesmal auch gar nicht dahin gesprungen.  Du hast
nämlich vergessen, bei allen gültigen Auswertungen dort noch den
irgendwann einmal ausgegebenen Wert wieder zu "löschen".

Das ist zumindest das, was meine Glaskugel anhand der spärlichen
Informationen so ausgespuckt hat...

von Jochen K. (jogibear9988)


Lesenswert?

Welchen Wert soll ich ablöschen?

Ich bin mittlerweile aber soweit das Ich nicht mal mehr damit:

unsigned long aa=0;

int main (void)
{
  DDRD |= (1<<PIN6);
  DDRD |= (1<<PIN5);
  PORTD |= (1<<PIN5);
  while(TRUE)
  {
    aa++;
    if (aa>100000000)
    {
      aa=0;
      PORTD ^= (1<<PIN6);
    }
  }
}

PD6 zum blinken bekomme (16Mhz Quartz, Atmega32)

aber PD5 und PD6 Leds gehen mit dem Code an!

Ich glaube Ich mache irgendwas Grundlegendes falsch...

von Hc Z. (mizch)


Lesenswert?

Das Programm ist ein Beispiel, wie Du es besser nicht machst.

Mit Optimierung kompiliert, wird es die Zählschleife wegoptimieren. 
Dann blinkt es schon, nur eben so schnell, dass Du es nur auf dem Scope 
sehen kannst.  Abhilfe: aa volatile machen.

Ohne Optimierung wird es ebenfalls blinken, aber dank der 100.000.000 
Inkremente so langsam, dass Du getrost eine oder mehrere Tassen Kaffee 
dazwischen trinken kannst, denn Du bekommst eine mindestens 3stellige 
(in Sekunden, grob geschätzt) Periode.

Schau Dir am besten den erzeugten Assembler-Code an für weitere 
Informationen.

von Jochen K. (jogibear9988)


Lesenswert?

Jo nun geht wenigstens das wieder....

Jetzt kann Ich mich wieder der ursprünglichen Problem widmen....

von Peter (Gast)


Lesenswert?

Hc Zimmerer schrieb:
> Mit Optimierung kompiliert, wird es die Zählschleife wegoptimieren.
> Dann blinkt es schon, nur eben so schnell, dass Du es nur auf dem Scope
> sehen kannst.  Abhilfe: aa volatile machen.

die schleife kann nicht wegoptimiert werden, weil dort eine 
portzuweisung enthalten ist, da darf er nicht optimieren weil es ja das 
verhalten ändern würde.

von Hc Z. (mizch)


Lesenswert?

Peter schrieb:
> die schleife kann nicht wegoptimiert werden, weil dort eine
> portzuweisung enthalten ist, da darf er nicht optimieren weil es ja das
> verhalten ändern würde.

Nein.  Das Inkrementieren von aa auf 100.000.000 ist die Schleife, 
danach erfolgt die Portzuweisung.  So kann die Logik nach der „as 
if“-Rule problemlos gesehen werden.  Erst NACH der Schleife erfolgt die 
Portzuweisung, und die wird ja nicht wegoptimiert, wohl aber das 
Hochzählen.

Wenn Du's nicht glaubst: schau den erzeugten Assemblercode an, wie ich 
bereits schrieb.

von Jochen K. (jogibear9988)


Lesenswert?

Gut Ich hab jetzt die Compiler Optimierungen aus.

Dachte nun Ich könnte im Programm eeprom_write_byte zum debugging 
verwenden.

Doch nichts da, es wurde nichts ins eprom geschrieben.

Doch selbst wenn ich meine Main so gestallte (wie unten), steht nur FF 
im Eprom (mit PonyProg ausgelesen).

Aber die LED blink...


int main (void)
{
  DDRD |= (1<<PIN6); //Port D Pin 6, Status LED Output
   eeprom_write_byte(0,'A');
   eeprom_write_byte(1,'B');

  while(TRUE)
  {
    aa++;
    if (aa>100000)
    {
      aa=0;
      PORTD ^= (1<<PIN6);
    }
  }
}

von Karl H. (kbuchegg)


Lesenswert?

Jochen Kuehner schrieb:
> Gut Ich hab jetzt die Compiler Optimierungen aus.

Falscher Weg.

Machs richtig und du hast weniger Probleme.
Es hat keinen Sinn wenn du dich um Programmierfehler dadurch 
rumschummelst, dass du den Optimierer ausschaltest.

von Jochen K. (jogibear9988)


Lesenswert?

Karl heinz Buchegger schrieb:
> Jochen Kuehner schrieb:
>> Gut Ich hab jetzt die Compiler Optimierungen aus.
>
> Falscher Weg.
>
> Machs richtig und du hast weniger Probleme.
> Es hat keinen Sinn wenn du dich um Programmierfehler dadurch
> rumschummelst, dass du den Optimierer ausschaltest.

Das bliken welches Ich über den Zaehler gemacht habe, fliegt ja auch 
wieder raus. Und die Optimierungen kommen dann wieder rein.

Bin grad nur erst auf der Suche nach meinem eigendlichen Problem, und 
dazu wollte Ich die Eprom Funktionen nutzem um mir debuginfos zu 
speichern, doch das klappt nicht...

von ... .. (docean) Benutzerseite


Lesenswert?

Jochen Kuehner schrieb:
> Ich die Eprom Funktionen nutzem um mir debuginfos zu
> speichern,

brrr viel zu langsam das schreiben, nimm lieber einen uart (wenn schon 
belgt einen per Software)

von Jochen K. (jogibear9988)


Lesenswert?

Die Geschwindigkeit ist mir gleich, fliegt ja eh alles wieder raus. Und 
habe nicht wirklich PINs frei. Ist den an Meinem benutzen der Eeprom 
Routinen was falsch, so das es nicht funktionieren sollte??

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.