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
Ü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
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 ...
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???
@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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.