Hallo! Ich habe folgendes Problem: Wenn mein Programm zu den Interrupts kommt wird der High Interrupt ausgeführt und er springt automatisch wieder zu GO TO HighIntHndl. Das heißt dieser Befehl wird sobald er fertig ist immer wieder ausgeführt, obwohl ich das Flag eigentlich nicht gesetzt habe, bzw. der Timer. Ich möchte mit meinem programm ein PWM Signal herstellen, aber aufgrund dieses Fehlers ist das leider nicht möglich. Ich hoffe mir kann jemand helfen. Mfg Tobi
Tobias N. schrieb: > entschuldigen, da ich den Code > nur so beilege, denn ich weiß nicht wie ich es sonst machen soll. Langen Code als Dateianhang *.c, bei kürzerem Syntax Highlighting. Das mit dem Syntax Highlighting würde dir schon mal gesagt: Beitrag "Re: PIC18F2431 Probleme mit dem ADC" Tobias N. schrieb: > Wenn mein Programm zu den Interrupts kommt wird der High Interrupt > ausgeführt und er springt automatisch wieder zu GO TO HighIntHndl. Tobias N. schrieb: > PIE1bits.TMR1IE=1; > [...] > T1CON = 0b10000101; Könnte es sein, dass TMR1 ein Interrupt auslöst? Baue in die ISR noch das ein:
1 | if(PIR1bits.TMR1IF) |
2 | PIR1bits.TMR1IF=0; |
Wenn du einen Debugger hast, kannst du ja mal einen Breakpoint am Ende der ISR setzten und nachschauen welche Interrupt Flag noch gesetzt ist.
Danke für die Info. Werd mich das nächste mal daran halten ;) Der Timer 1 erzeugt keinen Overflow. Hab ich im Debug Modus überprüft. Eigenartigerweise setzt sich das ADIF nachdem der ADIFIntHndl fertig ist, obwohl der Timer noch nicht überläuft, denn der Overflow muss das Bit dann auf 1 setzen und startet somit den ADC.
Tobias N. schrieb: > Werd mich das nächste mal daran halten ;) Wie wär's, wenn du den Eröffnungspost editierst und es einfügst? Und kommentierter Sourcecode wäre auch einfacher zu lesen, sonst muss man jedes einzelne Register im Datenblatt nachschlagen um zu sehen, welches Bit was bewirkt... > Eigenartigerweise setzt sich das ADIF nachdem der ADIFIntHndl fertig > ist Also ist das ADIF schuld, dass die ISR immer wieder ausgeführt wird? > denn der Overflow muss das > Bit dann auf 1 setzen und startet somit den ADC. Welches bit, welcher Timer?
> Also ist das ADIF schuld, dass die ISR immer wieder ausgeführt wird? Ich nehme einmal an. > Welches bit, welcher Timer? Im Debug Modus springt das ADIF immer am Ende des HighIntHndl auf 1 und springt zum GOTO HighIntHndl, allerdings befindet sich der Timer 1 noch bei einem Wert von ungefähr 130 und dieser muss das ADIF bei einem Overflow bei einem Wert von 800 normalerweise auf 1 setzen und sonst nichts.
>Im Debug Modus springt das ADIF immer am Ende des HighIntHndl auf 1 und >springt zum GOTO HighIntHndl, Gehst du da im Singlestep durch? Wird deine Hardware angehalten wenn du Singlesteps machst oder läuft die weiter?
Ich mach das in Singlesteps in MPLAB mit einem Simulator, also ist der µC gar nicht mit dem PC verbunden und das Programm läuft nur auf dem PC. Was ich noch vergessen habe zu sagen. Beim ersten Durchlauf wird der ADIF nicht auf 1 gesetzt und er geht zur while-Schleife in der main über bis einer der Timer überläuft.
>Ich mach das in Singlesteps in MPLAB mit einem Simulator
Flash das mal in einen Controller. Simulatoren machen
auch manchmal Fehler.
Hab es schon einmal probiert und da hat es nicht funktioniert, aber anscheinend hat das Aufräumen des Programms geholfen. Es funktioniert! Herzlichen Dank für den Tipp! :D
Habe ein neues Problem, bzw. vlt ist es eh noch das alte. Mein PWM Signal funktioniert bis auf das, dass der Servomotor teilweise zittert ganz gut. Nun möchte ich natürlich verschiedene Positionen im Hauptprogramm übergeben. Hab nun das Problem, dass meine while-Schleife nur beim ersten Durchlauf ausgeführt wird und dann nicht mehr. Sprich wenn ich High an den Eingang anlege sollte die LED leuchten, tut es aber nicht. Ideen?
Schau mal mit dem Debugger, wo das Programm hängt. Tobias N. schrieb: > #include <p18cxxx.h> Ich bezweifle, dass es eine gute Idee ist für den PIC18F2431 die header Datei für irgendeinen 18Cxxx zu includieren. Welchen Compiler verwendest du eigentlich? > Sprich > wenn ich High an den Eingang anlege sollte die LED leuchten An welchen Eingang? An welchem Ausgang ist die LED? In welcher Zeile sollte das passieren? > PORTBbits.RB3=1; > Delay10KTCYx(25); > PORTBbits.RB2 = 0; Ausgänge würde ich über das LATX Register ansprechen:
1 | LATXbits.LATXy=1; |
2 | //z.B.
|
3 | LATBbits.LATB3=1; |
Das Programm läuft die komplette main einmal durch und dann springt es zum HighIntHndl und am Ende vom Handler bleibt es hängen. Womit sollte ich eher inkludieren? Ich verwende den C18 Compiler. Die Werte der zwei Eingänge AN0 und AN1 werden in meinem Programm in die Variablen lk und rk gespeichert: lk=((int)ADRESH*256) + ADRESL; rk=((int)ADRESH*256) + ADRESL; Hier sollten die LEDs leuchten, wenn High anliegt: if (lk > 700) { PORTBbits.RB2 = 1; // Delay10KTCYx(25); PORTBbits.RB2 = 0; } Das mit dem LAT werde ich probieren.
Tobias N. schrieb: > Womit sollte ich eher inkludieren? Wie wär’s mit der <p18f2431.h>? Der Name lässt vermuten, dass Microchip sie genau für deinen PIC gemacht hat. > Das mit dem LAT werde ich probieren. Wird in deinem Fall nicht ändern, es wird aber Fälle geben, wo es einen unterscheid macht. > Das Programm läuft die komplette main einmal durch und dann springt es > zum HighIntHndl und am Ende vom Handler bleibt es hängen. Du hast also immer noch das gleiche Problem vom Anfang?
> Wie wär’s mit der <p18f2431.h>? Der Name lässt vermuten, dass Microchip > sie genau für deinen PIC gemacht hat. Hab ich geändert. Wenn ich es im Debug-Mode mit dem PicKit 3 probiere, durchläuft er ständig die while-Schleife in der Main, was er ja auch machen sollte, doch es zählt nur der Timer 2. Timer 1 tut nichts und Timer 2 setzt auch kein TMR2IF beim Überlauf und somit tut sich nichts. Kenn mich schön langsam gar nicht mehr aus. >Du hast also immer noch das gleiche Problem vom Anfang? Ja prinzipiell ist es das selbe Problem. Zu diesem Zeitpunkt war ich noch nicht beim eigentlichen Programm, deshalb ist es mir nicht aufgefallen, da ich nur die Timer richtig eingestellt habe und es soweit funktioniert hat.
Mit welchem Postscale soll Timer2 den Laufen? Weil der Kommentar passt nicht zur Einstellung: "T2CON = 0b01111111; //1:1 Postscale, Timer2 on, Prescaler is 16" Postscale ist 1:16 und nicht 1:1
Chris B. schrieb: > Mit welchem Postscale soll Timer2 den Laufen? > Weil der Kommentar passt nicht zur Einstellung: Ach ja da hab ich leider vergessen den Kommentar zu ändern. Er läuft richtigerweise mit einem Postscale von 1:16, da ich sonst nicht in den Millisekundenbereich komme. Aber es kann doch nicht sein, dass das TMR2IF nicht gesetzt wird, wenn er überläuft. Das ist ja klar so definiert. Wenn ich es auf den µC programmiere funktioniert das PWM ja auch ganz normal und hierfür ist der TMR2 zuständig. Heißt für mich jetzt, dass ich mich auf den Debugger nicht ganz verlassen kann oder?
Hast du irgendwo einen Low-Priority-Interrupt definiert (falls das nicht das gesamte Programm ist), denn "IPR1bits.TMR2IP = 0; //Timer 2 High Priority" ist sicher nicht "High Priority" sondern "Low Priority". Weiss jetzt nicht was der Compiler für einen Low-Interrupt-Dummy anlegt, aber mehr als "retfi" wird dort nicht drinstehen.
Chris B. schrieb: > ist sicher nicht "High Priority" sondern "Low Priority". Kein Problem: > RCONbits.IPEN = 0; //Enable Priority Der Kommentar ist falsch, die Priorität ist deaktiviert. Wenn ich es richtig im Kopf habe, wird ohne Priority der High-Vector Benutzt.
Ich habe ursprünglich mit Prioritäten gearbeitet, hab es dann aber wieder verworfen. Sollte ich mit Prioritäten arbeiten?
Tobias N. schrieb: > Sollte ich mit Prioritäten arbeiten? Wenn du es nicht brauchst, dann nicht. Es löst aber das Problem, dass du TMR2 auf Low-Priority gestellt hast.
Max H. schrieb: > Kein Problem: >> RCONbits.IPEN = 0; //Enable Priority > Der Kommentar ist falsch, die Priorität ist deaktiviert. Wenn ich es > richtig im Kopf habe, wird ohne Priority der High-Vector Benutzt. Ok, habe jetzt nicht jedes Register überprüft ob Kommentar zum Code passt ;-)
Zusätzlich wäre es gut, wenn die Kommentare mit dem Code übereinstimmen. Durch falsche Kommentare wird der Code noch unverständlicher als ohne.
Max H. schrieb: > Zusätzlich wäre es gut, wenn die Kommentare mit dem Code übereinstimmen. > Durch falsche Kommentare wird der Code noch unverständlicher als ohne. sry. muss ich mir angewöhnen, sobald ich etwas ändere. TMR2IF wird trotzdem nicht gesetzt bei einem Überlauf.
Allerdings ist das ja nicht mein Problem, denn wenn ich es Programmiere funktioniert es ja. Mein Problem ist nur immer noch, dass er die while nur einmal durchläuft und dann beim Interrupt Handler hängen bleibt. Wie kann ich vorgehen, um den Fehler zu finden?
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.