1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
// vim:set et sw=2 ts=2 tw=120:
#include "dcf77.h"
// 7372800/a=10000
// 115200 / a * x = 10000
// 7372800/8/150
// returns -1 on error
unsigned char getBits(const DCF start, const char len)
{
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<len; i++)
r += dcf77[start+i].bit * mult[i];
/// if(dcf77[start+i].bit)
/// p ^= 1;
return r;
}
// interrupt service routine (ISR) for timer 0 A compare match
ISR(TIMER0_COMPB_vect)
{
}
// ISR(TIMER0A_COMP_vect)
ISR(TIMER0_COMPA_vect)
{
interval++;
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++;
}
}
}
}
}
ISR(INT0_vect)
{
}
ISR(PCINT0_vect)
{
// if(INT0_CONTROL == INT0_RISING_EDGE)
// if(MCUCR & (1<<ISC00))
// {
if (interval > 1000 && interval < 2000) // 59th second - no rising edge at the beginning
{
if(dcf77_bit == 59) // check if every bit has been transfered
{
t_current.m = getBits(DCF_MIN, 7);
t_current.h = getBits(DCF_HOUR, 6);
t_current.dd = getBits(DCF_DAY, 6);
t_current.wd = getBits(DCF_WEEKDAY, 3);
t_current.mm = getBits(DCF_MONTH, 5);
t_current.yy = getBits(DCF_YEAR, 8);
}
// 59th second: synchronize with receiver...
dcf77_bit = 0;
t_current.s = 0;
t_current.ms = 0;
// falling edge causes interrupt...
// INT0_CONTROL = INT0_FALLING_EDGE;
}
else // INT0_FALLING_EDGE
{
if(interval > 50 && interval < 150)
dcf77[dcf77_bit++].bit = 0;
else if(interval > 150 && interval < 250)
dcf77[dcf77_bit++].bit = 1;
// rising edge causes interrupt...
// INT0_CONTROL = INT0_RISING_EDGE;
}
TCNT0 = 0;
interval = 0;
}
/*
void timer_init()
{
// 7372800/8
// >>>>>> DDRD &= ~((1<<PD2) | (1<<PD3)); // make INT0 and INT1 input-pins
// Prescaler...
// output compare...
//OCR0 = 152 - 1;
//TCCR0 |= (0<<WGM01) | (1<<WGM01);
// ICNC1 (Input Capture Noise Canceler (4 CKs) Timer/Counter 1
// ICES1 (Input Capture Edge Select Timer/Counter 1) - 1:increasing 0:falling
// CSx: set prescaler (010 means 8)
/// TCCR1B = (1<<ICNC1) | (1<<ICES1) | (0<<CS12) | (1<<CS11) | (0<<CS10);
// OCIE0: Output Compare Match Interrupt Enable
// TICIE: Timer/Counter Input Capture Interrupt Enable
// interrupts_init...
// General Interrupt Mask Register (enables interrupts)
GIMSK |= (1<<INT0);
// GICR |= (1<<INT0);
// MCU Control Register (controls CPU-behaviours like interrupts & sleepmode)
MCUCR |= (1<<ISC01) | (1<<ISC00); // any logical change generates interrupt
INT0_CONTROL = INT0_RISING_EDGE; // going to toggle int0-behaviour
/// loworhigh.bit = 0;
}
*/
|