wecker.c


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
}