Forum: Mikrocontroller und Digitale Elektronik Interrupts für Anfänger


von Mike (Gast)


Lesenswert?

Hi!

Ich bin noch ein mutiger Anfänger in Sachen MC und möchte ein relativ 
Programm schreiben für das ich auch schon ein paar Codeschnipsel 
gefunden hab. Dabei soll auf dem MC eine real time clock implementiert 
werden. Die Uhr wird durch einen Timerinterrupt jede Sekunde 
weitergezählt. Nun möchte ich einen externe Interruptpin durch einen 
Taster von VCC auf GND ziehen und es soll die Zeit gestoppt werden, wie 
lange ich auf den Taster drücke. Die Uhr soll aber ständig laufen und 
nicht nur wenn der Taster gedrückt wird. Geht das denn so einfach? Wenn 
ein Interrupt durch den Taster ausgeführt wird, kann dann noch der 
Timerinterrupt für die Uhr ausgelöst werden wenn der Taster z.B. für 4 
sek gedrückt wird??? Der Mikrocontroller befindet sich doch dann in der 
Interruptroutine für den externen Interrupt, oder?!

Gruß
Mike

von Kalle (Gast)


Lesenswert?

Üblicherweise setzt man in den ISR nur Flags und wertet diese dann im 
Main aus. So gibt es dann auch keine Probleme mit sich gegenseitig 
blockierenden Interruptroutinen.

MfG

Kalle

von Hannes L. (hannes)


Lesenswert?

Mike wrote:
> Hi!
>
> Ich bin noch ein mutiger Anfänger in Sachen MC und möchte ein relativ
> Programm schreiben

Was ist ein "relativ Programm"?

> für das ich auch schon ein paar Codeschnipsel
> gefunden hab. Dabei soll auf dem MC eine real time clock implementiert
> werden. Die Uhr wird durch einen Timerinterrupt jede Sekunde
> weitergezählt.

Warum nicht jede 10ms, dann kann der Interrupt auch gleich die Tasten 
mit entprellen?

Oder alle 1ms, dann kann der Interrupt auch gleich die Anzeige 
synchronisieren?

> Nun möchte ich einen externe Interruptpin durch einen
> Taster

Sehr schlechte Idee, denn (mechanische) Taster prellen. Der einzige 
sinnvolle Grund, einen mechanischen Bedienungstaster an einen 
Interrupt-Pin anzuschließen, ist das Aufwecken des MCs aus dem 
"Tiefschlaf" (z.B. Power-down" beim AVR). Ansonsten fragt man Taster 
zyklisch ab (Timer-Interrupt), such mal in der Codesammlung nach 
"bulletproof" und in der Artikelsammlung nach "entprellung".

> von VCC auf GND ziehen und es soll die Zeit gestoppt werden, wie
> lange ich auf den Taster drücke.

Das geht auch sehr gut im Timer-Interrupt.

> Die Uhr soll aber ständig laufen und
> nicht nur wenn der Taster gedrückt wird. Geht das denn so einfach?

Ja, wenn man es richtig macht.

> Wenn
> ein Interrupt durch den Taster ausgeführt wird, kann dann noch der
> Timerinterrupt für die Uhr ausgelöst werden wenn der Taster z.B. für 4
> sek gedrückt wird??? Der Mikrocontroller befindet sich doch dann in der
> Interruptroutine für den externen Interrupt, oder?!

Deshalb hält man die Interrupt-Routinen so kurz wie möglich und fragt 
Taster im Timer-Interrupt ab. Wie das im Einzelfall am günstigsten geht, 
wird durch die anderen Aufgaben des Programms bestimmt. Z.B. von der 
Ansteuerung eines LCDs oder dem Multiplexen einer mehrstelligen 
Siebensegmentanzeige oder was auch immer sonst noch gemacht werden muss.

>
> Gruß
> Mike

...

von Mike (Gast)


Lesenswert?

Hmm, das verstehe ich jetzt nich so richtig. Also dir RTC würde ich so 
implementieren:
1
void Uhr_weiterzaehlen()//zählt die Uhr um 1 Sec weiter
2
{
3
  sek++;
4
  if (sek == 60)
5
  {
6
    sek = 0;
7
    min++;
8
    if (min == 60)
9
    {
10
      min = 0;
11
      std++;
12
      if (std == 24)
13
      {
14
        std = 0;
15
        tag++;
16
      }
17
    }
18
  }
19
}
20
21
22
23
SIGNAL(SIG_OUTPUT_COMPARE1A)//Interupt Routine die beim Überlaufen (TOP) von Timer 1 ausgeführt wird
24
{
25
  Uhr_weiterzaehlen();// Uhr weiterzählen
26
}

Und den externen Interrupt dann einfach ähnlich:
1
SIGNAL(SIG_INTERRUPT0){
2
solange PINX ==0 soll Zähler hochlaufen;
3
gib Zähler aus z.b via UART

Geht das so ohne das die RTC stehen bleibt???

von Mike (Gast)


Lesenswert?

Sorry die antwort war jetz auf kalle bezogen...

von Johannes M. (johnny-m)


Lesenswert?

@Mike:
Wenn Du ein wirklich "mutiger Anfänger" bist, dann installiere am besten 
auch gleich die aktuellste Software. Die Syntax für die Interrupt 
Handler mit "SIGNAL" ist veraltet.

Ansonsten haben Hannes und Kalle recht: Lass einen Timer mit einem 
sinnvollen Basistakt Interrupts auslösen. Im Interrupt Handler setzt Du 
ein Flag (also irgendein Bit in irgendeiner globalen Variablen, volatile 
bei der Deklaration nicht vergessen) und fragst dieses Flag im 
Hauptprogramm ab. Wenn das Flag gesetzt ist, liest Du die Taster ein und 
zählst bei Bedarf Deinen Sekundenzähler rauf. Bei der Tasterauswertung 
speicherst Du jeweils den Zustand und vergleichst im jeweils nächsten 
Zyklus mit dem neuen Zustand, um festzustellen, ob sich was geändert hat 
und wenn ja, was sich geändert hat (Taster gedrückt oder Taster 
losgelassen). In welchem Zeitraster Du das genau machst, bleibt Dir 
selbst überlassen.

Generell gilt: Warteschleifen in Interrupt Handlern sind auf jeden Fall 
zu vermeiden und Interrupt Handler sollten so kurz wie möglich sein, da, 
wie Du ja schon richtig vermutet hast, während ihrer Ausführung das 
komplette System blockiert ist.

Viel Spaß beim Anfang!

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.