mikrocontroller.net

Forum: Compiler & IDEs Zwei gleiche Codeschnipsel = volkommen verschiedene Ergebnisse


Autor: cerberus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sitze jetzt seit 6 Stunden vor diesem Problem und bin langsam am 
verzweifeln
Grundidee war das ein Timer mit 2 Compare-Interrupts 2 Motoren steuern 
kann.
Beide Routinen sind absolut identisch. Inzwischen habe ich sogar einen 
zweiten Timer spendiert, der exakt eingestellt ist, wie der erste.
Motor 1 läuft super / Motor 2 macht, was er will
SIGNAL(SIG_OUTPUT_COMPARE1B)
{  
if(checkbit(az_status,0)) 
  {
  if(checkbit(az_status,2) && OCR1B < 255) clearbit(PORTA,PA2);
  if(checkbit(az_status,3) && OCR1B < 255) clearbit(PORTA,PA3);  
  }
}

SIGNAL(SIG_OUTPUT_COMPARE3B)
{
if(checkbit(ho_status,0)) 
  {
  if(checkbit(ho_status,2) && OCR3B < 255) clearbit(PORTA,PA4);
  if(checkbit(ho_status,3) && OCR3B < 255) clearbit(PORTA,PA5);  
  }  
}

SIGNAL(SIG_OUTPUT_COMPARE1A)    
{  
static char az_sec;
if(checkbit(az_status,0)) 
  {
  if(!checkbit(az_status,7))
    {
    if (++az_sec % 130 == 0)
      {
      az_sec = 0;
      if(checkbit(az_status,1) && (OCR1B < 255)) OCR1B++;
      if(!checkbit(az_status,1) && (OCR1B > 0)) OCR1B--;
      }
    }
  else
    {
    clearbit(az_status,7);
    }        
  if(checkbit(az_status,2) && OCR1B > 0) setbit(PORTA,PA2);
  if(checkbit(az_status,3) && OCR1B > 0) setbit(PORTA,PA3);
  }  
}

SIGNAL(SIG_OUTPUT_COMPARE3A)    
{  
static char ho_sec;
if(checkbit(ho_status,0)) 
  {
  if(!checkbit(ho_status,7))
    {
    if (++ho_sec % 130 == 0)
      {
      ho_sec = 0;
      if(checkbit(ho_status,1) && (OCR3B < 255)) OCR3B++;
      if(!checkbit(ho_status,1) && (OCR3B > 0)) OCR3B--;
      }
    }
  else
    {
    clearbit(ho_status,7);
    }        
  if(checkbit(ho_status,2) && OCR3B > 0) setbit(PORTA,PA4);
  if(checkbit(ho_status,3) && OCR3B > 0) setbit(PORTA,PA5);
  }  
}

void az_freigabe (void)
{
setbit(az_status,1);  // Direction-Bit setzen
setbit(az_status,0);// PWM - Freigabebit setzen
setbit(TIMSK1,OCIE1B);  // interrupt freigeben
setbit(TIMSK1,OCIE1A);
}

void ho_freigabe (void)
{
setbit(ho_status,1);  // Direction-Bit setzen
setbit(ho_status,0);// PWM - Freigabebit setzen
setbit(TIMSK3,OCIE3B);  // interrupt freigeben
setbit(TIMSK3,OCIE3A);
}

und im Main

if((!checkbit(motorsollbyte,2) && !checkbit(motorsollbyte,3)) || (checkbit(motorsollbyte,2) && checkbit(motorsollbyte,3))) // ho_stop
  if(checkbit(ho_status,1))
  clearbit(ho_status,1);
          
          
if(checkbit(motorsollbyte,2) && !checkbit(motorsollbyte,3))  //linkslauf
  {
  if(OCR3B == 0)    // zustand ist stop /Motor anfahren
    {
    setbit(ho_status,2);    // Port setzen
    clearbit(ho_status,3);    // Port setzen
    ho_freigabe();
    }
  else          //Zustand ist nicht stop
    {
    if(TCNT3 < OCR3B && checkbit(PINA,PA4) && !checkbit(ho_status,1)) // Wenn drehrichtung identisch aber direktion bit falsch / direction bit setzen
      setbit(ho_status,1);
    if(TCNT3 < OCR3B && checkbit(PINA,PA5) && checkbit(ho_status,1))// wenn Drehrichtung anders herum und direktion bit gesetzt / direction Bit löschen.
    clearbit(ho_status,1);
    }
  }
// wie vor, jedoch für Sollbyte 3
      
if(checkbit(motorsollbyte,3) && !checkbit(motorsollbyte,2))  //rechtslauf
  {
  if(OCR3B == 0)      // zustand ist stop /Motor anfahren
    {
    setbit(ho_status,3);    // Port setzen
    clearbit(ho_status,2);    // Port setzen
    ho_freigabe();
    }
  else          //Zustand ist nicht stop
    {
    if(TCNT3 < OCR3B && checkbit(PINA,PA5) && !checkbit(ho_status,1)) // Wenn drehrichtung identisch aber direktion bit falsch / direction bit setzen
    setbit(ho_status,1);
    if(TCNT3 < OCR3B && checkbit(PINA,PA4) && checkbit(ho_status,1))// wenn Drehrichtung anders herum und direktion bit gesetzt / direction Bit löschen.
    clearbit(ho_status,1);
    }
  }
if((!checkbit(motorsollbyte,0) && !checkbit(motorsollbyte,1)) || (checkbit(motorsollbyte,0) && checkbit(motorsollbyte,1))) // az_stop
  if(checkbit(az_status,1))
  clearbit(az_status,1);
          
if(checkbit(motorsollbyte,0) && !checkbit(motorsollbyte,1))  //linkslauf
  {
  if(OCR1B == 0)      // zustand ist stop /Motor anfahren
    {
    setbit(az_status,2);    // Port setzen
    clearbit(az_status,3);    // Port setzen
    az_freigabe();
    }
  else          //Zustand ist nicht stop
    {
    if(TCNT1 < OCR1B && checkbit(PINA,PA2) && !checkbit(az_status,1)) // Wenn drehrichtung identisch aber direktion bit falsch / direction bit setzen
    setbit(az_status,1);
    if(TCNT1 < OCR1B && checkbit(PINA,PA3) && checkbit(az_status,1))// wenn Drehrichtung anders herum und direktion bit gesetzt / direction Bit löschen.
    clearbit(az_status,1);
    }
  }
// wie vor, jedoch für Sollbyte 1
if(checkbit(motorsollbyte,1) && !checkbit(motorsollbyte,0))  //rechtslauf
  {
  if(OCR1B == 0)      // zustand ist stop /Motor anfahren
    {
    setbit(az_status,3);    // Port setzen
    clearbit(az_status,2);    // Port setzen
    az_freigabe();
    }
  else          //Zustand ist nicht stop
    {
    if(TCNT1 < OCR1B && checkbit(PINA,PA3) && !checkbit(az_status,1)) // Wenn drehrichtung identisch aber direktion bit falsch / direction bit setzen
    setbit(az_status,1);
    if(TCNT1 < OCR1B && checkbit(PINA,PA2) && checkbit(az_status,1))// wenn Drehrichtung anders herum und direktion bit gesetzt / direction Bit löschen.
    clearbit(az_status,1);
    }
  }
Während der AZ-Motor tut, wie er soll kann ich den ho-Motor ein mal 
ansprechen fährt er links herum und ich stoppe während des Hochfahrens, 
schaltet er ein. Danach kann ich mit dem Sollbyte machen was ich will, 
interessiert nicht mehr. Az funktioniert weiterhin ungestört. Fahre ich 
ihn  rechts herum an fährt er hoch und stoppt abrupt am Ende der PWM. 
Dabei macht es keinen Unterschied, ob der Timer nun OCR3B ist oder 
OCR1C. In Beiden Fällen die gleiche Grütze.
Nur der Vollständigkeit halber hier noch den Sollbyte-Manipulator
else if (strncmp_P(auswertstring,PSTR("east"),4)==0)    {volatile extern unsigned char motorsollbyte;   setbit(motorsollbyte,0); clearbit(motorsollbyte,1); ausgabefehler = 0;}
else if (strncmp_P(auswertstring,PSTR("west"),4)==0)    {volatile extern unsigned char motorsollbyte;   setbit(motorsollbyte,1); clearbit(motorsollbyte,0); ausgabefehler = 0;}
else if (strncmp_P(auswertstring,PSTR("stop"),4)==0)    {volatile extern unsigned char motorsollbyte;   motorsollbyte = 0x00; ausgabefehler = 0;}
else if (strncmp_P(auswertstring,PSTR("up"),2)==0)    {volatile extern unsigned char motorsollbyte;   setbit(motorsollbyte,2); clearbit(motorsollbyte,3);ausgabefehler = 0;}
else if (strncmp_P(auswertstring,PSTR("down"),4)==0)   {volatile extern unsigned char motorsollbyte;   setbit(motorsollbyte,3); clearbit(motorsollbyte,2);ausgabefehler = 0;}
Ich bin gerade ausgesprochen ratlos ...

Autor: cerberus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nach 10 Stunden und nac
h dem ich das Programm nun 5 mal neu geschrieben habe habe ich das 
Problem gefunden.

Das Programm funktioniert wenn die Variable nicht ho_status heißt. 
(jetzt heißt sie ho_statusbyte.
Ich habe zur Sicherheit alle meine Dateien nach dem Eintrag ho_status 
durchsuchen lassen und kann jetzt sagen, dass bei mir keine zweite 
Variable so heißt.

Ich würde mich etwas besser fühlen, wenn ich wüsste warum die Variable 
nicht ho_status heissen darf.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie und wo waren/sind die Variabeln deklariert?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei solchen Codeschnipseln gibt es hier immer große Jubelschreie:

Juhu, wir dürfen wieder das große Rätselraten beginnen.

Ooch wie schön, erstmal den unbekannten Compiler rauskriegen, die 
unbekannte MC-Familie und den unbekannten MC-Chip.

Was ist wo und wie deklariert, was ist sonst noch so im Programm.

Ooch wie schön, nen Haufen unbekannter Unterfunktionen und Macros.

Ooch wie schön, der Compiler bricht nach 1000 Errors ab, weil ihm so 
viele wichtige Informationen fehlen.


Nicht so große Rätselfreunde könnten sich daher leicht hinreißen lassen 
zu:
Solche Hellseher-sein-müssen-Postings sind voll forn Ar***.


Peter

Autor: cerberus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Juhu, wir dürfen wieder das große Rätselraten beginnen.
> Ooch wie schön, erstmal den unbekannten Compiler rauskriegen,
avr-gcc (GCC) 4.1.2 (WinAVR 20070525) ist meines wissens nicht soo 
unbekannt
> dieunbekannte MC-Familie
Es ist mir neu das Variablennamen aus C-Programmen im Programmspeicher 
der uC Familie abgelegt werden.
> und den unbekannten  MC-Chip.
dito
> Was ist wo und wie deklariert, was ist sonst noch so im Programm.
Nichts was nicht funktionieren würde ...
> Ooch wie schön, nen Haufen unbekannter Unterfunktionen und Macros.
Oh in der Tat! Ganze 3 Makros und die sind auch noch hier aus dem 
Tutorial!
> Ooch wie schön, der Compiler bricht nach 1000 Errors ab, weil ihm so
> viele wichtige Informationen fehlen.
Welche Errors? Wenn ich wenigstens nur ein einziges "warning" hätte gäbe 
es zumindest einen Anhaltspunkt.

> Wie und wo waren/sind die Variabeln deklariert?
volatile unsigned char    als globale Variable im main.c

@Peter Dannegger
Nur für mich zum Verständnis:
Wie bekommt man eigentlich ein, in den uC-Chip ladbares hex-file anhand 
dessen man die Funktion oder Fehlfunktion des Programmes testen kann, 
wenn der Compiler nach nach 1000 Errors abbricht, weil ihm so viele 
wichtige Informationen fehlen?

Autor: Dirk Dörr (dirkd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> avr-gcc (GCC) 4.1.2 (WinAVR 20070525) ist meines wissens nicht soo
> unbekannt

Davon steht aber in Deinem ersten Posting nichts. Und darum geht es.

> Ganze 3 Makros und die sind auch noch hier aus dem Tutorial!

Dann schreib's dabei. Das Forum wird auch von Leuten genutzt die das 
Tutorial nicht kennen (Welches eigentlich, gibt sicherlich mehrere hier) 
und das nicht sofort sehen.

In dem Controller können auch Fehler sein, die dazu führen, daß Dein 
Interrupt nicht korrekt ausgeführt wird. Kann man natürlich nur 
beurteilen wenn man weiß welchen Controller Du verwendest.

Der Compiler könnte Fehler enthalten. Vielleicht ist WinAVR20070525 kein 
guter Stand.

Alles Gründe warum diese Infos wichtig sein könnten.

Wenn Du das ganze Projekt posten würdest könnte man dem Fehler 
vielleicht finden. Nur mit dem Code-Schnipsel ist es recht 
unwahrscheinlich.

--

    Dirk

Autor: cerberus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist sogar recht unwahrscheinlich dass jemand den Fehler finden würde, 
wenn ich das ganze Projekt posten würde, denn es läuft auf einem Mega88 
ganz problemlos, obschon ich dort jetzt auch die ho_status-Variable 
sicherheitshalber umbenannt habe, es sei denn er baut auch die komplette 
Hardware nach, was wohl als Hilfestellung unzumutbar ist.
Der Interrupt wird ja korrekt ausgeführt, der Inhalt einer der beiden 
Variablen ist lediglich fehlerhaft, was keinen Sinn macht, wenn beide 
genau gleich bearbeitet werden.
Dabei spielt es keine Rolle ob die Variablen in einem oder in zwei 
unterschiedlichen Interrupts abgearbeitet werden. Es macht aber einen 
Unterschied, ob die Variable ho_status oder ho_statusbyte heißt. Das hat 
einfach nichts mit uC-Familie, uC-Typ noch mit Makros usw zu tun, 
allenfalls könnte es mit dem Compiler zu tun haben.
> Davon steht aber in Deinem ersten Posting nichts. Und darum geht es.
Nein, geht es nicht, es sei denn Herr Dannegger hätte an seinem Post 7 
Stunden und 47 Minuten gearbeitet ...

Autor: Dirk Dörr (dirkd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> allenfalls könnte es mit dem Compiler zu tun haben.

Und auch den hast Du erst genannt, als sich Peter beschwert hat.

Ich wollte Dich auch nur darauf hinweisen, daß Du einfach zu wenig 
Informationen in Deinem Posting hattest.

Auch wenn natürlich Deine weiteren Postings darauf hindeuten, daß das 
Problem nichts mit der Hardware zu tun hat, ging es Peter wohl auch um's 
Prinzip.


> Es ist sogar recht unwahrscheinlich dass jemand den Fehler finden würde,
> wenn ich das ganze Projekt posten würde [...] es sei denn er baut auch die
> kompletteHardware nach

Du sagst doch selbst, daß Du nicht glaubst, daß die HW schuld ist. Wozu 
also nachbauen?

Mit dem ganzen Projekt könnte man das auch mal durchbauen und Hex und 
ASM-Code der Variante mit ho_status und der mit ho_statusbyte 
vergleichen.

Wenn der Name wirklich einen Unterschied ausmachen soll dann müsste auch 
der ASM-Code bzw. das generierte Bin/Hex-File unterschiedlich sein.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
cerberus wrote:

>> Davon steht aber in Deinem ersten Posting nichts. Und darum geht es.
> Nein, geht es nicht, es sei denn Herr Dannegger hätte an seinem Post 7
> Stunden und 47 Minuten gearbeitet ...

Was meinst Du mit den 7 Stunden und 47 Minuten ?

Daß es überhaupt um einen AVR geht, hast Du erst 3 Tage nach meinem Post 
rausgerückt, im Post vom 15.06.2008 12:31.


Ob Dein Problem mit der Namensgebung zusammenhängt oder mit anderen 
gleichzeitig gemachten Änderungen (auch Compileroptionen), kann man 
nicht beurteilen.
Vielleicht hast Du auch irgendwelche Macros definiert, die gleich 
heißen.
Oder nicht sichtbare Zeichen in den Codezeilen.
Oder ....

Mit dem gesamten Code, der GCC-Version und dem Makefile hätte man das 
aber leicht herausfinden können.


Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
cerberus wrote:

> Oh in der Tat! Ganze 3 Makros und die sind auch noch hier aus dem
> Tutorial!

Na aber hallo, gehts Dir noch gut?
Du erwartest also allen Ernstes, daß jeder sämtlichen Code im Forum 
auswendig kennt?

Ich hab den AVR 1997 kennen gelernt, da war hier nichts mit Tutorial.
Ich hab auch nicht die Zeit, dann später etwas zu lesen, worüber ich 
schon längst Bescheid weiß.


> Welche Errors? Wenn ich wenigstens nur ein einziges "warning" hätte gäbe
> es zumindest einen Anhaltspunkt.

Unbekannte Macros erzeugen haufenweise Folgefehler, probiers aus.


> volatile unsigned char    als globale Variable im main.c

Diese Zeile gibt auch nur Compilerfehler.
Ist es denn so schwer, den exakten Quelltext zu posten?


> Wie bekommt man eigentlich ein, in den uC-Chip ladbares hex-file anhand
> dessen man die Funktion oder Fehlfunktion des Programmes testen kann,
> wenn der Compiler nach nach 1000 Errors abbricht, weil ihm so viele
> wichtige Informationen fehlen?

Na eben.
Ich konnte das ja nicht und das war meine Rede.

Daß Du es konntest, weil Du alle fehlenden Informationen hattest, hilft 
mir nicht einen Pups beim Lösen Deines Problems.


Peter

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.