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
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
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
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
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.