mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Fehler in C Code ?


Autor: Jochen Kuehner (jogibear9988)
Datum:

Bewertung
0 lesenswert
nicht 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;

  }

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Jochen Kuehner (jogibear9988)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jochen Kuehner (jogibear9988)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo nun geht wenigstens das wieder....

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

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jochen Kuehner (jogibear9988)
Datum:

Bewertung
0 lesenswert
nicht 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);
    }
  }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jochen Kuehner (jogibear9988)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Jochen Kuehner (jogibear9988)
Datum:

Bewertung
0 lesenswert
nicht 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??

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.