Hallo,
ich habe mir in dieser Woche vorgenommen einen Digitales Signal
auszuwerten, allerdings habe ich probleme beim Interrupt
1
ISR(INT1_vect)
2
{
3
if(getDcfPegel() == false) // Steigende Flanke
4
{
5
setDcfPegel(true); // Setze Merker
6
resetTimer(); // setze TCNT0 auf 0
7
startTimer(); // starte Timer
8
}
9
else // Fallende Flanke
10
{
11
setDcfPegel(false); // Setze Merker
12
stopTimer(); // Stoppe Timer
13
dcfPegelHighTime = getMilliseconds(); // Wie lange war der Pegel High
14
if(dcfPegelHighTime <= 100){
15
usartSendData(0); // Sende eine 0
16
}
17
else{
18
usartSendData(1); // Sende eine 1
19
}
20
}
21
}
Das Signal kommt von einem DCF empfänger. Diesen habe ich wie folgt
verbunden
1: GND -> GND (Und GND mit Mikrocontroller)
2: Betriebsspannung -> 5Volt
3: DCF-Ausgang -> INT1
4: DCF-Ausgang invertiert -> Offen
zwischen der Betriebsspannung und dem DCF-Ausgang habe ich noch einen
10kOhm Widerstand eingebaut.
Jetzt lese ich überall, dass das Signal nur jede Minute einmal kommt.
Wenn ich mir jetzt allerdings den Uart ansehe, werden da die ganze zeit
nullen geschickt. Verbinde ich GND mit INT1, wird garnichts geschickt,
da ja auch kein Interrupt ausgelöst wird.
Aber woran kann es liegen, dass das Signal andauern den INterrupt
auslöst, auch wenn es nur einmal die Minute kommen soll?
Bernd
Hallo,
ich denke Du solltest Dir noch mal Gedanken über die Art der Kodierung
einer "0" und "1" machen.
Siehe Abschnitt "Zeitinformation"
# https://de.wikipedia.org/wiki/DCF77
Bernd schrieb:> Aber woran kann es liegen, dass das Signal andauern den INterrupt> auslöst, auch wenn es nur einmal die Minute kommen soll?
Vielleicht liegt das an der Konfiguration deines Interrupts. Alleine der
Programmteil, der zur Ausführung kommt, wenn der Interrupt bereits
ausgelöst wurde, ist da wenig hilfreich. Da ist das Kind schon in den
Brunnen gefallen.
Bernd schrieb:
Was genau tut deine Funktion setDcfPegel() ?
Du fragst da ab, ob die Impulse kürzer oder länger als 100ms sind.
Beim DCF Signal sind die Impulse aber (im Idealfall) 100ms oder 200ms
lang. Also macht ein Vergleich mit 150 eher Sinn.
Nun ist es aber auch so, daß jeder DCF Empfänger die Impulse mehr oder
weniger verzerrt. Deswegen ist es besser, die tatsächliche Pulsbreite
deines konkreten Empfängers zu messen und dann genau die Mitte
dazwischen als Schwellwert zu verwenden.
Dann noch etwas zu dem 10k Pull-Up Widerstand: Die Ausgänge der gängigen
DCF-77 Empfänger Chips kann man nur ganz schwach belasten. Eine typische
Datenblatt-Angabe dazu wäre z.B. >5µA, was bedeutet, daß der Hersteller
5µA Belastbarkeit garantiert. Mit Glück geht auch mehr.
5V / 10k Ohm = 500µA, als das hundertfache!
Viele DCF-Empfänger haben daher zusätzlich noch einen Transistor drauf,
meistens als Open-Collector geschaltet. Der Invertiert dann das Signal,
so dass es jede Sekunde einen Low-Impuls liefert.
Aber es gibt auch Ausnahmen. Es gibt Chips, die einige mA ohne
zusätzlichen Transistor schalten können. Und was die Polarität des
Signals angeht, macht auch jeder was er will.
Also: Miss erst mal nach, was aus deinem Modul raus kommt und ob sein
Ausgang für deine Anwednung ausreichend belastbar ist.
Dann möchtre ich noch etwas zur Nutzung des Timers sagen: Da der µC nur
wenige Timer hat, ist das eine kostbare Ressource. Du wirst schnell auf
den bedarf stoßen, einen Timer für mehrere Zwecke gleichzeitig zu
verwenden.
Das ist auch ganz einfach. Beim Start des Impulses sollst du ihn nicht
zurück setzen, sondern den aktuellen Wert in eine Variable kopieren.
Beim Ende des Impulses holst du nochmal den aktuellen Timer-Wert und
subtrahierst beide voneinander.
1
if(steigendeFlanke)
2
{
3
startZeit=getMilliseconds();
4
}
5
else// fallende Flanke
6
{
7
pulsLaenge=getMilliseconds()-startZeit;
8
}
Die Variable starZeit muss den gleichen Typ haben, wie der Rückgabewert
von getMilliseconds(). Dann liefert die Subtraktion sogar dann noch den
richtigen Wert, wenn der Timer zwischenzeitlich einmal überläuft.
Der Vorteil dieser Vorgehensweise ist, daß du den selben
Millisekunden-Timer auch für andere Messungen verwenden kannst, die sich
mit diesem DCF Empfang zeitlich überlappen.
Da der DCF-Empfang nicht sehr zuverlässig ist, wäre es auch eine gute
Idee, die Uhr primär mit einem Quarz zu takten. Das DCF Signal kann man
dann zum Synchronisieren der Uhrzeit zu verwenden, wenn die empfangenden
Daten denn plausibel sind.
@Bernd (Gast)
>ich habe mir in dieser Woche vorgenommen einen Digitales Signal>auszuwerten, allerdings habe ich probleme beim Interrupt
DCF sollte man besser mit einem Timer abtasten und NICHT auf
Pegelwechsel reagieren. Denn im Falle einer eingekoppelten Störung kommt
deine Auswertung durcheinander.
>1: GND -> GND (Und GND mit Mikrocontroller)>2: Betriebsspannung -> 5Volt
Ist das für DEIN Modul OK? Die meisten wollen eher 1,5-3V sehen.
>zwischen der Betriebsspannung und dem DCF-Ausgang habe ich noch einen>10kOhm Widerstand eingebaut.
Ist das für DEIN Modul OK?
>Jetzt lese ich überall, dass das Signal nur jede Minute einmal kommt.
Verteilt über eine Minute! Pro Sekunde ein Bit!
Mach erstmal einen ganz einfachen Test. Kopiere in einer Endlosschleife
den Zustand des Eingangsports vom DCF77 Modul auf einen Ausgangsport, wo
eine LED + Vorwiderstand dranhängt. Dann musst du die LED im
Sekundentakt blinken sehen, man sieht auch kurze und lange Pulse sowie
die Pulspause bei Sekunde 59. Dann geht es weiter.
https://www.mikrocontroller.net/articles/DCF77-Funkwecker_mit_AVR#DCF77-Modul_von_Reichelt
Stefan U. schrieb:> Beim DCF Signal sind die Impulse aber (im Idealfall) 100ms oder 200ms> lang. Also macht ein Vergleich mit 150 eher Sinn.
Ja, das macht mehr sinn.
Stefan U. schrieb:> Eine typische> Datenblatt-Angabe dazu wäre z.B. >5µA, was bedeutet, daß der Hersteller> 5µA Belastbarkeit garantiert. Mit Glück geht auch mehr.> 5V / 10k Ohm = 500µA, als das hundertfache!
Ich habe einen DCF-Empfänger BN641138 von Conrad.
da steht Ausgänge 3 und 4 offener Kollektor NPN Max 30V, 1mA. Dann
müssten die 500uA aber ja passen
Stefan U. schrieb:> Dann möchtre ich noch etwas zur Nutzung des Timers sagen: Da der µC nur> wenige Timer hat, ist das eine kostbare Ressource. Du wirst schnell auf> den bedarf stoßen, einen Timer für mehrere Zwecke gleichzeitig zu> verwenden
JA, da bin ich schon. Das Problem würde ich aber bearbeiten, wenn der
DCF-Empfänger läuft, bzw. ich diesen richtig Auswerten kann.
Stefan U. schrieb:> if (steigende Flanke)> {> startZeit=getMilliseconds();> }> else // fallende Flanke> {> pulsLaenge=getMilliseconds()-startZeit;> }
Das werde ich mir notieren und vormerken. Danke
Falk B. schrieb:> Ist das für DEIN Modul OK? Die meisten wollen eher 1,5-3V sehen.
Als Betriebsspannung steht 2.5V bis 15V=
Falk B. schrieb:> Verteilt über eine Minute! Pro Sekunde ein Bit!
Dann habe ich es falsch verstanden
Da muss ich wohl noch mal ran;)
Ich danke euch schon einmal für die Antworten. ICh werde es noch einmal
überarbeiten und mich dann noch einmal melden, wie es läuft.
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang