Forum: Mikrocontroller und Digitale Elektronik Geisterhafter Quellcode


von S. K. (sinan)


Angehängte Dateien:

Lesenswert?

Guten Abend liebe Gemeinde,

seit einer Woche versuche ich einen Fehler auszubügeln, welchen ich beim 
besten Willen nicht finden kann. Ich hoffe ganz stark das Jemand hier im 
Forum ein ähnliches Problem hatte und mir seine Erfahrung mitteilen kann 
oder es findet jemand den Fehler, den ich schlicht übersehe.

Angaben:
Es geht um die Programmierung eines ATmega 328 (im Arduino UNO) welches 
mittels Atmel Studio 7.0 programmiert und per Avr ISP Mk2 geflasht wird.

Aufgabe:
Der ATmega328 wird verwendet um eine einstellbare Taktfrequenz am Chanel 
A des Timer_1 auszugeben. Hierbei soll nicht nur eine vorgegebene 
Frequenz eingestellt werden sondern auch Beschleunigungs/Abbremsrampen 
wenn eine Frequenzänderung vorgegeben wird(Frequenzänderungen sollen 
nicht schlagartig eintreten sondern sollen sich linear ändern).

Problem:
Die Oben beschriebene Aufgabe funktioniert soweit gut. Der µC macht was 
von ihm verlangt wird. Allerdings ist es so, dass das Programm 
merkwürdige Sachen macht. Im folgenden Quellcode ist ganz unten der 
Befehl
PORTD &= ~(0x10);

Wenn ich diesen Befehl auskommentiere, funktionierd die gesamte Funktion 
nicht mehr. Die Frequenz stellt sich auf die Zielfrequenz ein, ohne das 
eine Rampe durchlaufen wird. Der µC ignoriert sämtliche Befehle !!!

Das lustige ist das PD4 nichts mit der Funktion zu tun hat. Er sollte 
lediglich eine LED zum Leuchten bringen während die Funktion aktiv ist. 
Jetzt kann ich sie nicht mehr entfernen......

Nun gut... Dann lass ich diesen Befehl einfach drin könnten mache sagen. 
Allerdings gibt es noch andere Stellen, welche z.B aus einer 
While-Schleife nicht rauskommen obwohl sämtliche Bedingungen für den 
Austritt gegeben sind.

Bevor ich euch noch weiter zutexte möchte ich einfach mal fragen ob 
jemand eine Ähnliche Erfahrung gemacht hat. Besteht die Möglichkeit das 
Atmel Studio einen Bug hat ??
Ist evtl. der µC defekt ?
Ich habe zwar vorsichtshalber einen neuen bestellt aber bevor ich mein 
ganzes Equipment austausche wollte ich euch um Hilfe bitten.

Wie würded ihr diesen Fehler suchen ??
Ich komme mittlerweile nicht mehr weiter.

Vielen Dank

MfG



void set_timer1_CTC_freqchange (uint32_t freq, uint32_t acc)
{
  f_CLK_n1 = f_CLK_global;

  DDRD |= 0xF0;

  acc_ctrlreg |= 0x01;          // Freigabe für die Beschleunigung
  acc_ctrlreg |= 0x02;          // Freigabe für die Berechnung der 
nächsten Zwischenfrequenz

  if (freq >= f_CLK_global)  // Überprüfung ob eine Beschleunigung oder 
verzögerung gewünscht ist
  {
    acc_ctrlreg |= 0x08;  // Beschleunigung
    PORTD |=0x80;      // visualisierung des Beschleunigungsbeginns
  }
  else
  {
    acc_ctrlreg &= ~0x08;  // Verzögerung
    PORTD |=0x40;      // visualisierung des Verzögerungsbeginn
  }

  while((acc_ctrlreg & 0x01) == 0x01)    // Überprüfung der 
BEschleunigungsfreigabe
  {

    if ((acc_ctrlreg & 0x02) == 0x02)  // Überprüfung der 
Berechnungsfreigabe
    {

      /*********************************************************************** 
******************************************************************/

      if ((acc_ctrlreg & 0x08) == 0x08)        // Wenn Beschleunigung
      {
        f_CLK_n2 = (acc/f_CLK_n1)+f_CLK_n1;      // Berechnung des 
nächsten Schrittes
        f_CLK_n1 = f_CLK_n2;

        if (f_CLK_n2 >= freq)            // Falls die Zielfrequenz 
überschritten wird wird eingegriffen, das ist der letzte 
Inkrementierungsschritt. Siehe unten
        {
          f_CLK_n2 = freq;
          acc_ctrlreg &= ~(0x01);          // Deaktiviert den 
BEschleunigungsvorgang, Beschleunigung somit abgeschlossen, Schleife 
wird verlassen
        }
      }

      else                      // VErzögerung
      {
        f_CLK_n2 = -(acc/f_CLK_n1)+f_CLK_n1;    // Berechnung des 
nächsten Schrittes
        f_CLK_n1 = f_CLK_n2;

        if (f_CLK_n2 <= freq)            // Falls die Zielfrequenz 
überschritten wird wird eingegriffen, das ist der letzte 
Inkrementierungsschritt. Siehe unten
        {
          f_CLK_n2 = freq;
          acc_ctrlreg &= ~(0x01);          // Deaktiviert den 
BEschleunigungsvorgang, Beschleunigung somit abgeschlossen, Schleife 
wird verlassen
        }
      }
      /*********************************************************************** 
******************************************************************/

      if ((f_CLK_n2 - f_CLK_global) >= 1 || (f_CLK_n2 - f_CLK_global) <= 
-1)    // Überprüft ob eine Ganzzahldifferenz zwischen Ist- und 
Soll-Wert vorliegt
      {
        acc_ctrlreg |= 0x04;
      }

      acc_ctrlreg &= ~(0x02);                      // deaktivierung der 
Freigabe für die nächste Berechnung damit das Programm nicht zurück in 
die Berechnung springen kann
    }
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    PORTD &= ~(0x10);    // nicht zu erklärender Fehler. Wenn dieser 
Befehl gelöscht wird, funktioniert die Rampe nicht mehr

    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  }

  PORTD &= ~(0xC0);// Schaltet die visualisierungsled ab
}

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

S. K. schrieb:
> Wie würded ihr diesen Fehler suchen ??

Eine nicht-volatile Variable bzw. ein nicht-atomarer Zugriff darauf.

von S. K. (sinan)


Lesenswert?

Danke für die blitzschnelle Antwort.

Besteht die Möglichkeit das du die Vorgehensweise noch etwas 
ausformulierst. :)

Wäre dir sehr dankbar.

LG

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Nö, ist nur geraten.  Mehr ist bei dem Code-Schnüppel nicht drin.

von tux (Gast)


Lesenswert?

Zeig mal bitte den gesamten Code her. So kann man nur sehr wenig mit 
deinen Variablennamen anfangen.

Wo beschreibst du das OCR1A Register?

von Jens (Gast)


Lesenswert?

S. K. schrieb:
> Besteht die Möglichkeit das du die Vorgehensweise noch etwas
> ausformulierst. :)

Besteht die Möglichkeit, dass du erst mal deutsch lernst, dann C, und 
anschließend in 5-10 Jahren noch einmal fragst?

Wir wären dir sehr dankbar.

Jens

von Thomas E. (thomase)


Lesenswert?

S. K. schrieb:
> Besteht die Möglichkeit das Atmel Studio einen Bug hat ??
> Ist evtl. der µC defekt ?

Ja. Aber die Wahrscheinlichkeit, daß das Problem vor dem PC sitzt, ist 
um ein vielfaches größer. Also, das ganze Programm als *.c Datei im 
Anhang.
0 Errors, 0 Warnings.

von S. K. (sinan)


Angehängte Dateien:

Lesenswert?

Anbei der gesamte Quellcode.
Ist im Grunde eine Header-Datei.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

S. K. schrieb:
> Anbei der gesamte Quellcode.
> Ist im Grunde eine Header-Datei.

Der Quellcode ist eine Header-Datei?

Ich hatte bisher eine andere Vorstellung davon, was eine Header Datei 
ist.

von Stefan E. (sternst)


Lesenswert?

Fehlendes volatile für acc_ctrlreg.

von Thomas E. (thomase)


Lesenswert?

S. K. schrieb:
> Anbei der gesamte Quellcode.

Das ist doch kein Programm.

von S. K. (sinan)


Lesenswert?

Entschuldigt bitte meine mangelnde Kenntnis an Fachbegriffen.
Zu meiner Verteidigung. Bin nur ein Maschinenbauer.

Ich korrigiere.
Im obigen c-File findet ihr die Funktionssammlung und nicht den 
Quellcode.....

Bei der Gelegenheit bedanke ich mich schon mal bei den Helfern, die mich 
schnell auf den Lösungsweg mit dem volatile und dem atomaren 
Datenzugriff gebracht haben.

Ich habe es zwar noch nicht ausprobiert aber es hört sich sehr logisch 
an, dass es zu meinem Problem passen könnte nachdem was ich im Internet 
gelesen habe.

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.