Hallo Community, kurz zu meinem Projekt: Ich habe mir einen RGB Controller bestehend aus einem PIC 18F1330, welcher drei MOSFETs steuert, drei Taster (zwei zur Steuerung, einer für RESET) und einem Drehimpulsgeber zur Farbeinstellung aufgebaut. Der Prozessor soll nun mehrere Betriebsmodi haben, welche über die beiden Taster geschaltet werden können. Realisiert habe ich dies über eine globale Variable in idata, welche in der main Routine abgefragt wird. Je nach deren Wert wird dann eine zugehörige Funktion aufgerufen. Wird einer der beiden Taster gedrückt, so wird ein Interrupt (low priority) ausgelöst. In der Serviceroutine wird dann abgefragt welcher Taster auslöste (natürlich mit entprellen) und dementsprechend die globale Variable in- oder dekrementiert. Dies funktioniert soweit auch sehr gut, wenn ich jetzt z.B. nur einzelne Farben umschalte. Implementiere ich jetzt in einem der "Menüpunkte" eine Ablaufautomatik, so reagiert der Prozessor scheinbar nicht oder nur selten auf den Interrupt. Es hat den Anschein, als trete dann ein unbestimmtes Verhalten auf, welches ich aber nicht so ganz nachvollziehen kann. Der Automatikmodus besteht aus mehreren Schleifen für Delays und einem Zähler für die Änderung der Farben (funktioniert auch, Code kann ich nachreichen, habe ich grad nur nicht parat). Als Entwicklungsumgebung nutze ich MPLAB X 1.60 und den ICD 3. Ich denke, dass das Problem der Return vom Interrupt ist. Hier müsste ich eigentlich ja nicht mehr an die Stelle zurückspringen, an der ich vor dem Interrupt war, sondern wieder in mein "Menü". Nur wie kann ich das in C realisieren, ohne das nach ein paar Mal drücken der Adress-Stack überläuft? Das war jetzt viel Text, aber ich hoffe das Problem wird klar :-) Vielen Dank für eure Hilfe. Viele Grüße, Dennis K.
Dennis K. schrieb: > Dies funktioniert soweit auch sehr gut, wenn ich jetzt z.B. nur einzelne > Farben umschalte. Implementiere ich jetzt in einem der "Menüpunkte" eine > Ablaufautomatik, so reagiert der Prozessor scheinbar nicht Doch, das tut er. Nur: was hilft es dir, wenn iData einen neuen Wert bekommt .... > Der Automatikmodus besteht aus mehreren Schleifen für Delays und einem > Zähler für die Änderung der Farben der aber nie abgefragt wird, weil dein µC mit Schleifen und Warten beschäftigt ist. > Ich denke, dass das Problem der Return vom Interrupt ist. Nein, das ist nicht das Problem. Der restliche Programmaufbau ist das Problem. Solange du nicht von der Technik des Däumchen drehen und alle heiligen Zeiten mal die Variable abfragen, die von einem Interrupt verändert wird abgehst, wird das auch nichts. PS: für Tasten braucht man auch keine Interrupts.
Karl Heinz Buchegger schrieb: > Doch, das tut er. > > Nur: was hilft es dir, wenn iData einen neuen Wert bekommt .... > > der aber nie abgefragt wird, weil dein µC mit Schleifen und Warten > beschäftigt ist. Der Aufbau ist folgendermaßen in main:
1 | int auto = 0; |
2 | |
3 | while(1) |
4 | {
|
5 | if(MenuCtr == 0) |
6 | {
|
7 | auto = Automatic(auto); |
8 | }
|
9 | |
10 | if(MenuCtr == 1) |
11 | {
|
12 | FarbeRot(); |
13 | }
|
14 | |
15 | if(MenuCtr == 2) |
16 | {
|
17 | FarbeGruen(); |
18 | }
|
19 | }
|
Die Autmatic Routine ist folgende:
1 | int Automatic(int TmrCtr) |
2 | {
|
3 | int i; |
4 | |
5 | Delay10KTCx(255); |
6 | Delay10KTCx(255); |
7 | |
8 | for(i = 0; i < 200; i++) |
9 | {
|
10 | TmrCtr++; |
11 | if(TmrCtr == 1785) |
12 | {
|
13 | TmrCtr = 0 |
14 | }
|
15 | SetColor(TmrCtr); // Setzt PWM Kanaele fuer aktuelle Farbe |
16 | Delay1KTCx(1); |
17 | }
|
18 | |
19 | return TmrCtr; |
20 | }
|
Das heißt also, dass er eigentlich nachdem er dann die Farbe um 200 Schritte erhöht hat wieder in das Hauptmenü zurückgeht und den MenuCtr (in idata des PICs gespeichert) abfragt. Das hier ein Delay zwischen drücken des Tasters und ausführen der Menüänderung vorhanden ist, ist mir bewusst. Aber der macht das dann teilweise gar nicht oder es kommen plötzlich komische Farben heraus, die ich nicht definiert habe. >> Ich denke, dass das Problem der Return vom Interrupt ist. > > Nein, das ist nicht das Problem. > Der restliche Programmaufbau ist das Problem. > Solange du nicht von der Technik des > Däumchen drehen und alle heiligen Zeiten mal die Variable abfragen, > die von einem Interrupt verändert wird > abgehst, wird das auch nichts. Wie soll man es dann besser machen? Natürlich würde ich die Delays später durch einen Timer ersetzen. > > PS: für Tasten braucht man auch keine Interrupts. Sollte ich die Tasten lieber pollen? Ich dachte hier Interrupts zu benutzen wäre besser?
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.