Forum: Mikrocontroller und Digitale Elektronik Externer Interrupt oder TimerInterrupt und Pin abfragen?


von Felix (Gast)


Lesenswert?

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

von Nico W. (nico_w)


Lesenswert?

Nehm doch einfach beides. Mit nem externen Interrupt einen Timer starten 
und zB die Entprell-Routine aus dem Wiki hier einbauen.

von Stefan S. (chiefeinherjar)


Lesenswert?

https://www.mikrocontroller.net/articles/Entprellung

In diesem Artikel steht alles drin. Incl. aller Vor- und Nachteile.

von Jacko (Gast)


Lesenswert?

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.

von georg (Gast)


Lesenswert?

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

von Michael F. (sharpals)


Lesenswert?

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

von Carl D. (jcw2)


Lesenswert?

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.

von Veit D. (devil-elec)


Lesenswert?

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