Forum: Mikrocontroller und Digitale Elektronik Interrupt programmieren in C ATMega8


von Simon R. (e-techniker)


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.

von Peter (Gast)


Lesenswert?

dann zeig doch erstmal wie weit du schon gekommen bist, und woran du zum 
schluss gescheidert bist.

von Karl H. (kbuchegg)


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.

von Simon R. (Gast)


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;
  }
}
  }

von Sumynona (Gast)


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
}

von Simon R. (Gast)


Lesenswert?

Vielen Dank erstmal für die schnellen Antworten...ich werde das mit dem 
Programm ausprobieren.

von Sumynona (Gast)


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!

von Peter (Gast)


Lesenswert?

und lass die gotos weg, es gibt zwar gründe soetwas auch in C zu 
verwenden aber nicht in diesem Programm

von Peter (Gast)


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.

von Sumynona (Gast)


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

von gast (Gast)


Lesenswert?

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