Forum: Mikrocontroller und Digitale Elektronik dcf77 Signal Einlesen. Atmega644


von Michael B. (michaelba)


Lesenswert?

Hallo allerseits,
derzeit versuche ich eine Funkuhr zu basteln und möchte zunächst eine 
LED im Takt zum invertierten Signal blinken lassen, welche im späteren 
Betrieb den Empfang des Signals anzeigen soll.
Mit dem folgenden Programm bin ich der Ansicht, einen 16Bit-Timer 
programmiert zu haben, der jede ms einen Overflow erzeugt  und dann die 
ISR aufruft, PIN2 prüft und PIN 3 an Port D den Wert 1 zuweist, solange 
dcf77_sig den High-Pegel enthält.
Leider zeigt sich aber keine Reaktion.
Kann jmd. sehen, wo der Fehler liegt?

#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/common.h>
#ifndef F_CPU
#define F_CPU 1000000
#endif
uint8_t dcf77_sig;

int main(void)
{
  sei();
  DDRD |= 1<<PIND3;
  DDRD &= ~(1<<PIND2);
  PORTD |=(1<<PIND2);
  TCCR1B |= 1<<CS10;
  TIMSK1 |= 1<<OCIE1A;
  OCR1A = 1000;
  while(1)
  {
  }
}

ISR(TIMER1_OVF_vect)
{
  dcf77_sig = PIND2;
  while(dcf77_sig==1)
  {
    PORTD|=1<<PIND3;
    }
  }


 Anmerkungen:
-Atmega 644
-Lösungen mit Hardwareinterrupts ebenfalls erwünscht. (PIN 2 hat Zugriff 
auf INT0)
-DCF77 Signal an PIND2, LED an PIND3.
-Sonstige Kritik erwünscht. Verfolge keine  „Mach-Mal“-Strategie. 
Möchte die Lösung nachvollziehen.
Vielen Dank im Voraus.
Michael

von Wolfgang (Gast)


Lesenswert?

Michael B. schrieb:
1
while(dcf77_sig==1)
2
  {
3
    PORTD|=1<<PIND3;
4
  }

Dein Interrupt hängt.
Wie soll das Programm jemals wieder aus der Schleife raus kommen.

von holger (Gast)


Lesenswert?

>Wie soll das Programm jemals wieder aus der Schleife raus kommen.

Nö, es geht gar nicht erst rein weil PIND2 = 4 ist;)

von holger (Gast)


Lesenswert?

>Nö, es geht gar nicht erst rein weil PIND2 = 4 ist;)

Natürlich ist PIND2 = 2.

von Wolfgang (Gast)


Lesenswert?

holger schrieb:
> Natürlich ist PIND2 = 2.

So weit hatte ich noch gar nicht geguckt ;-)

Wenn der Compiler gut ist und das erkennt, sollte er bei der Optimierung 
also die ganze ISR weg optimieren ...

von Michael B. (michaelba)


Lesenswert?

Okay ,
zunächst vielen Dank Euch beiden.
Dann verstehe ich jetzt zwei Sachen nicht:

- An welcher Stelle wird PIND2 der Wert 2 zugewiesen. Denkfehler von 
mir?
  (Dachte ein PIN kann nur 0 oder 1 annehmen, da PIND2 einem Bit 
entspricht.)

- in die ISR müsste das Programm doch eigentlich ohnehin springen wenn:
  TCNT1 dem Wert von OCR1A entspricht.
   --> OCF1A Flag in TIFR1 wird gesetzt.


Gruß

von Frank G. (frank_g53)


Lesenswert?

Michael B. schrieb:
> An welcher Stelle wird PIND2 der Wert 2 zugewiesen.

hier:
Michael B. schrieb:
> dcf77_sig = PIND2;

Du möchtest bestimmt den Pinstatus einlesen.
Ich glaube das muss so sein:
dcf77_sig=( PIND & ( 1<<PIND2 ) )

von Stefan F. (Gast)


Lesenswert?

Um den Pin D2 einzulesen schreibt man:

 dcf77_sig = PIND & (1<<PD2);

Oder

  dcf77_sig = (PIND >> PD2) & 1;

Wobei PD2 den Wert 2 hat.

Kannst ja mal darüber sinnieren, wo jetzt genau der Unterschied ist. So 
lernst du die wichtigsten Operatoren der µC Programmierung kennen.

von Frank G. (frank_g53)


Lesenswert?

Frank G. schrieb:
> Michael B. schrieb:
>> An welcher Stelle wird PIND2 der Wert 2 zugewiesen.
>
> hier:
> Michael B. schrieb:
>> dcf77_sig = PIND2;

falsch gelesen, einfach ignorieren.

von Stefan F. (Gast)


Lesenswert?

> An welcher Stelle wird PIND2 der Wert 2 zugewiesen.

PIND2 ist eine Konstante mit dem Wert 2. Sie steht in irgendeiner der 
zahlreichen Header Dateien, die von avr/io.h eingebunden werden.

> in die ISR müsste das Programm doch eigentlich ohnehin springen
> wenn: TCNT1 dem Wert von OCR1A entspricht.


Ja, und dann hängt der Prozessor in einer Sackgasse, weil deine 
Interruptroutine eine Endlosschleife enthält. Interruptroutinen werden 
nicht wiederum durch Interrupts unterbrochen.

von Michael B. (michaelba)


Lesenswert?

Alles klar,
vielen Dank an alle für Eure  Hilfsbereitschaft.
Es hat funktioniert.

@ Stefan US:
Den Unterschied deiner beiden Varianten habe ich soweit begriffen.

Wo aber liegt der Unterschied zu
dcf77_sig=( PIND & ( 1<<PIND2 ) )
von Frank G.

Also sprich:
1.  Warum die Klammern?
2.  Was unterscheidet PIND2 von PD2?

PIND sind ja die  Input-Pin-Adressen von PORT D.
PD2 ist doch eigtl. einfach der Name des Pins als solches, oder?


Gruß
Michael

von Stefan F. (Gast)


Lesenswert?

Du zusätzlichen (äußeren) Klammern bewirken nichts. PIND2 und PD2 haben 
beide den Wert 2.

>> PIND sind ja die Input-Pin-Adressen von PORT D.

Ja, aber PIND2 ist einfach nur eine 2. Keine Adresse und hat auch nicht 
Wirklich einen Bezug zu PD2.

Du kannst auch Schreiben: dcf77_sig=PIND & ( 1<<PINA2 )

Was allerdings aus Gründen der Lesbarkeit nicht ratsam ist. Funktioniert 
aber.

von Michael B. (michaelba)


Lesenswert?

Alles klar,
danke an alle.
Gruß
Michael

von Fred R. (fredylich)


Lesenswert?

Hallo,

muss die Programmierung zwingend in C sein?
Mit BASCOM gibt es eine sehr gute Lösung. Die Lib „DCF77“ (ASM) läst 
kaum Wünsche offen.
Wann synchronisiert werden soll oder welche Informationen noch benötigt 
werden.
Da kann ich auf jedem Fall mit meinen Erfahrungen weiter Helfen.

P.S. Habe noch ein paar Industrie DCF77 Aktivantennen, kleines Gehäuse 
IP54, für kleines Geld abzugeben.
Diese haben auch schon eine LED für Empfangsqualität.
Bitte beachten: Nur meine Unkosten sollten beglichen werden. Währ ja 
schade diese Dinger in den Restmüll zu werfen.

Mit freundlichen Grüßen

von Michael B. (michaelba)


Lesenswert?

Hallo Fred,

sorry, habe Deine Antwort erst jetzt gelesen.

Das Programm muss in C geschrieben sein, ja.
Es handelt sich um ein Projekt für die FH.

DCF77-Empfänger haben wir bereits zwei
(Und leben damit eigtl. im Überfluss)

Vielen Dank aber für Dein Angebot und die Bereitschaft zu helfen.

Gruß
Michael

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.