Interrupt programmieren in C ATMega8

OP #1381645
Lesenswert?

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.
#1381675
Lesenswert?

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.
Gast #1381687
Lesenswert?

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;
  }
}
  }
Gast #1381690
Lesenswert?

> 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
}
Gast #1381703
Lesenswert?

>   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!
Gast #1381709
Lesenswert?

> 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.
Gast #1381718
Lesenswert?

> 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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren