1 /*
2 projekt: numitron_clock.c
3 datum: 30.05.2013
4 autor: KOSTKA Filip
5 SENFLUK Petr
6
7 *****************************
8 Numitronove hodiny s Atmega32
9 *****************************
10
11 obsluha: pin PD5 - PWM
12 pin PB2 - zhaveni
13
14 zobrazovace: SEG1 - PD7
15 SEG2 - PD6
16 SEG3 - PB3
17 SEG4 - PD4
18 SEG5 - PB0
19 SEG6 - PB1
20
21 segmenty: PAx
22 _____
23 | 1 |
24 3 |_____| 0
25 | 2 |
26 4 |_____| 7 # 6
27 5
28
29 */
30
31 #define F_CPU 14745600
32
33 #include <avr/io.h>
34 #include <avr/interrupt.h>
35
36 //definice znakove sady
37 const char dNULL = 0b00000000;
38 const char dDASH = 0b00000100;
39 const char dTOP = 0b00000010;
40 const char dBOTTOM = 0b00100000;
41
42 const char d0 = 0b10111011;
43 const char d1 = 0b10000001;
44 const char d2 = 0b00110111;
45 const char d3 = 0b10100111;
46 const char d4 = 0b10001101;
47 const char d5 = 0b10101110;
48 const char d6 = 0b10111110;
49 const char d7 = 0b10000011;
50 const char d8 = 0b10111111;
51 const char d9 = 0b10101111;
52
53 const char dA = 0b10011111;
54 const char db = 0b10111100;
55 const char dE = 0b00111110;
56 const char dJ = 0b10100001;
57 const char dS = 0b10101110;
58 const char dY = 0b10001101;
59
60 const char menu_top = 6;
61 const char brigh_top = 3;
62
63 //stavove promenne
64 char time_update, set_update, brigh_update = 1;
65 char menu_state = 0, mpx_state = 1, brigh_state = 3;
66 char hr = 0; char min = 0; char sec = 0;
67 char digit_1, digit_2, digit_3, digit_4, digit_5, digit_6;
68 char time_cnt;
69
70 //tlacitko MENU
71 ISR(INT0_vect ){
72 if(menu_state == menu_top)
73 menu_state = 0;
74 else
75 menu_state += 1;
76 }
77
78 //tlacitko SET
79 ISR(INT1_vect ){
80 set_update = 1;
81 }
82
83 //citac OC0 - multiplex
84 ISR(TIMER0_OVF_vect ){
85 //frekvence spousteni 900Hz
86 if(mpx_state == 6)
87 mpx_state = 1;
88 else
89 mpx_state += 1;
90 }
91
92 //citac OC2 - casomira
93 ISR(TIMER2_OVF_vect ){
94 //frekvecne spousteni 225Hz
95 if(time_cnt == 225){
96 time_cnt = 0;
97 time_update = 1;
98 }
99 else
100 time_cnt += 1;
101 }
102
103 char num_to_digit(short num){
104 switch(num){
105 case 0 : return d0;
106 case 1 : return d1;
107 case 2 : return d2;
108 case 3 : return d3;
109 case 4 : return d4;
110 case 5 : return d5;
111 case 6 : return d6;
112 case 7 : return d7;
113 case 8 : return d8;
114 case 9 : return d9;
115 }
116 return dDASH; //pro pripad spatneho vstupniho parametru
117 }
118
119 //inicializace casu
120 void time_init(){
121 if(sec < 59)
122 sec += 1;
123 else{
124 sec = 0;
125 if(min < 59)
126 min += 1;
127 else{
128 min = 0;
129 if(hr < 23)
130 hr += 1;
131 else
132 hr = 0;
133 }//min
134 }//sec
135 time_update = 0;
136 }
137
138 //inicializace pri stisknuti tlacitka SET
139 void set_init(){
140 switch(menu_state){
141 case 0 : ; break; //rezerva (datum / sleep mode ...)
142 case 1 : if(hr == 23)
143 hr = 0;
144 else
145 hr += 1; break;
146 case 2 : if(min == 59)
147 min = 0;
148 else
149 min += 1; break;
150 case 3 : if(brigh_state == brigh_top)
151 brigh_state = 0;
152 else
153 brigh_state += 1;
154 brigh_update = 1; break;
155 }//switch
156 set_update = 0;
157 }
158
159 //menu_state = 0 - IDLE
160 void menu_0(){
161 digit_1 = num_to_digit(hr / 10);
162 digit_2 = num_to_digit(hr % 10) | 0b01000000;
163 digit_3 = num_to_digit(min / 10);
164 digit_4 = num_to_digit(min % 10) | 0b01000000;
165 digit_5 = num_to_digit(sec / 10);
166 digit_6 = num_to_digit(sec % 10) | 0b01000000;
167 }
168
169 //menu_state = 1 - NASTAVENI HODIN
170 void menu_1(){
171 digit_1 = num_to_digit(hr / 10);
172 digit_2 = num_to_digit(hr % 10) | 0b01000000;
173 digit_3 = dDASH;
174 digit_4 = dDASH;
175 digit_5 = dDASH;
176 digit_6 = dDASH;
177 }
178
179 //menu_state = 2 - NASTAVENI MINUT
180 void menu_2(){
181 digit_1 = dDASH;
182 digit_2 = dDASH;
183 digit_3 = num_to_digit(min / 10);
184 digit_4 = num_to_digit(min % 10) | 0b01000000;
185 digit_5 = dDASH;
186 digit_6 = dDASH;
187 }
188
189 //menu_state = 3 - NASTAVENI JASU
190 void menu_3(){
191 digit_1 = dJ;
192 digit_2 = dA;
193 digit_3 = dS;
194 digit_4 = dNULL;
195 switch(brigh_state){
196 case 0 : digit_5 = d0;
197 digit_6 = d0; break;
198 case 1 : digit_5 = d0;
199 digit_6 = d1; break;
200 case 2 : digit_5 = d1;
201 digit_6 = d0; break;
202 case 3 : digit_5 = d1;
203 digit_6 = d1; break;
204 }//switch
205 }
206
207 //menu_state = 4 - BEZICI TEXT
208 void menu_4(){
209 switch(sec % 6){
210 case 0 : digit_1 = dDASH;
211 digit_2 = dDASH;
212 digit_3 = dDASH;
213 digit_4 = db;
214 digit_5 = dY;
215 digit_6 = dE; break;
216 case 1 : digit_1 = dDASH;
217 digit_2 = dDASH;
218 digit_3 = db;
219 digit_4 = dY;
220 digit_5 = dE;
221 digit_6 = dDASH; break;
222 case 2 : digit_1 = dDASH;
223 digit_2 = db;
224 digit_3 = dY;
225 digit_4 = dE;
226 digit_5 = dDASH;
227 digit_6 = dDASH; break;
228 case 3 : digit_1 = db;
229 digit_2 = dY;
230 digit_3 = dE;
231 digit_4 = dDASH;
232 digit_5 = dDASH;
233 digit_6 = dDASH; break;
234 case 4 : digit_1 = dY;
235 digit_2 = dE;
236 digit_3 = dDASH;
237 digit_4 = dDASH;
238 digit_5 = dDASH;
239 digit_6 = db; break;
240 case 5 : digit_1 = dE;
241 digit_2 = dDASH;
242 digit_3 = dDASH;
243 digit_4 = dDASH;
244 digit_5 = db;
245 digit_6 = dY; break;
246 }//switch
247 }
248
249 //menu_state = 5 - VLNKY
250 void menu_5(){
251 switch((time_cnt / 15) % 4){
252 case 0 : digit_1 = dBOTTOM;
253 digit_2 = dDASH;
254 digit_3 = dTOP;
255 digit_4 = dDASH;
256 digit_5 = dBOTTOM;
257 digit_6 = dDASH; break;
258 case 1 : digit_1 = dDASH;
259 digit_2 = dTOP;
260 digit_3 = dDASH;
261 digit_4 = dBOTTOM;
262 digit_5 = dDASH;
263 digit_6 = dTOP; break;
264 case 2 : digit_1 = dTOP;
265 digit_2 = dDASH;
266 digit_3 = dBOTTOM;
267 digit_4 = dDASH;
268 digit_5 = dTOP;
269 digit_6 = dDASH; break;
270 case 3 : digit_1 = dDASH;
271 digit_2 = dBOTTOM;
272 digit_3 = dDASH;
273 digit_4 = dTOP;
274 digit_5 = dDASH;
275 digit_6 = dBOTTOM; break;
276 }//switch
277 }
278
279 //menu_state = 6 - BINARNI SEKUNDOVKA
280 void menu_6(){
281 char temp = sec;
282 digit_6 = num_to_digit(temp % 2);
283 temp /= 2;
284 digit_5 = num_to_digit(temp % 2);
285 temp /= 2;
286 digit_4 = num_to_digit(temp % 2);
287 temp /= 2;
288 digit_3 = num_to_digit(temp % 2);
289 temp /= 2;
290 digit_2 = num_to_digit(temp % 2);
291 temp /= 2;
292 digit_1 = num_to_digit(temp % 2);
293 temp /= 2;
294 }
295
296 int main(void ){
297
298 //globalni preruseni
299 sei();
300
301 //preruseni pro tlacitka
302 GICR |= (1 << INT1)|(1 << INT0); //external interrupt
303 MCUCR |= (1 << ISC01)|(1 << ISC11); //falling edge
304
305 //preruseni citace OC0 - multiplex
306 TIMSK |= (1 << TOIE0);
307
308 //preruseni citace OC2 - casomira
309 TIMSK |= (1 << TOIE2);
310
311 //nastaveni citace 0C0 - multiplex
312 TCCR0 |= (1 << CS00)|(1 << CS01); //prescaler 64
313
314 //nastaveni citace OC1A - PWM
315 TCCR1A |= (1 << COM1A1); //set at bottom, clear on match
316 TCCR1A |= (1 << WGM10); //fast PWM 8-bit
317 TCCR1B |= (1 << WGM12);
318 TCCR1B |= (1 << CS10); //no prescaler
319
320 //nastaveni citace 0C2 - casomira
321 TCCR2 |= (1 << CS22)|(1 << CS21); //prescaler 256
322
323 //inicializece portu - celkem 16 vystupnich pinu
324 DDRA = 0b11111111;
325 DDRB = 0b00001111;
326 DDRC = 0b00000000;
327 DDRD = 0b11110000;
328
329 //zhaveni (PB2), pull-up na INT0 (PD2), INT2 (PD3) a PWM (PD5)
330 PORTB = 0b00000100;
331 PORTD = 0b00101100;
332
333 while(1){
334 //...externi aktualizace - tlacitko SET
335 if (set_update == 1){
336 set_init();
337 }
338
339 //...nastaveni PWM
340 if(brigh_update == 1){
341 switch(brigh_state){
342 case 0 : OCR1AL = 102; break; //...2/5 Ucc
343 case 1 : OCR1AL = 154; break; //...3/5 Ucc
344 case 2 : OCR1AL = 205; break; //...4/5 Ucc
345 case 3 : OCR1AL = 255; break; //...Ucc
346 }//switch
347 brigh_update = 0;
348 }
349
350 //...interni aktualizace - cas
351 if (time_update == 1){
352 time_init();
353 }
354
355 //...sestaveni displeje
356 switch(menu_state){
357 case 0 : menu_0(); break; //IDLE
358 case 1 : menu_1(); break; //NASTAVENI HODIN
359 case 2 : menu_2(); break; //NASTAVENI MINUT
360 case 3 : menu_3(); break; //NASTAVENI JASU
361 case 4 : menu_4(); break; //BEZICI TEXT - ukazka
362 case 5 : menu_5(); break; //VLNY - ukazka
363 case 6 : menu_6(); break; //BINARNI SEKUNDOVKA - ukazka
364 }//switch
365
366 //...multiplex
367 switch(mpx_state){
368 case 1: PORTB &= ~0b00000010; //vypnuti katody 6. zobrazovace
369 PORTD |= 0b10000000; //zapnuti katody 1. zobrazovace
370 PORTA = digit_1; break; //odeslani znaku
371 case 2: PORTD &= ~0b10000000; //...
372 PORTD |= 0b01000000;
373 PORTA = digit_2; break;
374 case 3: PORTD &= ~0b01000000;
375 PORTB |= 0b00001000;
376 PORTA = digit_3; break;
377 case 4: PORTB &= ~0b00001000;
378 PORTD |= 0b00010000;
379 PORTA = digit_4; break;
380 case 5: PORTD &= ~0b00010000;
381 PORTB |= 0b00000001;
382 PORTA = digit_5; break;
383 case 6: PORTB &= ~0b00000001;
384 PORTB |= 0b00000010;
385 PORTA = digit_6; break;
386 }
387 }//while
388
389 }//main
390