Hallo Leute,
Will zur Übung mit uCs und aus Spaß an der Freude eine DCF77-Uhr bauen.
Zuerst wollte ich mir dazu auf irgendeine Weise das Signal ausgeben
lassen. Meine erster Ansatz: ich lasse mir die Pulsdauer (als einfacher
Timerwert) auf ein 2x16 Display schreiben.
Conrad DCF Modul an PortD
http://www.conrad.de/ce/de/product/641138/Conrad-DCF-Empfaengerplatine
P.Fleurys LCD-Bib, LCD an PORTA
http://homepage.hispeed.ch/peterfleury/avr-software.html#libs
easyAVR6-Board (Pullups/downs am Board werden nicht genutzt)
Atmega16, 8Mhz int.RC, Timer1, Prescaler 1024.
Erwarten würde ich, dass ich, da Input Capture ja sowohl auf fallende
als auch steigende Flanken reagieren sollte, für die 0,1-Sek.-Pulse
ICR1-Werte um 780(für 0,2-Sek.-Pulse um 1550, für 0,9-Sek.-Pausen um
7000, für 0,8-Sek.-Pausen 6250) bekommen würde.
Dem ist aber leider überhaupt nicht so. Die ausgegebenen Werte liegen
alle etwa in den Bereichen 8800+-100, 8050+-100, 7200+-100.
Die einzige Erklärung die ich dafür finden konnte ist, dass nicht alle
Flanken erkannt werden. Ist diese Erklärung evtl falsch? Wenn ja, wo ist
mein Denkfehler? Wenn nein, woran könnte es liegen, bzw. was kann ich
dagegen tun?
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<stdio.h>
4
#include<string.h>
5
6
#include"lcd.h"
7
#define LCD_BL 2
8
9
volatilelongintpulsewidth1=0;
10
volatilelongintpulsewidth2=0;
11
volatileuint8_ta=0;
12
charLCD_string[10];
13
14
15
intmain(void){
16
lcd_init(LCD_DISP_ON);
17
DDRA|=(1<<LCD_BL);// Pin unbelegt -> Ausgang
18
PORTA|=(1<<LCD_BL);
19
20
DDRD&=~(1<<DDD6);// PD6 Eingang
21
PORTD=(1<<PD6);// Pullup, da DCF-Modul OpenCollector
Nachtrag: Der einzige sinnvolle Wert kommt jede Minute beim
ausgelassenen 59. Bit, welches einer Pause von 1,8 Sek bzw 1,9 Sek (also
Timerwert um ca 15000) entspricht.
K. S. schrieb:> Erwarten würde ich, dass ich, da Input Capture ja sowohl auf fallende> als auch steigende Flanken reagieren sollte, für die 0,1-Sek.-Pulse> ICR1-Werte um 780(für 0,2-Sek.-Pulse um 1550, für 0,9-Sek.-Pausen um> 7000, für 0,8-Sek.-Pausen 6250) bekommen würde.
Soweit erstmal nachvollziehbare Überlegungen. Und da es lobens- und
fördernswert ist, wenn noch jemand selber denkt, tatsächlich noch ein
kleiner Hinweis:
> Dem ist aber leider überhaupt nicht so. Die ausgegebenen Werte liegen> alle etwa in den Bereichen 8800+-100, 8050+-100, 7200+-100.
Und was passiert, wenn du vor jeder Ausgabe erstmal das Display komplett
löschst (oder zumindest den Bereich, in dem die Ausgaben erfolgen, also
wenigstens 4 Zeichen)...
Problem erkennt?
K. S. schrieb:> Erwarten würde ich, dass ich, da Input Capture ja sowohl auf fallende> als auch steigende Flanken reagieren sollte...
Richtig!
Entweder wird auf die fallende oder auf die steigende Flanke reagiert.
Welche davon, das wird durch Bit ICES1 in TCCR1B festgelegt.
c-hater schrieb:> Und was passiert, wenn du vor jeder Ausgabe erstmal das Display komplett> löschst (oder zumindest den Bereich, in dem die Ausgaben erfolgen, also> wenigstens 4 Zeichen
Das stimmt natürlich, danke.
test schrieb:> Entweder wird auf die fallende oder auf die steigende Flanke reagiert.> Welche davon, das wird durch Bit ICES1 in TCCR1B festgelegt.
Dieses Bit ist mir überhaupt nicht aufgefallen, danke. Das heißt also,
ich müsste das Bit jedes Mal im Interrupt Checken und entsprechend
setzen bzw. löschen.
1
ISR(TIMER1_CAPT_vect){
2
pulsewidth_new=ICR1;
3
TCNT1=0;
4
if(TCCR1B&&(1<<ICES1)){// Wenn steigende Flanke aktiv