Guten abend, ich wollte mal fragen, ob ihr externe Interrupts benutzt. Z.B. Um die dauer eines gedrückten Tasters oder eines Signals zu ermitteln. Normalerweise würde ich bei bei einer Flanke den Interrupt auslösen, einen Timer starten und bei der erneuten Flanke den Timer stoppen und die zeit auslesen. Jetzt habe ich aber öfters schon gehört, dass das nicht so gut ist, wegen Störungen. So wird z.B. ein Timer genommen, der jede Millisekunde eine ISR aufruft und in dieser wird der Zustand des Pins vom Kontroller kontrolliert. Ist dieser anders als der vorige Zustand, kam es zu einem Flankenwechsel. Was sind denn sonst noch Vor-/Nachteile? Je nachdem würde ich es bei mir noch umbauen. Gruß Felix
Nehm doch einfach beides. Mit nem externen Interrupt einen Timer starten und zB die Entprell-Routine aus dem Wiki hier einbauen.
https://www.mikrocontroller.net/articles/Entprellung In diesem Artikel steht alles drin. Incl. aller Vor- und Nachteile.
Für Tasten gibt es bewährte Erfassungs-Routinen, die auch das Entprellen von Tastern (meist lösen die beim Drücken und beim Loslassen jeweils mehrere Pegelsprünge aus) besorgen. Hier wird mit Hilfe eines internen Timer-Interrupts geprüft, ob sich der jeweilige Tastenzustand über mehrere ms stabilisiert hat. Für Signale von außen kann auch ein externer Interrupt günstig sein, um SOFORT zu reagieren. Wenn man weiß, wie oft sich das Signal maximal ändern kann, kann man in der Interrupt- Routine prüfen, ob das Ereignis genügend Zeit-Abstand zum vorigen Ereignis hat. Wenn nicht, wird es ignoriert.
Felix schrieb: > Z.B. Um die > dauer eines gedrückten Tasters oder eines Signals zu ermitteln Das ist eben die Frage, was - Taster prellen, werden aber von Hand bedient, da muss man keineswegs besonders schnell reagieren, im Gegenteil. Da ist ein Timer geeignet, der einen Zähler pro Taste auf/abwärts zählt, dafür gibt es genügend Beispielprogramme zur Entprellung. Normalerweise werden in diesem Timer nicht nur eine, sondern alle Tasten abgefragt, auch eine komplette PC-Tastatur ist kein Problem. Muss man auf ein Signal schnell reagieren, so ist ein externer Interrupt geeignet, aber dann muss das Signal prellfrei sein. Beides, schnelle Reaktion und Entprellung/Entstörung, geht nicht. Georg
wie schmutzig ist denn das signal und wie lange soll die taste gedrückt sein ? Ich mache es meist so, unterbrechungsroutine starten. Wenn ausgelöst, dann ISR abschalten ,1 - 100ms ( je nach anwendung , weniger, oder länger ) warten, machsehen, ob taster gedrückt und dann aktion ausführen, und nicht vergessen, den ISR wider einzuschalten. Gruß Michael
Interessant wäre zu erfahren, welche "Drückzeit" mit welcher Auflösung erkannt werden soll. Wenn der Taster manuell bedient wird, dann kann man mit PeDa's Verfahren bei 10ms Abtastrate Drücke ab 40ms erkennen und deren Länge in 10ms-Schritten ermitteln. Für kurz-/lang-gedrückt reicht das dicke.
Hallo, Interrupts verschwendet man wie schon gesagt wurde nicht für Taster abfragen. Programmiere dir einen Millisekundentimer und polle damit deine Tastereingänge. Alle zeitlichen Wiederholungen/Abfragen wo [ms] oder [s] Genauigkeit ausreichend ist kann man damit erschlagen. Code Bsp.:
1 | // ATtiny841
|
2 | #define F_CPU 8000000UL // Systemtakt in Hz
|
3 | |
4 | #include <avr/io.h> |
5 | #include <stdio.h> |
6 | #include <avr/interrupt.h> |
7 | #include <util/atomic.h> |
8 | |
9 | |
10 | volatile uint32_t millis_count; // ISR Timer 0 Variable |
11 | volatile uint32_t second_count; // ISR Timer 0 Variable |
12 | uint32_t last_millis; |
13 | uint32_t last_second; |
14 | |
15 | // *** Funktion Deklarationen *** //
|
16 | uint32_t millis(); |
17 | uint32_t seconds(); |
18 | ISR(TIMER0_COMPA_vect); |
19 | void set_Timer0(); // Timer 0, millis, seconds |
20 | |
21 | |
22 | int main(void) |
23 | {
|
24 | set_Timer0(); |
25 | |
26 | while (1) |
27 | {
|
28 | last_millis = millis(); |
29 | last_second = seconds(); |
30 | }
|
31 | }
|
32 | |
33 | |
34 | /* *** Funktionen *** */
|
35 | void set_Timer0 () // millis, seconds |
36 | {
|
37 | cli(); |
38 | TCNT0 = 0; // Register Reset |
39 | TCCR0A = 0; |
40 | TCCR0B = 0; |
41 | TIMSK0 = 0; |
42 | TCCR0A = (1 << WGM01); // CTC Modus |
43 | OCR0A = 124; // TOP, (F_CPU/PRESCALER)/1000-1 |
44 | TIMSK0 |= (1 << OCIE0A); // Compare Match einschalten |
45 | TCCR0B |= (1 << CS01) | (1 << CS00); // Prescaler 64, Timer starten |
46 | sei(); |
47 | }
|
48 | |
49 | |
50 | uint32_t millis() |
51 | {
|
52 | uint32_t value = 0; |
53 | ATOMIC_BLOCK (ATOMIC_RESTORESTATE) |
54 | {
|
55 | value = millis_count; |
56 | }
|
57 | return value; |
58 | }
|
59 | |
60 | |
61 | uint32_t seconds() |
62 | {
|
63 | uint32_t value = 0; |
64 | ATOMIC_BLOCK (ATOMIC_RESTORESTATE) |
65 | {
|
66 | value = second_count; |
67 | }
|
68 | return value; |
69 | }
|
70 | |
71 | |
72 | ISR(TIMER0_COMPA_vect) |
73 | {
|
74 | static uint32_t local_millis = 0; |
75 | |
76 | millis_count++; // Zähler für Millisekunden |
77 | local_millis++; |
78 | |
79 | if (local_millis > 999) { |
80 | second_count++; // Zähler für Sekunden |
81 | local_millis = 0; |
82 | }
|
83 | }
|
:
Bearbeitet durch User
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.