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. :-))
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
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
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
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
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
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
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
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... :-/
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.
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
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
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