Forum: Mikrocontroller und Digitale Elektronik Debug-Problem in AVR-Studio 5


von Ernst B. (puravida)


Angehängte Dateien:

Lesenswert?

Hi!

Ich habe beim Debuggen im AVR-Studio 5 einige Probleme.

Das c-File habe ich als Datei angehängt, Controller ist ein ATmega8.

Wenn man das Programm durchgeht dann fällt als erstes folgendes auf: Der 
gelbe Pfeil trifft auf sei() und springt danach sofort in die erste ( 
die für den TOP-Wert) Interruptroutine. Danach geht es weiter mit der 
zweiten Interruptroutine ISR(TIMER1_COMPB_vect), er arbeitet da drinnen 
alles brav ab aber dann springt er aus der Interruptroutine raus an den 
Anfang meiner MAIN-Funktion. Was natürlich nicht sein darf weil da 
nochmals alle Daten eingelesen werden und der ganze Ablauf nimmer 
stimmt.

Wo liegt da der Fehler? Wahrscheinlich der Typ vor dem Monitor, oder? 
g

Was auch auffällt, der Rechner springt nie in die Endlosschleife in der 
Main-Routine. Aber selbst wenn ich das sei() in die Endlosschleife 
schreibe springt er nach der ISR(TIMER1_COMPB_vect) an den Anfang von 
Main.

Könnt Ihr Euch das bitte mal anschauen wo da der Hund ist?

Danke!

LG
Ernst

PS: Liebevolle Tipps zum Code - bin ja noch ein blutiger Anfänger - sind 
immer willkommen. :-))

von Frank L. (franklink)


Lesenswert?

Hallo,
als erstes, fällt mir auf, dass Du auf einen Servo mit der Nummer 9 
zugreifst und damit ausserhalb Deiner Array-Grenzen arbeitest.

Die Nebeneffekt beim Überschreiben der Speicherstellen, kannst Du Dir 
vielleicht ausmalen.

Gruß
Frank

von Frank L. (franklink)


Lesenswert?

Schau Dir auch nochmal diesen Teil an:
1
if (ServoNr==9)
2
{
3
   PORTC &= ~(servos_closed[ServoNr].port);
4
   ServoNr=0;
5
}
6
while (servos_closed[ServoNr].when-servos_closed[ServoNr-1].when<=3)

Wenn die ServerNr == 0 ist, dann greifst Du mit ServerNr-1 wieder auf 
Werte zurück, die ausserhalb des Arrays liegen. Dasselbe gilt natürlich 
auch im Fall von ServerNr == 9.

Gruß
Frank

von Ernst B. (puravida)


Lesenswert?

Frank Link schrieb:
> Hallo,
> als erstes, fällt mir auf, dass Du auf einen Servo mit der Nummer 9
> zugreifst und damit ausserhalb Deiner Array-Grenzen arbeitest.
>
> Die Nebeneffekt beim Überschreiben der Speicherstellen, kannst Du Dir
> vielleicht ausmalen.

Hi Frank!

f*ck! 10000 mal steht es in den C-Büchern... "Achtung, Array werden zwar 
mit Zahl X definiert aber das Array beginnt dann bei 0"

Und prompt mache ich auch den Fehler.

Danke Dir!

Jetzt muß ich schauen... in der ISR mache ich den Fehler auf jeden Fall. 
Aber ich glaube auch in der Sortierroutine Bubble. Bzw. ziemlich sicher.

LG
Ernst

von Frank L. (franklink)


Lesenswert?

In Deinem Bubble, greifst Du auf jeden Fall ausserhalb der Grenzen zu. 
Desweiteren benötigst Du für temp eigentlich nur einen temporären Zeiger 
und musst die Struktur nicht mit malloc erzeugen. Funktionen wie malloc 
sollte man auf einem Mikrocontroller vermeiden.

Gruß
Frank

von Ernst B. (puravida)


Angehängte Dateien:

Lesenswert?

Danke Frank!

Ich habe das in der ISR Routine umgestellt. Aber das allein war es ja 
nicht und weil ich mich mit Zeigern und der Übergabe an die Funktion 
noch nicht wirklich auskenne habe ich jetzt eine Sortierfunktion 
geschrieben die zwar nicht schön ist aber stimmen sollte.

Es wird auch brav sortiert, DDRD auf Ausgang geschaltet aber sobald ich 
auf sei(); stosse springt es an den Anfang von Main und meine 
Struct-Werte die ich überwache springen allesamt auf 0. Zu dem Zeitpunkt 
wird noch gar keine ISR aufgerufen die ja vorhin (auch) fehlerhaft war. 
(und jetzt hoffentlich paßt).

Woran liegt das?

ratlose Grüße
Ernst

von Frank L. (franklink)


Lesenswert?

wo ist denn Dein Overflow-Interrupt Routine?

Du gibst mit:
1
TIMSK |= (1<<TOIE1 | 1<<OCIE1A | 1<< OCIE1B)

die beiden Compare-ISR frei und mit TOIE1 den Overflow, hast aber keine 
ISR dafür...

Gruß
Frank

von Frank L. (franklink)


Lesenswert?

Ich hab gerade gesehen, dass Du den Aufruf sogar drin hattest und nur 
auskommentiert hast, mach entwender das TOIE1 raus oder kommentier die 
ISR weider ein.

Gruß
Frank

von Frank L. (franklink)


Lesenswert?

Hier ist auch noch ein kleiner Denkfehler:
1
while (ServoNr > 0 && servos_closed[ServoNr].when-servos_closed[ServoNr-1].when<=3)
2
    {
3
      
4
      // TODO: Warten
5
      if (ServoNr<=7)
6
      {
7
        PORTD &= ~(servos_closed[ServoNr].port);
8
      } 
9
      else
10
      {
11
        PORTC &= ~(servos_closed[ServoNr].port);
12
        ServoNr = 0;
13
      }
14
      if (ServoNr > 0)
15
      {
16
        ServoNr++;
17
      }
18
      
19
    }
20
    OCR1B = servos_closed[ServoNr].when;

Was passiert, wenn Deine zweite Bedingung nie erfüllt wird?

Gruß
Frank

von Frank L. (franklink)


Lesenswert?

Je länger ich mir den Code ansehe, desto weniger verstehe ich, was Du 
eigentlich bezwecken möchtest, könntest Du mir das mal näher erklären?

Gruß
Frank

von Ernst B. (puravida)


Angehängte Dateien:

Lesenswert?

Frank Link schrieb:
> Je länger ich mir den Code ansehe, desto weniger verstehe ich, was Du
> eigentlich bezwecken möchtest, könntest Du mir das mal näher erklären?
>
> Gruß
> Frank

Danke Frank für Deine Mühe.

In kurzen Worten was es mal können soll:

An den neun Pins hängen neun Servos (Servo[0] - Servo[8]). Über den 
Timer mache oder möchte ich die PWM für die Servos machen.

Beim ersten mal Erreichen des OCR1A Wertes gehen alle Ausgänge auf High. 
Dann wird OCR1B mit dem Wert gesetzt wann der erste Servopin wieder auf 
LOW geht. Deswegen muß ich die Werte sortieren. (Die Liste sind nur 
Beispielwerte, irgendwann mal soll das aus dem EEProm gelesen werden)

Sobald der OCR1B Wert erreicht ist wird die ISR aufgerufen, der Pin geht 
auf Low. Und OCR1B wird mit dem nächsten Wert gesetzt. Und so schalten 
sie schön brav der Reihe nach aus.

Die while-Schleife ist drinnen weil es ja sein könnte, daß z. Bsb. Servo 
1 und Servo 2 sich nur durch 1µs unterscheiden oder gar gleich sind. So 
schnell kann ich den OCR1B Wert nicht setzen und deswegen soll dort 
gebprüft werden wie groß die Differenz ist. Ist sie nicht ausreichend 
dann wird "gewartet". (Mein TODO: Warten)

Ich habe jetzt mal alles rausgeworfen was nicht unbedingt notwendig ist 
um da mal Schritt für Schritt durchzugehen um den Fehler zu finden. Es 
wird jetzt schon eine sortierte Liste eingelesen.

Aber nicht mal das geht. :-(((

Es funktioniert alles bis zum ersten ISR Aufruf durch den TOP Wert 
OCR1A. Da drinnen wird dann OCR1B = servo_closed[ServoNr] gesetzt. Bzw. 
sollte gesetzt werden. Wird aber nicht gesetzt, der Wert bleibt auf Null 
wenn man sich die IO anschaut.

(Habe auch die Timerdefinition umgestellt weil das ging vorher überhaupt 
nicht in der Reihenfolge wie ich es drinnen hatte.)

Wenn Du das im AVR STudio debugst, geht das dann bei Dir? Wird OCR1B 
gesetzt?

Bis zu dieser Programmzeile passiert nix aufregendes, da wird nix 
gezählt oder ähnliches wo ich vielleicht aus dem Array rausfalle weil 
ich mich noch irgendwo irre.

Oder hat jemand anderer eine Idee?

LG
Ernst

Edith: Frank, wenn Du ganz genau wissen willst was das mal können soll 
dann kannst auch hier nachlesen:

Beitrag "Newbie braucht Hilfe: 9 Servos mit 1µs Auflösung ansteuern? (AVR)"

Ist aber schon ziemlich viel zu lesen... :-/

von Ernst B. (puravida)


Lesenswert?

Kann es vielleicht sein, daß das Software-Debugging im AVR-Studio 5 
einfach nicht bzw. nicht vernünftig funktioniert?

Entweder zeigt mir das IO-Fenster nicht richtige Werte an oder meine 
Anweisungen werden einfach ignoriert.

Im IO-Fenster sehe ich, daß OCR1B==0 ist aber diese Zeilen

if(OCR1B==0)
{
    return 0;
}

werden beim Debuggen einfach übersprungen...

Auch reagiert der Software-Debugger nicht so wie der µC das machen 
sollte laut Datenblatt. Im Fast-PWM-Mode sollte folgendes gelten lt. 
Datenblatt:

OCRnx / TOP Update
and *TOVn Interrupt Flag
Set and OCnA Interrupt
Flag Set* or ICFn
Interrupt Flag Set
(Interrupt on TOP)

Wenn ich beim Debuggen aber durchklicke wird zuerst die OCR1A ISR 
Routine aufgerufen, dann die OCR1B, dann einmal komplett durch bis 
wieder der TOP-Wert erreicht ist und dann erst wird OCR1A ISR gefolgt 
vom OVF ISR aufgerufen. Das erste mal OVF wird einfach verschluckt.

von Frank L. (franklink)


Lesenswert?

Hallo Ernst,
ich habe unter Studio5 Simulator nicht Debugger das gleiche Verhalten.

Ich würde jetzt mal sagen, is a bug not a feature...

Diese Simulatoren sind alle nicht besonders gut und alles andere als 
fehlerfrei...

Die einzige wirklich releavante Aussage wäre ein vernüftiges Scope und 
das ganze auf einem Mikrocontroller laufen zu lassen.

Oder direkt auf einem Mikrocontroller mit Debug-Möglchkeit. Alles andere 
ist Zeitverschwendung, weil Du nicht genau weisst, was ein Fehler im 
Programm oder im Simulator ist.

Gruß
Frank

von Frank L. (franklink)


Lesenswert?

So. ich hab das ganze nochmal im Simulator geprüft, die Werte für die 
Register werden angezeigt, allerdings nicht sofort, sondern erst beim 
nächsten Einsprung in die ISR.

Gruß
Frank

von Ernst B. (puravida)


Lesenswert?

Frank Link schrieb:
> So. ich hab das ganze nochmal im Simulator geprüft, die Werte für die
> Register werden angezeigt, allerdings nicht sofort, sondern erst beim
> nächsten Einsprung in die ISR.
>
> Gruß
> Frank

Hi Frank,

genau, und das ist viel zu spät weil ich ja innerhalb der ISR neue OCR1B 
Werte setze die nicht warten können bis der Timer von vorne startet 
sondern innerhalb eines Timerdurchganges erreich werten müssen.

Ich habe inzwischen heraussen warum das alles so komisch reagiert hat. 
Zumindest denke ich das. Ich habe einiges probiert, sogar den µC 
geflasht um zu sehen ob das in Echt auch so ist wie in der Simulation. 
Und auch nochmals Datenblatt studiert und in Summe dann folgendes 
festgestellt:

Beim Modus Fast-PWM des Timers wird der OCR1B Wert erst bei BOTTOM 
aktualisiert. Eben das was Du auch festgestellt hast.

Ich habe jetzt auf CTC umgestellt. Das ist der einzige Modus außer 
Normal wo die OCRxn Werte "immidiate" erfasst werden.

Tja, kaum hat man den Fehler funktioniert es auch schon. :-)) Wie 
erwartet war das Problem der vor dem Monitor.

Frank, Du warst mir heute (und bleibst hoffentlich auch in Zukunft :-) ) 
eine super große Stütze. Wenn man als Anfänger herumsucht und sucht und 
nochmal sucht und nicht recht weiß wo ansetzen... Da war es einfach 
super Deine Ideen zu lesen und nicht komplett allein zu sein. Vielen 
Dank nochmals.

Im Moment funktioniert der Rumpf, ohne Sortierung, ohne while-Schleife. 
Mal schauen ob ich morgen weiter komme und den Rest wieder dazufrickel.

LG
Ernst

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.