Forum: Mikrocontroller und Digitale Elektronik Interrupt entprellen


von herbert (Gast)


Lesenswert?

Hallo.
Ich will mit einem Programm eine Spannung überwachen. Wenn die 
Eingangsspannung größer als die Refernzspannung ist soll ein Interrupt 
ausgelöst werden und eine Variabel inkrementiert werden. Nun zu meinem 
Problem: wenn die Eingangsspannung die Rfernzspannung erreicht wird mehr 
mals der Interrupt ausgelöst. Wie kann ich den Interrupt entprellen?

Source Code:
1
#include <avr/io.h>  // Deklarationen
2
#include <stdio.h>
3
4
#define BAUD 9600  // Symbol fuer Baudrate
5
#define TAKT 3686400  // Symbol fuer Controllertakt
6
#define TEILER (long)TAKT/(16*(long)BAUD) - 1   // Symbol fuer Teiler
7
8
#include <avr/interrupt.h>
9
//#include <avr/signal.h>
10
11
12
13
void UART_Init(void)  // UART initialisieren
14
{
15
  
16
17
  UBRRL = TEILER;      // Baudrate einstellen
18
  UCSRB |= (1<<RXEN);    // Empfaenger ein
19
  UCSRB |= (1<<TXEN);    // Sender ein
20
  UCSRB |= (1<<RXCIE);  // Empfaengerinterrupt frei
21
}
22
23
24
void UART_putch(unsigned char data)         // warten und Zeichen nach Sender  
25
{
26
  //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
27
  while (!(UCSRA&0x20));
28
  //sende
29
  UDR = data;
30
}
31
32
33
void UART_putstr(unsigned char *zeiger)    // String bis Endemarke ausgeben
34
{
35
  while (*zeiger != 0)
36
  {
37
    while (!(UCSRA&0x20));    // warte bis Datenregister frei
38
    UDR = *zeiger;        // Zeichen nach Sendedatenregister
39
    zeiger++;                         
40
  }
41
}
42
43
int i = 0;
44
char buffer[20];
45
46
SIGNAL(SIG_COMPARATOR)
47
{
48
  i++;
49
  sprintf(buffer, "Impulse: %d \r\n", i);
50
   UART_putstr(buffer);
51
}
52
53
54
55
int main(void)  // Hauptfunktion
56
{
57
58
59
  UART_Init();        // UART initialisieren
60
61
  DDRD = 0x00;
62
  PORTD =0x00;
63
64
  ACSR |= ( (1<<ACIS0) | (1<<ACIS1) | (1<<ACIE));
65
  ACSR &= ~( (0<<ACI) | (0<<ACD));
66
  
67
68
  sei();
69
;
70
  
71
  while(1)      // Arbeitsschleife ist leer
72
  {
73
  
74
  
75
76
  } //end while(1)
77
78
} // Ende main

von Falk B. (falk)


Lesenswert?

@ herbert (Gast)

>Problem: wenn die Eingangsspannung die Rfernzspannung erreicht wird mehr
>mals der Interrupt ausgelöst. Wie kann ich den Interrupt entprellen?

Entweder per Software oder mit einem exteren Comparator mit Hysterese.

Entprellung
Schmitt-Trigger

MFG
Falk

von Michael Wilhelm (Gast)


Lesenswert?

Es gibt eine Software- und eine Hardwarelösung. Welche soll es denn 
sein?

MW

von herbert (Gast)


Lesenswert?

Software wäre mir lieber.
(Die Eingangsspannung muss ca. 500 mal pro Sekunde abgetastet werden)

Mfg. herbert

von Christian F. (Gast)


Lesenswert?

z.B. nur jeden 5ten oder x-ten Interrupt auswerten, oder im jeweiligen 
Interrupt das ADC Register auslesen und mit einem kurzen Timer 
überprüfen ob sich der Wert nochmals verändert und dann die ausgaben 
machen.

von Falk B. (falk)


Lesenswert?

@ herbert (Gast)

>Software wäre mir lieber.
>(Die Eingangsspannung muss ca. 500 mal pro Sekunde abgetastet werden)

Bei Abtastung prellt nix. Denn da hast du einen festen Timerinterupt mit 
2ms und liest einfach den Status des Comparators aus. Fertig. Ohne 
Comparator-Interrupt.

MFG
Falk

von Michael Wilhelm (Gast)


Lesenswert?

Wenn ich das jetzt richtig gesehen habe, ist es der Analog-Komparator 
Interrupt. 500 x in der Sekunde entspricht 2 ms. Wenn der Interrupt 
kommt, starte einen Timer für eine gewisse Zeit in der kein Int kommen 
darf. Nach Ablauf ist das Signal entweder stabil (Timer Int wurde nicht 
unterbrochen) oder es kommen weitere Ints (Rauschen). Hardware wäre mir 
sicherer (nur 1 Widerstand, evtl. mit einem C gegen Ripple).

MW

von herbert (Gast)


Lesenswert?

Danke für deine Antwort. Kannst du mir bitte die Hardware Lösung genauer 
erklären?
Mfg. Herbert

von Peter D. (peda)


Lesenswert?

Wenn die Eingangsspannung fast gleich der Schwellspannung ist, kannst Du 
Dich auf den Kopf stellen, der Komparator wird immer zappeln.

Wenn dieser Bereich garantiert innerhalb einer Maximalzeit durchfahren 
wird, kannst Du mit einer größeren Zeit (>2-fach) als Abtastintervall in 
Software entprellen.

Ansonsten brauchst Du ne Hysterese und das geht nur in Hardware durch ne 
Mitkopplung vom Komparatorausgang auf den +Eingang.


Peter

von herbert (Gast)


Lesenswert?

danke für deine antwort peter. dann bleibtmir wohl nichts anderes über 
als die Hardware version zu implementieren.

Mfg. Herbert

von Peter H. (pehe)


Lesenswert?

Hallo Herbert,

die Hardwarelösung kommt auch ohne externen Operationsverstärker (s. 
Bild im Schmitt-Trigger Artikel)aus, man ersetze ihn durch den AVR:
die Eingänge + und - sind sowieso schon bei Dir angeschlossen, und der 
Rückkopplungswiderstand (R3) wird an einen Portausgang angeschlossen.
Zum Verschieben der Schaltschwelle, also zur Erzeugung einer Hysterese, 
kann in der Interruptroutine dieser Port auf VCC, GND oder Tristate 
geschaltet werden - je nachdem, was sinnvoll ist.
Wenn die Ausgangsimpedanz der Quelle für das IN Signal einigermaßen 
paßt, kann R3 auch an den - Eingang angeschlossen werden, die Hysterese 
entsteht dann durch Veränderung des zu messenden Signals.

Noch eine Anmerkung zu Deiner Interruptroutine: sprintf() und 
UART_putstr() sollten dort nicht enthalten sein, die haben u.U. lange 
Laufzeiten, und der UART kann -je nach Implementierung von putstr- die 
Interruptroutine für lange Zeit blockieren. Rechne doch mal nach, ob Dir 
dabei nicht Meßwerte verloren gehen.

Tip: Für die Simulation solcher Schaltungen bietet sich VMLab an, falls 
Du es nicht sowieso schon kennst (kostenlos).


Gruß,
Peter H.

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.