Hendrik Langer
7 years ago
11 changed files with 1108 additions and 51 deletions
@ -0,0 +1,376 @@ |
|||||
|
/*
|
||||
|
* Description: Clock |
||||
|
* Author: h3ndrik |
||||
|
* License: AGPLv3+ |
||||
|
*/ |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include <stdlib.h> |
||||
|
#include "../random/prng.h" |
||||
|
#include "../config.h" |
||||
|
#include "../pixel.h" |
||||
|
#include "../util.h" |
||||
|
|
||||
|
#ifndef COLOR_DEFAULT |
||||
|
#define COLOR_DEFAULT 3 |
||||
|
#endif |
||||
|
#ifndef COLOR_OFF |
||||
|
#define COLOR_OFF 0 |
||||
|
#endif |
||||
|
|
||||
|
uint8_t hours = 10; |
||||
|
uint8_t minutes = 25; |
||||
|
uint8_t seconds = 45; |
||||
|
|
||||
|
uint8_t oldhours = 0; |
||||
|
uint8_t oldminutes = 0; |
||||
|
|
||||
|
uint8_t time_update(void) |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
|
||||
|
//send request
|
||||
|
//time_request();
|
||||
|
minutes += seconds / 60; |
||||
|
seconds = seconds % 60; |
||||
|
hours += minutes / 60; |
||||
|
minutes = minutes % 60; |
||||
|
hours = hours % 12; |
||||
|
|
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
void set_funk(void) |
||||
|
{ |
||||
|
setpixel((pixel){ 3, 7},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 3, 6},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 3, 5},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 3, 4},COLOR_DEFAULT); |
||||
|
} |
||||
|
|
||||
|
void set_esistuhr(void) |
||||
|
{ |
||||
|
setpixel((pixel){ 0, 10},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 0, 9},COLOR_DEFAULT); |
||||
|
|
||||
|
setpixel((pixel){ 0, 7},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 0, 6},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 0, 5},COLOR_DEFAULT); |
||||
|
|
||||
|
setpixel((pixel){ 9, 2},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 9, 1},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 9, 0},COLOR_DEFAULT); |
||||
|
} |
||||
|
|
||||
|
void set_nach(void) |
||||
|
{ |
||||
|
setpixel((pixel){ 3, 3},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 3, 2},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 3, 1},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 3, 0},COLOR_DEFAULT); |
||||
|
} |
||||
|
|
||||
|
void set_vor(void) |
||||
|
{ |
||||
|
setpixel((pixel){ 3,10},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 3, 9},COLOR_DEFAULT); |
||||
|
setpixel((pixel){ 3, 8},COLOR_DEFAULT); |
||||
|
} |
||||
|
|
||||
|
void set_hour(uint8_t hour, unsigned char value) |
||||
|
{ |
||||
|
switch (hours) { |
||||
|
case 0: |
||||
|
//set_hour(11, COLOR_OFF);
|
||||
|
setpixel((pixel){ 8, 4},value); |
||||
|
setpixel((pixel){ 8, 3},value); |
||||
|
setpixel((pixel){ 8, 2},value); |
||||
|
setpixel((pixel){ 8, 1},value); |
||||
|
setpixel((pixel){ 8, 0},value); |
||||
|
break; |
||||
|
case 1: |
||||
|
//set_hour(0, COLOR_OFF);
|
||||
|
setpixel((pixel){ 5,10},value); |
||||
|
setpixel((pixel){ 5, 9},value); |
||||
|
setpixel((pixel){ 5, 8},value); |
||||
|
setpixel((pixel){ 5, 7},value); |
||||
|
break; |
||||
|
case 2: |
||||
|
//set_hour(1, COLOR_OFF);
|
||||
|
setpixel((pixel){ 5, 3},value); |
||||
|
setpixel((pixel){ 5, 2},value); |
||||
|
setpixel((pixel){ 5, 1},value); |
||||
|
setpixel((pixel){ 5, 0},value); |
||||
|
break; |
||||
|
case 3: |
||||
|
//set_hour(2, COLOR_OFF);
|
||||
|
setpixel((pixel){ 6,10},value); |
||||
|
setpixel((pixel){ 6, 9},value); |
||||
|
setpixel((pixel){ 6, 8},value); |
||||
|
setpixel((pixel){ 6, 7},value); |
||||
|
break; |
||||
|
case 4: |
||||
|
//set_hour(3, COLOR_OFF);
|
||||
|
setpixel((pixel){ 6, 3},value); |
||||
|
setpixel((pixel){ 6, 2},value); |
||||
|
setpixel((pixel){ 6, 1},value); |
||||
|
setpixel((pixel){ 6, 0},value); |
||||
|
break; |
||||
|
case 5: |
||||
|
//set_hour(4, COLOR_OFF);
|
||||
|
setpixel((pixel){ 4, 3},value); |
||||
|
setpixel((pixel){ 4, 2},value); |
||||
|
setpixel((pixel){ 4, 1},value); |
||||
|
setpixel((pixel){ 4, 0},value); |
||||
|
break; |
||||
|
case 6: |
||||
|
//set_hour(5, COLOR_OFF);
|
||||
|
setpixel((pixel){ 7,10},value); |
||||
|
setpixel((pixel){ 7, 9},value); |
||||
|
setpixel((pixel){ 7, 8},value); |
||||
|
setpixel((pixel){ 7, 7},value); |
||||
|
setpixel((pixel){ 7, 6},value); |
||||
|
break; |
||||
|
case 7: |
||||
|
//set_hour(6, COLOR_OFF);
|
||||
|
setpixel((pixel){ 8,10},value); |
||||
|
setpixel((pixel){ 8, 9},value); |
||||
|
setpixel((pixel){ 8, 8},value); |
||||
|
setpixel((pixel){ 8, 7},value); |
||||
|
setpixel((pixel){ 8, 6},value); |
||||
|
setpixel((pixel){ 8, 5},value); |
||||
|
break; |
||||
|
case 8: |
||||
|
//set_hour(7, COLOR_OFF);
|
||||
|
setpixel((pixel){ 7, 3},value); |
||||
|
setpixel((pixel){ 7, 2},value); |
||||
|
setpixel((pixel){ 7, 1},value); |
||||
|
setpixel((pixel){ 7, 0},value); |
||||
|
break; |
||||
|
case 9: |
||||
|
//set_hour(8, COLOR_OFF);
|
||||
|
setpixel((pixel){ 9, 7},value); |
||||
|
setpixel((pixel){ 9, 6},value); |
||||
|
setpixel((pixel){ 9, 5},value); |
||||
|
setpixel((pixel){ 9, 4},value); |
||||
|
break; |
||||
|
case 10: |
||||
|
//set_hour(9, COLOR_OFF);
|
||||
|
setpixel((pixel){ 9,10},value); |
||||
|
setpixel((pixel){ 9, 9},value); |
||||
|
setpixel((pixel){ 9, 8},value); |
||||
|
setpixel((pixel){ 9, 7},value); |
||||
|
break; |
||||
|
case 11: |
||||
|
//set_hour(10, COLOR_OFF);
|
||||
|
setpixel((pixel){ 4, 5},value); |
||||
|
setpixel((pixel){ 4, 4},value); |
||||
|
setpixel((pixel){ 4, 3},value); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void set_minute(uint8_t minute, unsigned char value) |
||||
|
{ |
||||
|
switch (minutes) { |
||||
|
case 0: |
||||
|
case 1: |
||||
|
case 2: |
||||
|
case 3: |
||||
|
case 4: |
||||
|
break; |
||||
|
case 5: |
||||
|
case 6: |
||||
|
case 7: |
||||
|
case 8: |
||||
|
case 9: |
||||
|
//set_minute(0, COLOR_OFF);
|
||||
|
/* fünf */ |
||||
|
setpixel((pixel){ 0, 3},value); |
||||
|
setpixel((pixel){ 0, 2},value); |
||||
|
setpixel((pixel){ 0, 1},value); |
||||
|
setpixel((pixel){ 0, 0},value); |
||||
|
set_nach(); |
||||
|
break; |
||||
|
case 10: |
||||
|
case 11: |
||||
|
case 12: |
||||
|
case 13: |
||||
|
case 14: |
||||
|
//set_minute(5, COLOR_OFF);
|
||||
|
/* zehn */ |
||||
|
setpixel((pixel){ 1,10},value); |
||||
|
setpixel((pixel){ 1, 9},value); |
||||
|
setpixel((pixel){ 1, 8},value); |
||||
|
setpixel((pixel){ 1, 7},value); |
||||
|
set_nach(); |
||||
|
break; |
||||
|
case 15: |
||||
|
case 16: |
||||
|
case 17: |
||||
|
case 18: |
||||
|
case 19: |
||||
|
//set_minute(10, COLOR_OFF);
|
||||
|
/* viertel */ |
||||
|
setpixel((pixel){ 2, 6},value); |
||||
|
setpixel((pixel){ 2, 5},value); |
||||
|
setpixel((pixel){ 2, 4},value); |
||||
|
setpixel((pixel){ 2, 3},value); |
||||
|
setpixel((pixel){ 2, 2},value); |
||||
|
setpixel((pixel){ 2, 1},value); |
||||
|
setpixel((pixel){ 2, 0},value); |
||||
|
set_nach(); |
||||
|
break; |
||||
|
case 20: |
||||
|
case 21: |
||||
|
case 22: |
||||
|
case 23: |
||||
|
case 24: |
||||
|
//set_minute(15, COLOR_OFF);
|
||||
|
/* zwanzig */ |
||||
|
setpixel((pixel){ 1, 6},value); |
||||
|
setpixel((pixel){ 1, 5},value); |
||||
|
setpixel((pixel){ 1, 4},value); |
||||
|
setpixel((pixel){ 1, 3},value); |
||||
|
setpixel((pixel){ 1, 2},value); |
||||
|
setpixel((pixel){ 1, 1},value); |
||||
|
setpixel((pixel){ 1, 0},value); |
||||
|
set_nach(); |
||||
|
break; |
||||
|
case 25: |
||||
|
case 26: |
||||
|
case 27: |
||||
|
case 28: |
||||
|
case 29: |
||||
|
//set_minute(20, COLOR_OFF);
|
||||
|
/* fünf */ |
||||
|
setpixel((pixel){ 0, 3},value); |
||||
|
setpixel((pixel){ 0, 2},value); |
||||
|
setpixel((pixel){ 0, 1},value); |
||||
|
setpixel((pixel){ 0, 0},value); |
||||
|
set_vor(); |
||||
|
/* halb */ |
||||
|
setpixel((pixel){ 4,10},value); |
||||
|
setpixel((pixel){ 4, 9},value); |
||||
|
setpixel((pixel){ 4, 8},value); |
||||
|
setpixel((pixel){ 4, 7},value); |
||||
|
break; |
||||
|
case 30: |
||||
|
case 31: |
||||
|
case 32: |
||||
|
case 33: |
||||
|
case 34: |
||||
|
//set_minute(25, COLOR_OFF);
|
||||
|
/* halb */ |
||||
|
setpixel((pixel){ 4,10},value); |
||||
|
setpixel((pixel){ 4, 9},value); |
||||
|
setpixel((pixel){ 4, 8},value); |
||||
|
setpixel((pixel){ 4, 7},value); |
||||
|
break; |
||||
|
case 35: |
||||
|
case 36: |
||||
|
case 37: |
||||
|
case 38: |
||||
|
case 39: |
||||
|
//set_minute(30, COLOR_OFF);
|
||||
|
/* fünf */ |
||||
|
setpixel((pixel){ 0, 3},value); |
||||
|
setpixel((pixel){ 0, 2},value); |
||||
|
setpixel((pixel){ 0, 1},value); |
||||
|
setpixel((pixel){ 0, 0},value); |
||||
|
set_nach(); |
||||
|
/* halb */ |
||||
|
setpixel((pixel){ 4,10},value); |
||||
|
setpixel((pixel){ 4, 9},value); |
||||
|
setpixel((pixel){ 4, 8},value); |
||||
|
setpixel((pixel){ 4, 7},value); |
||||
|
break; |
||||
|
case 40: |
||||
|
case 41: |
||||
|
case 42: |
||||
|
case 43: |
||||
|
case 44: |
||||
|
//set_minute(35, COLOR_OFF);
|
||||
|
/* zwanzig */ |
||||
|
setpixel((pixel){ 1, 6},value); |
||||
|
setpixel((pixel){ 1, 5},value); |
||||
|
setpixel((pixel){ 1, 4},value); |
||||
|
setpixel((pixel){ 1, 3},value); |
||||
|
setpixel((pixel){ 1, 2},value); |
||||
|
setpixel((pixel){ 1, 1},value); |
||||
|
setpixel((pixel){ 1, 0},value); |
||||
|
set_vor(); |
||||
|
break; |
||||
|
case 45: |
||||
|
case 46: |
||||
|
case 47: |
||||
|
case 48: |
||||
|
case 49: |
||||
|
//set_minute(40, COLOR_OFF);
|
||||
|
/* viertel */ |
||||
|
setpixel((pixel){ 2, 6},value); |
||||
|
setpixel((pixel){ 2, 5},value); |
||||
|
setpixel((pixel){ 2, 4},value); |
||||
|
setpixel((pixel){ 2, 3},value); |
||||
|
setpixel((pixel){ 2, 2},value); |
||||
|
setpixel((pixel){ 2, 1},value); |
||||
|
setpixel((pixel){ 2, 0},value); |
||||
|
set_vor(); |
||||
|
break; |
||||
|
case 50: |
||||
|
case 51: |
||||
|
case 52: |
||||
|
case 53: |
||||
|
case 54: |
||||
|
//set_minute(45, COLOR_OFF);
|
||||
|
/* zehn */ |
||||
|
setpixel((pixel){ 1,10},value); |
||||
|
setpixel((pixel){ 1, 9},value); |
||||
|
setpixel((pixel){ 1, 8},value); |
||||
|
setpixel((pixel){ 1, 7},value); |
||||
|
set_vor(); |
||||
|
break; |
||||
|
case 55: |
||||
|
case 56: |
||||
|
case 57: |
||||
|
case 58: |
||||
|
case 59: |
||||
|
//set_minute(50, COLOR_OFF);
|
||||
|
/* fünf */ |
||||
|
setpixel((pixel){ 0, 3},value); |
||||
|
setpixel((pixel){ 0, 2},value); |
||||
|
setpixel((pixel){ 0, 1},value); |
||||
|
setpixel((pixel){ 0, 0},value); |
||||
|
set_vor(); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void wordclock(void) |
||||
|
{ |
||||
|
while (1) { |
||||
|
|
||||
|
if(time_update() == 0) |
||||
|
{ |
||||
|
set_funk(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (oldminutes != minutes) { |
||||
|
clear_screen(COLOR_OFF); |
||||
|
set_minute(minutes, COLOR_DEFAULT); |
||||
|
oldminutes = minutes; |
||||
|
|
||||
|
//if (oldhours != hours) {
|
||||
|
set_hour(hours, COLOR_DEFAULT); |
||||
|
// oldhours = hours;
|
||||
|
//}
|
||||
|
|
||||
|
set_esistuhr(); |
||||
|
} |
||||
|
|
||||
|
wait(10); /* milliseconds */ |
||||
|
seconds++; |
||||
|
} |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
MAKETOPDIR = ../.. |
||||
|
|
||||
|
TARGET = objects |
||||
|
|
||||
|
include $(MAKETOPDIR)/defaults.mk |
||||
|
|
||||
|
SRC = dcf77.c |
||||
|
|
||||
|
include $(MAKETOPDIR)/rules.mk |
||||
|
|
||||
|
include $(MAKETOPDIR)/depend.mk |
@ -0,0 +1,16 @@ |
|||||
|
|
||||
|
dep_bool_menu "DCF77 Support" DCF77_SUPPORT y |
||||
|
|
||||
|
if [ "$DCF77_SUPPORT" = "y" ]; then |
||||
|
|
||||
|
## define_int USER_TIMER0_FOR_WAIT 1 |
||||
|
|
||||
|
choice 'DCF Interrupt' \ |
||||
|
"Int0 0 \ |
||||
|
Int1 1" \ |
||||
|
'Int0' DCF_INTERRUPT |
||||
|
|
||||
|
|
||||
|
fi |
||||
|
|
||||
|
endmenu |
@ -0,0 +1,513 @@ |
|||||
|
#define MCU atmega32 |
||||
|
#include <stdlib.h> |
||||
|
#include <stdint.h> |
||||
|
#include <string.h> // memcpy |
||||
|
#ifdef __AVR__ |
||||
|
#include <avr/io.h> |
||||
|
#include <avr/interrupt.h> |
||||
|
#endif |
||||
|
|
||||
|
#include "../config.h" |
||||
|
|
||||
|
#include "../util.h" |
||||
|
#include "dcf77.h" |
||||
|
|
||||
|
#if DCF_INTERRUPT == 0 |
||||
|
#define DCF77_INT_ENABLE() GICR |= (1<<INT0); |
||||
|
#define DCF77_INT_CONTROL MCUCR |
||||
|
#define DCF77_INT_FALLING_EDGE 0x02 |
||||
|
#define DCF77_INT_RISING_EDGE 0x03 |
||||
|
#elif DCF_INTERRUPT == 1 |
||||
|
#endif |
||||
|
|
||||
|
#define DCFminpulsewidth 50/1000 * FREQ/1024 |
||||
|
#define DCFsplitpulsewidth 180/1000 * FREQ/1024 |
||||
|
#define DCFmaxpulsewidth 280/1000 * FREQ/1024 |
||||
|
#define DCFsecondwidth FREQ/1024 |
||||
|
|
||||
|
/* the currently recieving timestamp */ |
||||
|
sTimeStamp time; |
||||
|
|
||||
|
int8_t tick_number; |
||||
|
uint8_t ticks_inwindow; |
||||
|
uint8_t ticks; |
||||
|
uint8_t ticks_max; |
||||
|
int8_t ticks_max_pos; |
||||
|
|
||||
|
sDCF dcfdata; |
||||
|
sDCF dcfdata_lastvalid; |
||||
|
uint8_t dcf_bit_counter; |
||||
|
uint8_t funksignal; |
||||
|
|
||||
|
void update_dcftimestamp (sDCF *dcftimestamp) { |
||||
|
uint8_t daysinmonth; |
||||
|
switch (dcftimestamp->month) { |
||||
|
case 1: |
||||
|
case 3: |
||||
|
case 5: |
||||
|
case 7: |
||||
|
case 8: |
||||
|
case 10: |
||||
|
case 12: |
||||
|
daysinmonth = 31; |
||||
|
break; |
||||
|
case 2: |
||||
|
daysinmonth = 29; |
||||
|
break; |
||||
|
case 4: |
||||
|
case 6: |
||||
|
case 9: |
||||
|
case 11: |
||||
|
default: |
||||
|
daysinmonth = 30; |
||||
|
break; |
||||
|
} |
||||
|
dcftimestamp->minute++; |
||||
|
// dcftimestamp->second++;
|
||||
|
// dcftimestamp->minute += dcftimestamp->second / 60;
|
||||
|
dcftimestamp->hour += dcftimestamp->minute / 60; |
||||
|
dcftimestamp->day += dcftimestamp->hour / 24; |
||||
|
dcftimestamp->weekday += dcftimestamp->hour / 24; |
||||
|
dcftimestamp->month += dcftimestamp->day / (daysinmonth+1); |
||||
|
dcftimestamp->year += dcftimestamp->month / 12; |
||||
|
|
||||
|
// dcftimestamp->second = dcftimestamp->second % 60;
|
||||
|
dcftimestamp->minute = dcftimestamp->minute % 60; |
||||
|
dcftimestamp->hour = dcftimestamp->hour % 24; |
||||
|
dcftimestamp->day = dcftimestamp->day % (daysinmonth+1); |
||||
|
if (dcftimestamp->day == 0) dcftimestamp->day++; |
||||
|
dcftimestamp->weekday = dcftimestamp->weekday % 8; |
||||
|
if (dcftimestamp->weekday == 0) dcftimestamp->weekday++; |
||||
|
dcftimestamp->month = dcftimestamp->month % 13; |
||||
|
if (dcftimestamp->month == 0) dcftimestamp->month++; |
||||
|
} |
||||
|
|
||||
|
uint8_t dcfsanitycheck(sDCF *dcftimestamp) { |
||||
|
if (dcftimestamp->error != 0) |
||||
|
return 1; |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//64 Bit für DCF77 benötigt werden 59 Bits
|
||||
|
//volatile unsigned long long dcf_rx_buffer = 0;
|
||||
|
|
||||
|
void dcf_pulse(uint8_t bit_counter, uint8_t value) |
||||
|
{ |
||||
|
dcfdata.complete++; |
||||
|
switch(bit_counter) |
||||
|
{ |
||||
|
case 0: //Start einer neuen Minute, ist immer 0
|
||||
|
if (dcfdata.error == 0 && dcfdata.complete >= 58) { |
||||
|
//if (abs(time.year - dcfdata.year) <= 2)
|
||||
|
// update_dcftimestamp(&dcfdata_lastvalid);
|
||||
|
// if ( dcfdata.year == dcfdata_lastvalid.year
|
||||
|
// && dcfdata.month == dcfdata_lastvalid.month
|
||||
|
// && dcfdata.day == dcfdata_lastvalid.day
|
||||
|
// && dcfdata.hour == dcfdata_lastvalid.hour
|
||||
|
// && dcfdata.minute == dcfdata_lastvalid.minute)
|
||||
|
// {
|
||||
|
time.year = dcfdata.year; |
||||
|
time.month = dcfdata.month; |
||||
|
time.day = dcfdata.day; |
||||
|
time.minute = dcfdata.minute; |
||||
|
time.second = 0; |
||||
|
time.hour = dcfdata.hour; |
||||
|
time.valid = 1; |
||||
|
// }
|
||||
|
/* there is a valid timestamp in the variable. Copy it! */ |
||||
|
memcpy( &dcfdata, &dcfdata_lastvalid, sizeof( dcfdata_lastvalid ) ); |
||||
|
} |
||||
|
|
||||
|
dcfdata.error = 0; |
||||
|
dcfdata.complete = 1; |
||||
|
if (value == 0) { |
||||
|
//Start einer neuen Minute, ist immer 0
|
||||
|
} else if (value == 1) { |
||||
|
dcfdata.error++; |
||||
|
} |
||||
|
|
||||
|
break; |
||||
|
case 1: ;break; //Wetterdaten MeteoTime
|
||||
|
case 2: ;break; //Wetterdaten
|
||||
|
case 3: ;break; //Wetterdaten
|
||||
|
case 4: ;break; //Wetterdaten
|
||||
|
case 5: ;break; //Wetterdaten
|
||||
|
case 6: ;break; //Wetterdaten
|
||||
|
case 7: ;break; //Wetterdaten
|
||||
|
case 8: ;break; //Wetterdaten
|
||||
|
case 9: ;break; //Wetterdaten
|
||||
|
case 10: ;break; //Wetterdaten
|
||||
|
case 11: ;break; //Wetterdaten
|
||||
|
case 12: ;break; //Wetterdaten
|
||||
|
case 13: ;break; //Wetterdaten
|
||||
|
case 14: ;break; //Wetterdaten
|
||||
|
case 15: ;break; //Rufbit für PTB
|
||||
|
case 16: |
||||
|
if (value == 0) { |
||||
|
//Keine Änderung der Zeitzone
|
||||
|
} else if (value == 1) { |
||||
|
//Am Ende dieser Stunde wird MEZ/MESZ umgestellt.
|
||||
|
} |
||||
|
break; |
||||
|
case 17: |
||||
|
if (value == 0) { |
||||
|
//Zeitzone: MEZ
|
||||
|
} else if (value == 1) { |
||||
|
//Zeitzone: MESZ
|
||||
|
} |
||||
|
break; |
||||
|
case 18: |
||||
|
if (value == 0) { |
||||
|
//Zeitzone: MESZ
|
||||
|
} else if (value == 1) { |
||||
|
//Zeitzone: MEZ
|
||||
|
} |
||||
|
break; |
||||
|
case 19: |
||||
|
if (value == 0) { |
||||
|
//keine Schaltsekunde
|
||||
|
} else if (value == 1) { |
||||
|
//Am Ende dieser Stunde wird eine Schaltsekunde eingefügt.
|
||||
|
} |
||||
|
break; |
||||
|
case 20: //Beginn der Zeitinformation, ist immer 1
|
||||
|
dcfdata.minute = 0; |
||||
|
dcfdata.minute_parity = 0; |
||||
|
dcfdata.hour = 0; |
||||
|
dcfdata.hour_parity = 0; |
||||
|
dcfdata.day = 0; |
||||
|
dcfdata.weekday = 0; |
||||
|
dcfdata.month = 0; |
||||
|
dcfdata.year = 0; |
||||
|
dcfdata.date_parity = 0; |
||||
|
if (value == 0) { |
||||
|
dcfdata.error++; |
||||
|
} else if (value == 1) { |
||||
|
//Beginn der Zeitinformation, ist immer 1
|
||||
|
} |
||||
|
break; |
||||
|
case 21: // Minute (Einer)
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.minute+=1;dcfdata.minute_parity+=1; |
||||
|
} break; |
||||
|
case 22: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.minute+=2;dcfdata.minute_parity+=1; |
||||
|
} break; |
||||
|
case 23: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.minute+=4;dcfdata.minute_parity+=1; |
||||
|
} break; |
||||
|
case 24: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.minute+=8;dcfdata.minute_parity+=1; |
||||
|
} break; |
||||
|
case 25: // Minute (Zehner)
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.minute+=10;dcfdata.minute_parity+=1; |
||||
|
} break; |
||||
|
case 26: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.minute+=20;dcfdata.minute_parity+=1; |
||||
|
} break; |
||||
|
case 27: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.minute+=40;dcfdata.minute_parity+=1; |
||||
|
} break; |
||||
|
case 28: //Parität Minute
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.minute_parity+=1; |
||||
|
} |
||||
|
if (dcfdata.minute_parity%2 != 0) { |
||||
|
dcfdata.error++; |
||||
|
} |
||||
|
if (dcfdata.minute >= 60) |
||||
|
dcfdata.error++; |
||||
|
break; |
||||
|
case 29: // Stunde (Einer)
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.hour+=1;dcfdata.hour_parity+=1; |
||||
|
} break; |
||||
|
case 30: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.hour+=2;dcfdata.hour_parity+=1; |
||||
|
} break; |
||||
|
case 31: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.hour+=4;dcfdata.hour_parity+=1; |
||||
|
} break; |
||||
|
case 32: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.hour+=8;dcfdata.hour_parity+=1; |
||||
|
} break; |
||||
|
case 33: // Stunde (Zehner)
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.hour+=10;dcfdata.hour_parity+=1; |
||||
|
} break; |
||||
|
case 34: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.hour+=20;dcfdata.hour_parity+=1; |
||||
|
} break; |
||||
|
case 35: // Parität Stunde
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.hour_parity+=1; |
||||
|
} |
||||
|
if (dcfdata.hour_parity%2 != 0) { |
||||
|
dcfdata.error++; |
||||
|
} |
||||
|
if (dcfdata.hour > 24) |
||||
|
dcfdata.error++; |
||||
|
break; |
||||
|
case 36: // Kalendertag (Einer)
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.day+=1;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 37: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.day+=2;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 38: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.day+=4;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 39: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.day+=8;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 40: // Kalendertag (Zehner)
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.day+=10;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 41: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.day+=20;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 42: // Wochentag
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.weekday+=1;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 43: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.weekday+=2;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 44: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.weekday+=4;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 45: // Monatsnummer (Einer)
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.month+=1;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 46: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.month+=2;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 47: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.month+=4;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 48: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.month+=8;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 49: // Monatsnummer (Zehner)
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.month+=10;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 50: // Jahr (Einer)
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.year+=1;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 51: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.year+=2;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 52: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.year+=4;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 53: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.year+=8;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 54: // Jahr (Zehner)
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.year+=10;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 55: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.year+=20;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 56: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.year+=40;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 57: |
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.year+=80;dcfdata.date_parity+=1; |
||||
|
} break; |
||||
|
case 58: // Parität Datum
|
||||
|
if (value == 0) { |
||||
|
} else if (value == 1) { |
||||
|
dcfdata.date_parity+=1; |
||||
|
} |
||||
|
if (dcfdata.date_parity%2 != 0) { |
||||
|
dcfdata.error++; |
||||
|
} |
||||
|
if (dcfdata.day > 31) |
||||
|
dcfdata.error++; |
||||
|
if (dcfdata.month > 12) |
||||
|
dcfdata.error++; |
||||
|
break; |
||||
|
case 59: ;break; // keine Sekundenmarke --> neue Minute
|
||||
|
// wird nur bei einer Schaltsekunde erreicht
|
||||
|
default: ;break; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
void dcf77_init(void) { |
||||
|
// set pin mode dcf77_pin
|
||||
|
DDRD &= ~(1 << PD2); // set PORTD2 as input
|
||||
|
//PORTD |= (1 << PD2); // set internal pull-up
|
||||
|
// set interrupt
|
||||
|
// DCF77_INT_ENABLE();
|
||||
|
// DCF77_INT_CONTROL = DCF77_INT_RISING_EDGE;
|
||||
|
|
||||
|
// TCNT1 = 63035; // 65535 - (FREQ/64)/100; (overflow every 10ms)
|
||||
|
// TCCR1A = 0x00; // normal operation
|
||||
|
// TCCR1B = ((0<<CS12) | (1<<CS11) | (1<<CS10)); // set TIMER1 Prescaler to 64
|
||||
|
// TIMSK |= (1 << TOIE1); // TIMER1 Overflow Interrupt
|
||||
|
|
||||
|
TCCR2 = _BV(WGM21); // CTC mode
|
||||
|
TCCR2 |= _BV(CS22) | _BV(CS21) | _BV(CS20); // clk/1024
|
||||
|
OCR2 = (F_CPU/102400); //100Hz
|
||||
|
// TCNT2 = 0;
|
||||
|
TIMSK |= (1 << OCIE2); |
||||
|
|
||||
|
sei(); |
||||
|
|
||||
|
|
||||
|
time.valid = 0; |
||||
|
} |
||||
|
|
||||
|
//ISR(DCF77_INT_VECT, ISR_BLOCK) {
|
||||
|
//}
|
||||
|
|
||||
|
ISR(TIMER2_COMP_vect, ISR_BLOCK) { |
||||
|
/* every 10ms */ |
||||
|
// cli();
|
||||
|
tick_number++; |
||||
|
if (PIND & (1<<PD2)) { |
||||
|
if (ticks < 253) ticks += 2; |
||||
|
if (ticks > ticks_max) { |
||||
|
ticks_max = ticks; |
||||
|
ticks_max_pos = tick_number; |
||||
|
} |
||||
|
if (tick_number <= 35) |
||||
|
ticks_inwindow++; |
||||
|
} |
||||
|
else { |
||||
|
if (ticks > 0) ticks -= 1; |
||||
|
} |
||||
|
|
||||
|
/* second elapsed */ |
||||
|
if (tick_number >= 100) |
||||
|
{ |
||||
|
time.second++; |
||||
|
time.minute += time.second / 60; |
||||
|
time.second = time.second % 60; |
||||
|
time.hour += time.minute / 60; |
||||
|
time.minute = time.minute % 60; |
||||
|
time.hour = time.hour % 24; |
||||
|
|
||||
|
|
||||
|
if (ticks_inwindow < 5) { |
||||
|
/* too short / new minute */ |
||||
|
dcf_bit_counter=0; |
||||
|
} else if (ticks_inwindow < 18) { |
||||
|
/* zero */ |
||||
|
dcf_pulse(dcf_bit_counter, 0); |
||||
|
dcf_bit_counter++; |
||||
|
} else if (ticks_inwindow < 28) { |
||||
|
/* one */ |
||||
|
dcf_pulse(dcf_bit_counter, 1); |
||||
|
dcf_bit_counter++; |
||||
|
} else { |
||||
|
/* too long, instead: identify by position */ |
||||
|
if (ticks_max_pos <= 25 && ticks_max_pos >= 15) { |
||||
|
dcf_pulse(dcf_bit_counter, 0); |
||||
|
} else if (ticks_max_pos <= 35 && ticks_max_pos >= 25) { |
||||
|
dcf_pulse(dcf_bit_counter, 1); |
||||
|
} else { |
||||
|
dcfdata.error++; |
||||
|
} |
||||
|
dcf_bit_counter++; |
||||
|
} |
||||
|
|
||||
|
/* blink if signal and unimportant weather data */ |
||||
|
if (ticks_inwindow > 5 && ticks_inwindow < 28 && dcf_bit_counter > 1 && dcf_bit_counter < 14) |
||||
|
funksignal = dcf_bit_counter & 1; |
||||
|
else |
||||
|
funksignal = 0; |
||||
|
|
||||
|
tick_number = 0; |
||||
|
/* move signal closer to tick_number 0 */ |
||||
|
if (ticks < 194) { |
||||
|
if (ticks_max_pos > 20+15) { |
||||
|
tick_number = -2; |
||||
|
} else if (ticks_max_pos < 10+5) { |
||||
|
tick_number = 2; |
||||
|
} |
||||
|
} else { |
||||
|
funksignal = 1; |
||||
|
} |
||||
|
|
||||
|
ticks = 0; |
||||
|
ticks_max= 0; |
||||
|
ticks_max_pos = 0; |
||||
|
ticks_inwindow = 0; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// sei();
|
||||
|
} |
@ -0,0 +1,53 @@ |
|||||
|
#ifndef DFC77_H |
||||
|
#define DCF77_H |
||||
|
#endif |
||||
|
|
||||
|
#ifdef __AVR__ |
||||
|
# include <avr/io.h> |
||||
|
#endif |
||||
|
|
||||
|
#include "../config.h" |
||||
|
|
||||
|
#if DCF_INTERRUPT == 0 |
||||
|
#define DCF77_INT_VECT (INT0_vect) |
||||
|
#elif DCF_INTERRUPT == 1 |
||||
|
#define DCF77_INT_VECT (INT1_vect) |
||||
|
#endif |
||||
|
|
||||
|
/* Timestamp definition */ |
||||
|
typedef struct { |
||||
|
uint16_t year; |
||||
|
uint8_t month; |
||||
|
uint8_t day; |
||||
|
uint8_t hour; |
||||
|
uint8_t minute; |
||||
|
uint8_t second; |
||||
|
uint8_t valid; |
||||
|
} sTimeStamp; |
||||
|
|
||||
|
extern sTimeStamp time; |
||||
|
|
||||
|
extern uint8_t funksignal; |
||||
|
|
||||
|
/* DCF Data */ |
||||
|
typedef struct { |
||||
|
uint8_t minute; |
||||
|
uint8_t hour; |
||||
|
uint8_t day; |
||||
|
uint8_t weekday; |
||||
|
uint8_t month; |
||||
|
uint8_t year; |
||||
|
|
||||
|
uint8_t minute_parity; |
||||
|
uint8_t hour_parity; |
||||
|
uint8_t date_parity; |
||||
|
|
||||
|
// uint8_t timezone;
|
||||
|
// uint8_t second;
|
||||
|
uint8_t error; |
||||
|
uint8_t complete; |
||||
|
} sDCF; |
||||
|
|
||||
|
void dcf77_init(void); |
||||
|
|
||||
|
//void dcf77_getTime(pTimeStamp ts);
|
Loading…
Reference in new issue