#include "clock.h" // returns -1 on error unsigned char getBits(const DCF start, const char len, const DCF pbit) { static const unsigned char mult[] = {1, 2, 4, 8, 10, 20 ,40 ,80}; /// unsigned char p = 1; //parity unsigned char r = 0; // retval unsigned char i; for(i=0; i 59) | /// (getBits(DCF_HOUR, 6, DCF_HOURP) == -1) /// ) return; // set new time t_current.m = (getBits(DCF_MIN, 7, DCF_START)) - 1; t_current.h = (getBits(DCF_HOUR, 6, DCF_START)); t_current.dd = (getBits(DCF_DAY, 6, DCF_START)); t_current.wd = (getBits(DCF_WEEKDAY, 3, DCF_START)); t_current.mm = (getBits(DCF_MONTH, 5, DCF_START)); t_current.yy = (getBits(DCF_YEAR, 8, DCF_START)); } // 7372800/a=10000 // 115200 / a * x = 10000 // 7372800/8/150 ISR(TIMER0_COMP_vect) // called 10000 times per second (12000000/8/150) { //cli(); // F_CPU / PRESCALER / (OCR0 + 1) if(++t_current.us >= 10) // one u-second { t_current.us = 0; // restart // interval length of dcf77 can be greater than 1000 ms... count it! ++interval; /* cli(); if(t_current.ms <= 500) { OCR1A = 50 + (200 - (t_current.ms / 3)); } else { OCR1A = 50 + (200 - ((1000 - t_current.ms) / 3)); } sei(); */ if(++t_current.ms >= 1000) // one second { t_current.ms = 0; // restart if(++t_current.s > 59) // one minute { t_current.s = 0; // restart if(++t_current.m > 59) // one hour { t_current.m = 0; // restart if(++t_current.h > 23) // one day { t_current.h = 0; // restart t_current.dd++; } } } } } //sei(); } ISR(INT0_vect) { /// stdout_put_int(interval, uart_putc); /// stdout_put_string("INT0 call\n", uart_putc); cli(); if(INT0_CONTROL == INT0_RISING_EDGE) { if(interval > 1000 && interval < 2000) // 59th second - no rising edge at the beginning { /// if(dcf77_bit == 59) // check if every bit has been transfered set_dcf_value(); // completely received- apply new time data // 59th second: synchronize with receiver... dcf77_bit = 0; TCNT0 = 0; t_current.s = 0; t_current.ms = 0; t_current.us = 0; } INT0_CONTROL = INT0_FALLING_EDGE; } else // INT0_FALLING_EDGE { dcf77[dcf77_bit++].bit = interval >= 200 ? 1 : 0; lastinterval = interval; INT0_CONTROL = INT0_RISING_EDGE; } interval = 0; // reset interval to count next interval sei(); } void timer_init() { // 7372800/8 DDRD &= ~((1<