1 | #define F_CPU 3686400
|
2 | #include <avr\io.h>
|
3 | //---------------------------------------------------------------------------------
|
4 | // TWI-Funktionssammlung
|
5 | #ifndef TWI_CLOCK
|
6 | #define TWI_CLOCK 100000 // Geschwindigkeit des TWI-Busses
|
7 | #endif
|
8 | // TWCR - Control-Register-Bits
|
9 | #define _TWINT 0b10000000
|
10 | #define _TWEA 0b01000000
|
11 | #define _TWSTA 0b00100000
|
12 | #define _TWSTO 0b00010000
|
13 | #define _TWWC 0b00001000
|
14 | #define _TWEN 0b00000100
|
15 | #define _TWIE 0b00000001
|
16 | uint8_t twiAdr = 0xD0;
|
17 | void twiInitMaster(uint8_t twiAdr);
|
18 | #include <util\delay.h>
|
19 | #include <util\delay.h>
|
20 |
|
21 | //------------------------------------------------------------------------
|
22 | // twiInitMaster
|
23 | //------------------------------------------------------------------------
|
24 | void twiInitMaster(uint8_t twiAdr)
|
25 | {
|
26 | // Clock
|
27 | TWBR=((F_CPU/TWI_CLOCK)-16)*2;
|
28 | // TWI-Status-Register (Vorteiler)
|
29 | TWSR=0;
|
30 | // Bus-Addr
|
31 | TWAR=twiAdr;
|
32 | // Enable
|
33 | TWCR=_TWINT|_TWEN;
|
34 | }
|
35 | //------------------------------------------------------------------------
|
36 | // Start TWI (ohne Interrupt)
|
37 | //------------------------------------------------------------------------
|
38 | void twiStart()
|
39 | {
|
40 | uint8_t x=TWCR;
|
41 | x&=_TWEN|_TWIE; // nur Beibehalten von Enable und InterruptJ/N
|
42 | TWCR=x|_TWINT|_TWSTA;
|
43 | // warten bis fertig
|
44 | while( !(TWCR & _TWINT))
|
45 | {}
|
46 | }
|
47 | //------------------------------------------------------------------------
|
48 | // Stopp TWI (ohne Interrupt)
|
49 | //------------------------------------------------------------------------
|
50 | void twiStop()
|
51 | {
|
52 | uint8_t x=TWCR;
|
53 | x&=_TWEN|_TWIE; // nur Beibehalten von Enable und InterruptJ/N
|
54 | TWCR=x|_TWINT|_TWSTO;
|
55 | }
|
56 | //------------------------------------------------------------------------
|
57 | // Write Byte per TWI (ohne Interrupt)
|
58 | // PE: data = zu sendende Daten
|
59 | // ackn = wenn !=0 wird Acknowledge (=TWEA) gesetzt
|
60 | //------------------------------------------------------------------------
|
61 | void twiWriteByte(uint8_t data, uint8_t ackn)
|
62 | {
|
63 | TWDR=data; // Daten bereitlegen
|
64 | // Befehl zusammenstellen
|
65 | uint8_t x=TWCR;
|
66 | x&=_TWEN|_TWIE; //nur Beibehalten von Enable und InterruptJ/N
|
67 | x|=_TWINT;
|
68 | if(ackn)
|
69 | x|=_TWEA; // evt. TWEA setzen, für Datenanforderung
|
70 | TWCR=x; // senden
|
71 | // warten bis fertig
|
72 | while( !(TWCR & _TWINT))
|
73 | {}
|
74 | }
|
75 | //------------------------------------------------------------------------
|
76 | // Read Byte per TWI (ohne Interrupt)
|
77 | // PE: ackn = wenn !=0 wird Acknowledge (=TWEA) gesetzt
|
78 | // PA: Data
|
79 | //------------------------------------------------------------------------
|
80 | int twiReadByte(uint8_t ackn)
|
81 | {
|
82 | // Befehl zusammenstellen
|
83 | uint8_t x=TWCR;
|
84 | x&=_TWEN|_TWIE; //nur Beibehalten von Enable und InterruptJ/N
|
85 | x|=_TWINT;
|
86 | if(ackn)
|
87 | x|=_TWEA; // evt. TWEA setzen, für Datenanforderung
|
88 | TWCR=x; // senden
|
89 | // warten bis fertig
|
90 | while( !(TWCR & _TWINT))
|
91 | {}
|
92 | return TWDR;
|
93 | }
|
94 |
|
95 | //-------------------------------------------------------------------------
|
96 | // rtcGetRtcData
|
97 | //-------------------------------------------------------------------------
|
98 | uint8_t rtcGetRtcData(uint8_t Register)
|
99 | {
|
100 | // Adresse senden
|
101 | twiStart();
|
102 | twiWriteByte(twiAdr,0);
|
103 | twiWriteByte(Register,1);
|
104 | // Daten lesen
|
105 | twiStart();
|
106 | twiWriteByte(twiAdr+1,1);
|
107 | uint8_t b = (uint8_t)twiReadByte(0);
|
108 | twiStop();
|
109 | return b;
|
110 | }
|
111 | //-------------------------------------------------------------------------
|
112 | // rtcGetSeconds
|
113 | //-------------------------------------------------------------------------
|
114 | uint8_t rtcGetSeconds()
|
115 | {
|
116 | return rtcGetRtcData(0) & 0x7F;
|
117 | }
|
118 | //-------------------------------------------------------------------------
|
119 | // rtcGetMinute
|
120 | //-------------------------------------------------------------------------
|
121 | uint8_t rtcGetMinute()
|
122 | {
|
123 | return rtcGetRtcData(1);
|
124 | }
|
125 | //-------------------------------------------------------------------------
|
126 | // rtcGetHour
|
127 | //-------------------------------------------------------------------------
|
128 | uint8_t rtcGetHour()
|
129 | {
|
130 | return rtcGetRtcData(2) & 0x3F;
|
131 | }
|
132 | //-------------------------------------------------------------------------
|
133 | // rtcWaitMs
|
134 | //-------------------------------------------------------------------------
|
135 | void rtcWaitMs(int miliSec)
|
136 | {
|
137 | _delay_loop_2( 1*(F_CPU/(1000/4)) * miliSec); // 4 Zyklen warteschleife
|
138 | }
|
139 |
|
140 | //--------------------------------------------------------------------
|
141 | // myWait_ms - Warte-Routine für x-Millisekunden (0-255)
|
142 | // ein Millisekundenzyklus dauert 1,052 ms
|
143 | // PE: Anzahl der zu wartenden Milisekunden
|
144 | //--------------------------------------------------------------------
|
145 | void myWait_ms(uint8_t dauer_ms)
|
146 | {
|
147 | __asm__ volatile (
|
148 | "myWait_ms_0%=:\n"
|
149 | "push %0\n"
|
150 | "ldi %0,1\n"
|
151 | "myWait_ms_3%=:\n"
|
152 | "push %0\n"
|
153 | "ldi %0,5\n"
|
154 | "myWait_ms_2%=:\n"
|
155 | "push %0\n"
|
156 | "ldi %0,255\n"
|
157 | "myWait_ms_1%=:\n"
|
158 | "dec %0 \n"
|
159 | "brne myWait_ms_1%=\n"
|
160 | "pop %0 ; Register wiederherstellen\n"
|
161 | "dec %0 \n"
|
162 | "brne myWait_ms_2%=\n"
|
163 | "pop %0 ; Register wiederherstellen\n"
|
164 | "dec %0 \n"
|
165 | "brne myWait_ms_3%=\n"
|
166 | "pop %0 ; Register wiederherstellen\n"
|
167 | "dec %0 \n"
|
168 | "brne myWait_ms_0%=\n"
|
169 | :
|
170 | :"d" (dauer_ms)
|
171 | );
|
172 | }
|
173 |
|
174 | //---------------------------------------------------------------------------
|
175 | void waitMs(int miliSec)
|
176 | {
|
177 | _delay_loop_2( 1*(F_CPU/(1000/4)) * miliSec); // 4 Zyklen warteschleife
|
178 | }
|
179 |
|
180 | //------------------------------------------------------------------------
|
181 | // Initialisierungen
|
182 | //------------------------------------------------------------------------
|
183 | void init()
|
184 | {
|
185 | twiInitMaster(twiAdr);
|
186 | }
|
187 |
|
188 | //------------------------------------------------------------------------
|
189 | // Zahlensystem-Wandler
|
190 | //------------------------------------------------------------------------
|
191 |
|
192 | int dectobcd(int dec)
|
193 | {
|
194 | int BCD;
|
195 | BCD = (((dec / 10) * 16) + (dec % 10));
|
196 | return BCD;
|
197 | }
|
198 |
|
199 | int bcdtodec(int BCD)
|
200 | {
|
201 | int dec;
|
202 | dec = ((((BCD >> 4)&0b111)*10)+(BCD&0b1111));
|
203 | return dec;
|
204 | }
|
205 |
|
206 | //------------------------------------------------------------------------
|
207 | // Einstellung der Zeit
|
208 | //------------------------------------------------------------------------
|
209 |
|
210 | void define_time(int stunde, int minute, int sekunde)
|
211 | {
|
212 | twiStart();
|
213 | twiWriteByte(twiAdr,0);
|
214 | twiWriteByte(0,1);
|
215 | sekunde = dectobcd(sekunde);
|
216 | twiWriteByte(sekunde,1);
|
217 | minute = dectobcd(minute);
|
218 | twiWriteByte(minute,1);
|
219 | stunde = dectobcd(stunde);
|
220 | twiWriteByte(stunde,1);
|
221 | twiStop();
|
222 | }
|
223 |
|
224 | //------------------------------------------------------------------------
|
225 | // Ein/Ausschalten des Relais
|
226 | //------------------------------------------------------------------------
|
227 |
|
228 | int switcher(int stunde_on, int stunde_off)
|
229 | {
|
230 | int stunde = 0;
|
231 | stunde = rtcGetHour();
|
232 | stunde = bcdtodec(stunde);
|
233 | if ((stunde>=stunde_on) && (stunde<stunde_off))
|
234 | {
|
235 | PORTC = 0x08;
|
236 | }
|
237 | else
|
238 | {
|
239 | PORTC = 0x00;
|
240 | }
|
241 | }
|
242 |
|
243 | /////////////////////////////////////////////////////////////////////////////
|
244 | // Main-Funktion
|
245 | /////////////////////////////////////////////////////////////////////////////
|
246 | main()
|
247 | {
|
248 | //Variablen-Initialisierung
|
249 | int zeit1,zeit2;
|
250 |
|
251 | init(); // Initialisierungen
|
252 |
|
253 | //Zur Zeiteinstellung Kommentare entfernen!
|
254 | /*zeit1 = rtcGetHour();
|
255 | zeit2 = rtcGetMinute();
|
256 |
|
257 |
|
258 | if ((zeit1==0)&&(zeit2==0))
|
259 | {
|
260 | define_time(8,19,31);
|
261 | }*/
|
262 |
|
263 | // Alternativ: direkte Überschreibung
|
264 | // define_time(10,10,15);
|
265 |
|
266 | DDRC = 0x08;
|
267 |
|
268 | while (true) // Mainloop-Begin
|
269 | {
|
270 | switcher(11,13);
|
271 | _delay_ms(1000);
|
272 | }
|