1 | /*
|
2 | Avr-Wecker by LB-Homeprojects
|
3 | visit htttp://lb-homeprojects.co.cc/
|
4 |
|
5 | Pinbelegung:
|
6 | PD0 -- LCD D4
|
7 | PD1 -- LCD D5
|
8 | PD2 -- LCD D6
|
9 | PD3 -- LCD D7
|
10 | PD4 -- LCD RS
|
11 | PD5 -- LCD E
|
12 | */
|
13 |
|
14 | #include <avr/io.h>
|
15 | #include <stdlib.h>
|
16 | #include <stdio.h>
|
17 | #include <stdint.h>
|
18 | #include <avr/interrupt.h>
|
19 |
|
20 | #include "lcd-routines.h" //LCD Routine von Mikrocontroller.net
|
21 | #include "taster.h" //Taster Routine von RN Wissen
|
22 |
|
23 | //############ variables ###########
|
24 | //Hilfsvariablen
|
25 | volatile uint8_t updateTime = 0;
|
26 | volatile uint8_t alarm; //alarm on/off
|
27 | volatile uint8_t mode; //taster-mode
|
28 |
|
29 | //Variablen für die Zeit
|
30 | volatile unsigned int millisekunden;
|
31 | volatile unsigned int sekunde;
|
32 | volatile unsigned int minute;
|
33 | volatile unsigned int stunde;
|
34 | volatile unsigned int tag;
|
35 |
|
36 | //Variablen für die Weckzeit
|
37 | volatile unsigned int w_minute;
|
38 | volatile unsigned int w_stunde;
|
39 |
|
40 |
|
41 | //############## init ##############
|
42 | int init(void){
|
43 |
|
44 | //Initialisierung des LCDs
|
45 | lcd_init();
|
46 |
|
47 | //Portinitialisierung
|
48 | DDRB=0xFF; //Port B auf Ausgang setzen
|
49 | //DDRC=0x00; //PORT C auf Eingang setzen
|
50 |
|
51 | // Timer 1 konfigurieren
|
52 | TCCR1B |= (1<<WGM12); // CTC Modus
|
53 | TCCR1B |= (1<<CS11); // Prescaler 8
|
54 | // ((4000000/8)/1000) = 500
|
55 | OCR1A = 500-1;
|
56 |
|
57 | // Compare Interrupt erlauben
|
58 | TIMSK |= (1<<OCIE1A);
|
59 |
|
60 | // Global Interrupts aktivieren
|
61 | sei();
|
62 |
|
63 | //benutzerdefiniertes Zeichen erstellen
|
64 | uint8_t chrdata0[8] = {
|
65 | 0b00000000,
|
66 | 0b00000100,
|
67 | 0b00001110,
|
68 | 0b00001110,
|
69 | 0b00001110,
|
70 | 0b00011111,
|
71 | 0b00000100,
|
72 | 0b00000000
|
73 | };
|
74 | lcd_generatechar(LCD_GC_CHAR0, chrdata0);
|
75 |
|
76 | return 0;
|
77 | }
|
78 |
|
79 |
|
80 | void ioinit()
|
81 | {
|
82 | /* Taster sind Input (default nach RESET) */
|
83 | /* Bei LOW-aktiven an den Tastern die PullUps aktivieren, bei HIGH-aktiven nicht */
|
84 | #if TASTER_LEVEL
|
85 | ;
|
86 | #else
|
87 | PORTC = 0xFF;
|
88 | #endif
|
89 |
|
90 | /* Timer0 ohne Prescaler starten */
|
91 | TCCR0 = 1 << CS00;
|
92 |
|
93 | /* Timer0-Overflow-Interrupt aktivieren */
|
94 | TIMSK |= (1 << TOIE0);
|
95 | }
|
96 |
|
97 |
|
98 | //############ timer-ISR ###########
|
99 |
|
100 | /*
|
101 | Der Compare Interrupt Handler
|
102 | wird aufgerufen, wenn
|
103 | TCNT1 = OCR1A = 125-1
|
104 | ist (125 Schritte), d.h. genau alle 1 ms
|
105 | */
|
106 | ISR (TIMER1_COMPA_vect)
|
107 | {
|
108 | //Zeit-Funktionen
|
109 | millisekunden++;
|
110 | if(millisekunden == 1000)
|
111 | {
|
112 | updateTime = 1; //Anzeige-Funktionen im Sekundentakt in main aktivieren
|
113 | sekunde++;
|
114 | millisekunden = 0;
|
115 | if(sekunde == 60)
|
116 | {
|
117 | minute++;
|
118 | sekunde = 0;
|
119 | }
|
120 | if(minute == 60)
|
121 | {
|
122 | stunde++;
|
123 | minute = 0;
|
124 | }
|
125 | if(stunde == 24)
|
126 | {
|
127 | tag++;
|
128 | stunde = 0;
|
129 | }
|
130 | if(tag == 6)
|
131 | {
|
132 | tag = 0;
|
133 | }
|
134 | }
|
135 | }
|
136 |
|
137 | //############ taster-ISR ###########
|
138 | SIGNAL (SIG_OVERFLOW0)
|
139 | {
|
140 | static unsigned char count_ovl0;
|
141 | unsigned char ovl0 = count_ovl0+1;
|
142 |
|
143 | if (ovl0 >= 156)
|
144 | {
|
145 | get_taster (0, PINC & (1<<PC0));
|
146 | get_taster (1, PINC & (1<<PC1));
|
147 | get_taster (2, PINC & (1<<PC2));
|
148 | get_taster (3, PINC & (1<<PC3));
|
149 |
|
150 | ovl0 = 0;
|
151 | }
|
152 |
|
153 | count_ovl0 = ovl0;
|
154 | }
|
155 |
|
156 | //############## main ##############
|
157 | int main(void)
|
158 | {
|
159 | init();
|
160 | ioinit();
|
161 |
|
162 | /* Taster konfigurieren (#define NUM_TASTER 4 in taster.h)
|
163 | tasten[0].mode = TM_SHORT;
|
164 | tasten[1].mode = TM_LONG;
|
165 | tasten[2].mode = TM_REPEAT;*/
|
166 |
|
167 | sei();
|
168 |
|
169 | while(1){
|
170 |
|
171 | if(updateTime == 1){
|
172 |
|
173 | updateTime = 0;
|
174 |
|
175 | //Anzeige-Funktionen
|
176 | // ----------------
|
177 | // |___ 10:15:15 ___|
|
178 | // | So, #07:45 |
|
179 | // ----------------
|
180 |
|
181 | lcd_clear();
|
182 | lcd_string("___ ");
|
183 |
|
184 | if(stunde<=9){lcd_data( '0' );}
|
185 | { char Buffer[20];
|
186 | itoa( stunde, Buffer, 10 );
|
187 | lcd_string( Buffer ); }
|
188 |
|
189 |
|
190 | lcd_data( ':' );
|
191 |
|
192 | if(minute<=9){lcd_data( '0' );}
|
193 | { char Buffer[20];
|
194 | itoa( minute, Buffer, 10 );
|
195 | lcd_string( Buffer ); }
|
196 |
|
197 | lcd_data( ':' );
|
198 |
|
199 | if(sekunde<=9){lcd_data( '0' );}
|
200 | { char Buffer[20];
|
201 | itoa( sekunde, Buffer, 10 );
|
202 | lcd_string( Buffer ); }
|
203 |
|
204 | lcd_string(" ___");
|
205 |
|
206 | //Wochentag anzeigen
|
207 | lcd_setcursor(3,2);
|
208 |
|
209 | switch(tag){
|
210 | case 0: lcd_string("Mo, "); break;
|
211 | case 1: lcd_string("Di, "); break;
|
212 | case 2: lcd_string("Mi, "); break;
|
213 | case 3: lcd_string("Do, "); break;
|
214 | case 4: lcd_string("Fr, "); break;
|
215 | case 5: lcd_string("Sa, "); break;
|
216 | case 6: lcd_string("So, "); break;
|
217 | }
|
218 |
|
219 | //Weckzeit anzeigen
|
220 | lcd_data( '#' );
|
221 |
|
222 | if(w_stunde<=9){lcd_data( '0' );}
|
223 | { char Buffer[20];
|
224 | itoa( w_stunde, Buffer, 10 );
|
225 | lcd_string( Buffer ); }
|
226 |
|
227 | lcd_data( ':' );
|
228 |
|
229 | if(w_minute<=9){lcd_data( '0' );}
|
230 | { char Buffer[20];
|
231 | itoa( w_minute, Buffer, 10 );
|
232 | lcd_string( Buffer ); }
|
233 |
|
234 |
|
235 | //Weck-Funktionen
|
236 | if(alarm){
|
237 | lcd_setcursor(15,2);
|
238 | lcd_data(LCD_GC_CHAR0);
|
239 | lcd_home();
|
240 | }
|
241 | if(alarm && stunde == w_stunde && minute == w_minute && sekunde<=5){
|
242 | lcd_setcursor(15,2);
|
243 | //PORTB=(1 << PB2);
|
244 | }
|
245 | }
|
246 |
|
247 | signed char tast = taster;
|
248 |
|
249 |
|
250 | switch (tast)
|
251 | {
|
252 | default:
|
253 | case NO_TASTER:
|
254 | break;
|
255 |
|
256 | case 0: //Toggle Alarm (On/Off)
|
257 | if(!alarm){
|
258 | alarm=1;
|
259 | }
|
260 | else{
|
261 | alarm=0;
|
262 | }
|
263 | break;
|
264 |
|
265 | case 1: //Toggle Mode (w_stunde/w_minute/tag/stunde/minute)
|
266 | if(mode<=4){
|
267 | mode++;
|
268 | }
|
269 | else
|
270 | mode=0;
|
271 | break;
|
272 |
|
273 | case 2: //increment variable ++
|
274 | switch (mode)
|
275 | {
|
276 | case 0: w_stunde++; break;
|
277 | case 1: w_minute++; break;
|
278 | case 2: tag++; break;
|
279 | case 3: stunde++; break;
|
280 | case 4: minute++; break;
|
281 | }
|
282 | break;
|
283 |
|
284 | case 3: //decrement variable --
|
285 | switch (mode)
|
286 | {
|
287 | case 0: w_stunde--; break;
|
288 | case 1: w_minute--; break;
|
289 | case 2: tag--; break;
|
290 | case 3: stunde--; break;
|
291 | case 4: minute--; break;
|
292 | }
|
293 | break;
|
294 |
|
295 |
|
296 | }
|
297 |
|
298 | if (tast != NO_TASTER)
|
299 | taster = NO_TASTER;
|
300 | }
|
301 | }
|