main.c


1
/*
2
 * main.c
3
 *
4
 * Created: 01.10.2018 10:34:47
5
 * Author : Ingo
6
 */ 
7
8
#include <avr/io.h>
9
#include <stdint.h>
10
#include <string.h>
11
#include <avr/interrupt.h>
12
13
14
#define DCF77_DDR    DDRD
15
#define DCF77_PORT    PORTD
16
#define DCF77_PIN    PD0
17
#define ONE_PULSE_TIME  200
18
#define ZERO_PULSE_TIME  100
19
#define PERIOD      1000
20
21
#define BEGIN_ZEITINFO  20
22
#define BEGIN_MINUTE  21
23
#define ENDE_MINUTE    27
24
#define PARI_MINUTE    28
25
#define BEGIN_STUNDE  29
26
#define ENDE_STUNDE    34
27
#define PARI_STUNDE    35
28
29
#define TIMEBASE_1MS  TIMER1_COMPA_vect
30
31
static void LogicalOne ( const int16_t *Millis );
32
static void LogicalZero ( const int16_t *Millis );
33
34
struct {
35
  struct {
36
    uint8_t ByteMinute, ByteHour;
37
  }bcd;
38
  
39
  uint8_t ParityCountMinute, ParityCountHour;
40
  uint8_t BitCounter;
41
}DCF77;
42
43
struct {
44
  uint8_t Sekunden, Minuten, Stunden;  
45
}Uhr;
46
47
int main( void )
48
{
49
  //////////////////////////////////////////////////////////////////////////
50
  // Oszillator Fine-Tune
51
  OSCCAL = 0x43;
52
  
53
  //////////////////////////////////////////////////////////////////////////
54
  // Variablen
55
  Uhr.Stunden = 12;
56
  Uhr.Minuten = 34;
57
  DCF77.BitCounter = 0;
58
  DCF77.bcd.ByteMinute = (Uhr.Minuten/10 << 4) |  Uhr.Minuten % 10;
59
  DCF77.bcd.ByteHour = (Uhr.Stunden/10 << 4) | Uhr.Stunden % 10;
60
61
  //////////////////////////////////////////////////////////////////////////
62
  // IOs
63
  DCF77_DDR |= (1<<DCF77_PIN);
64
65
  //////////////////////////////////////////////////////////////////////////
66
  // Timer (Systick)
67
  OCR1A = 7999;                  // 8MHz/ 7999 = 1kHz
68
  TCCR1B |= (1<<CS10) | (1<<WGM12);        // Prescaler = 1
69
  TIMSK1 |= (1<<OCIE1A);
70
  
71
  //////////////////////////////////////////////////////////////////////////
72
  // Global Interrupt enable
73
  sei();
74
  
75
  //////////////////////////////////////////////////////////////////////////
76
    while ( "DCF77 Sending" ){
77
    // Nothing to do ;)
78
    }
79
}
80
81
//////////////////////////////////////////////////////////////////////////
82
// Uhr nachführen, DCF-77 Signal austakten
83
//////////////////////////////////////////////////////////////////////////
84
ISR ( TIMEBASE_1MS )
85
{
86
  static int16_t Millis = -1;
87
  //////////////////////////////////////////////////////////////////////////
88
  // Uhr
89
  if ( ++Millis >= PERIOD ){
90
    if ( ++Uhr.Sekunden >= 60 ){
91
      Uhr.Sekunden = 0;
92
      if (++ Uhr.Minuten >= 60 ){
93
        Uhr.Minuten = 0;
94
        if ( ++Uhr.Stunden >= 24 ){
95
          Uhr.Stunden = 0;
96
        }
97
      }
98
    }
99
    
100
    DCF77.bcd.ByteMinute = (Uhr.Minuten/10 << 4) |  Uhr.Minuten % 10;
101
    DCF77.bcd.ByteHour = (Uhr.Stunden/10 << 4) | Uhr.Stunden % 10;
102
    
103
    Millis = 0;
104
    DCF77.ParityCountMinute = 0;
105
    DCF77.ParityCountHour = 0;
106
    if ( ++DCF77.BitCounter >= 60 ) DCF77.BitCounter = 0;
107
  }
108
  
109
  //////////////////////////////////////////////////////////////////////////
110
  // Bit 0...19 => Null
111
  if ( DCF77.BitCounter < BEGIN_ZEITINFO ){
112
    LogicalZero( &Millis );
113
  }
114
  
115
  //////////////////////////////////////////////////////////////////////////
116
  // 1 gemäß "Beginn Zeitinformation"
117
  else if ( DCF77.BitCounter == BEGIN_ZEITINFO ){
118
    LogicalOne( &Millis );
119
  }
120
  
121
  //////////////////////////////////////////////////////////////////////////
122
  // Zeitinformation Minuten
123
  else if ( DCF77.BitCounter >= BEGIN_MINUTE && DCF77.BitCounter <= ENDE_MINUTE ){
124
    if ( DCF77.bcd.ByteMinute & (1<<(DCF77.BitCounter-BEGIN_MINUTE)) ){// 1
125
      if ( Millis == 0 ) DCF77.ParityCountMinute++;
126
      LogicalOne( &Millis );
127
    }
128
    else{//0
129
      LogicalZero( &Millis );
130
    }
131
  }
132
  
133
  // Parität Minute
134
  else if ( DCF77.BitCounter == PARI_MINUTE ){
135
    if ( DCF77.ParityCountMinute % 2 == 0 ){
136
      LogicalOne( &Millis );
137
    }else{
138
      LogicalZero( &Millis );
139
    }
140
  }
141
  
142
  //////////////////////////////////////////////////////////////////////////
143
  // Zeitinformation Stunden
144
  else if ( DCF77.BitCounter >= BEGIN_STUNDE && DCF77.BitCounter <= ENDE_STUNDE ){
145
    if ( DCF77.bcd.ByteHour & (1<<(DCF77.BitCounter-BEGIN_STUNDE)) ){// 1
146
      if ( Millis == 0 ) DCF77.ParityCountHour++;
147
      LogicalOne( &Millis );
148
    }
149
    else{//0
150
      LogicalZero( &Millis );
151
    }
152
  }
153
  
154
  // Parität Stunde
155
  else if ( DCF77.BitCounter == PARI_STUNDE ){
156
    if ( DCF77.ParityCountHour % 2 == 0 ){
157
      LogicalOne( &Millis );
158
    }else{
159
      LogicalZero( &Millis );
160
    }
161
  }
162
  
163
  //////////////////////////////////////////////////////////////////////////
164
  // Nullen bis zum Ende
165
  else if ( DCF77.BitCounter >= 36 && DCF77.BitCounter < 59 ){
166
    LogicalZero( &Millis );
167
  }
168
  
169
  //Ende
170
}
171
172
// DCF-Zeichen für logische 1
173
static void LogicalOne ( const int16_t *Millis )
174
{
175
  if ( *Millis < ONE_PULSE_TIME ){
176
    DCF77_PORT |= (1<<DCF77_PIN);
177
  }else{
178
    DCF77_PORT &= ~(1<<DCF77_PIN);
179
  }
180
}
181
182
// DCF-Zeichen für logische 0
183
static void LogicalZero ( const int16_t *Millis )
184
{
185
  if ( *Millis < ZERO_PULSE_TIME ){
186
    DCF77_PORT |= (1<<DCF77_PIN);
187
  }else{
188
    DCF77_PORT &= ~(1<<DCF77_PIN);
189
  }
190
}