Hallo zusammen, ich möchte ein globales Interrupt programmieren, welches mir durch einen externen Taster am Mikrocontroller (ATMega8) das Hauptprogramm unterbricht, bis der Taster erneut betätigt wurde und das Programm fortgesetzt wird. Für Experten mag das simpel klingen, aber ich bin ein blutiger Anfänger auf dem Gebiet...und das Tutorial hat mir auch nicht besonders weitergeholfen. :-( Würde mich über jegliche Tipps freuen.
dann zeig doch erstmal wie weit du schon gekommen bist, und woran du zum schluss gescheidert bist.
Wobei man allerdings auch sagen muss, dass die ganze Aufgabenstellung schon danach schreit, dass sie wahrscheinlich falsch angegangen wird. Der Interrupt soll das Hauptprogramm nämlich eigentlich gar nicht unterbrechen. Wenn überhaupt, dann soll der Interrupt lediglich den Tastenzustand auswerten. Das Hauptprogramm sieht an für sich günstigen Stellen regelmässig nach, ob die Taste gedrückt ist und legt gegebenenfalls eine Pause ein. Sinn der Sache ist es, dass das Hauptprogramm die Entscheidung behält ob und wann es unterbrochen werden kann, damit sie eine angefangene Operation, die auf jeden Fall fertig durchgezogen werden muss, auch durchziehen kann.
so schaut das Hauptprogramm aus...es dient der Zustandsüberwachung von LEDs und soll je nach Zustand reagieren. Und wie gesagt...sobald ein Taster betätigt wird, soll das Programm unterbrochen werden bis der Taster erneut bestätigt wurde. void main(void) { DDRB=0x21; /*PB0 und PB5 als Ausgänge, PB1-PB4 als Eingänge*/ DDRD=0x3F; /*PD0-PD5 als Ausgänge, PD6 und PD7 als Eingänge, PD0 Set, PD5 Reset*/ DDRC=0x04; /*PC0, PC1 und PDC3-PC5 als Eingänge, PC2 als Ausgang*/ lcd_init(); lcd_home(); while(1) { reset: PORTB=0x20; /* Setzen --> Grundzustand*/ if(!(PINB & (1<<PB3)) && !(PINB & (1<<PB4)) && (PINB & (1<<PB1)) && (PINB & (1<<PB2))) { PORTB|=(1<<PB0); /*Set aktivieren, Programm starten*/ } else { goto reset; } wechsel: while(((!(PINB & (1<<PB3)) && (PINB & (1<<PB4))) || ((PINB & (1<<PB3)) && !(PINB & (1<<PB4)))) && !(PINB & (1<<PB1)) && !(PINB & (1<<PB2))); if(((!(PINB & (1<<PB3)) || (PINB & (1<<PB4))) && ((PINB & (1<<PB3)) || !(PINB & (1<<PB4))) && (!(PINB & (1<<PB3)) || (PINB & (1<<PB4)))) || (PINB & (1<<PB1)) || (PINB & (1<<PB2))) { lcd_data(zaehler); /*Schreibe auf Display*/ zaehler++; /*Zählregister um 1 erhöhen*/ bfr=zaehler/pulse; /*BFR ausrechnen*/ set_cursor(0,2); lcd_data(bfr); /*schreibe auf Display*/ PORTB=0x20; /*kehre in den grundzustand zurück*/ } else { fehler++; lcd_data(fehler); goto wechsel; } } }
> ich möchte ein globales Interrupt programmieren, Alle Interrupts im ATMega sind global. > welches mir durch einen externen Taster am > Mikrocontroller (ATMega8) das Hauptprogramm Dafür nimmt man meist keinen Interrupt. Stichwort: Prellende Taster. Wenn deine Main-Schleife nicht Zeitkritisch ist (das sollte sie nie sein), hol dir die Tasterwerte lieber per Polling und entprelle das Ganze dann. > unterbricht, bis der Taster erneut betätigt > wurde und das Programm fortgesetzt wird. Das würde heißen du bist die ganze Zeit (mehrere Sekunden! lang) im Interrupt, was aber das Interrupthandling ad absurdum führt. Interrupts sollten so schnell wie möglich abgearbeitet werden, Aufgaben die länger dauern sollten ausgelagert werden. Was du viel eher brauchst ist eine Art "rudimentäre Zustandsmaschine"
1 | void main(void) |
2 | {
|
3 | int zustand = 0; |
4 | |
5 | while(1) // hauptschleife |
6 | {
|
7 | //Taster pollen
|
8 | if(taster_gedrueckt) |
9 | {
|
10 | if(zustand == 1) zustand = 0; else zustand = 1; |
11 | }
|
12 | |
13 | |
14 | //hier alles rein was immer ausgeführt werden muss (auch bei pause)
|
15 | |
16 | if(zustand == 0) |
17 | schleife_normal(); |
18 | else
|
19 | schleife_pause(); |
20 | }
|
21 | }
|
22 | |
23 | void schleife_normal() |
24 | {
|
25 | // hier alles rein was du normalerweise in der hauptschleife tust.
|
26 | // Die Funktion wird dauernd aufgerufen
|
27 | }
|
28 | |
29 | void schleife_pause() |
30 | {
|
31 | // hier alles rein, was im Pause-Modus ausgeführt werden muss.
|
32 | }
|
Vielen Dank erstmal für die schnellen Antworten...ich werde das mit dem Programm ausprobieren.
> int zustand = 0;
Ich programmier wohl schon zu lang java... dabei sinds erst paar Monate.
ein uint8_t reicht hier natürlich völlig ;-)
Funktionsprototypen hab ich auch vergessen
Tasterentprellung hab ich auch nicht erwähnt (die muss auf jeden Fall
erfolgen)
1 | reset:
|
2 | ...
|
3 | goto reset |
Das geht gar nicht! Gotos sind ein No-Go seit mindestens 20 Jahren! Auch in Basic!
und lass die gotos weg, es gibt zwar gründe soetwas auch in C zu verwenden aber nicht in diesem Programm
> Das geht gar nicht! Gotos sind ein No-Go seit mindestens 20 Jahren! Auch > in Basic! Es ist ein teil der Sprache - also kann man es auch verwenden. Und ja es gibt beispiel wo es sinn macht und der Code damit einfacher zu lesen ist. Klar kann man es auch immer Ohne machen und sich damit die Finger brechen. Gotos also nur einsetzen, wenn alles andere die Sacher schwer lesbar macht.
> Gotos also nur einsetzen, wenn alles > andere die Sacher schwer lesbar macht. Ja, sie sind noch Teil der Sprache, aus historischen Gründen. Gut, es mag auf der ganzen Welt 2-3 Programme geben, wo gotos wirklich übersichtlicher sind, als "alles andere", das was ich da oben sehe gehört aber nicht dazu. in 99,...% der Fälle ist ein Goto eben unübersichtlicher als zb eine Unterfunktion
> Gotos also nur einsetzen, wenn alles andere die Sacher schwer lesbar > macht. was aber hier eindeutig nicht der fall ist. das goto reset springt nur innerhalb der schleife, wechsel genauso...
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.