1 | //Stoppuhr
|
2 |
|
3 | #include <avr/io.h>
|
4 | #include <avr/interrupt.h>
|
5 | #include <stdint.h>
|
6 | #include <inttypes.h>
|
7 |
|
8 |
|
9 |
|
10 | volatile unsigned char running;
|
11 | volatile unsigned char zahl[10]; //Array in denen die Portausgaben für die Zahlen 0-9 gespeichert ist
|
12 | volatile unsigned char sek[4]; //Zeiger auf zahl
|
13 | volatile unsigned char i; //Zählvariable für sek
|
14 |
|
15 |
|
16 | //Timer und Interrupt Initialisierung
|
17 | int interrupt_init(void)
|
18 | {
|
19 | TCNT0 = 0x00; //Timer0 mit 0 initialisieren (00000000)
|
20 | TIMSK = 0x01; //Timer0 Overflow Interrupt aktivieren (00000001)
|
21 |
|
22 | MCUCR = 0x03; //Rising Edge Interrupt an INT0 aktivieren (00000011)
|
23 | MCUCSR = 0x40; //Rising Edge Interrupt an INT2 aktivieren (01000000)
|
24 | GICR = 0x60; //Interrupt auf INT0 und INT2 aktivieren (01100000)
|
25 |
|
26 | return 0;
|
27 | }
|
28 | //-----------------------------------
|
29 |
|
30 |
|
31 | //Konstanten und Portkonfiguration
|
32 | int const_init(void)
|
33 | {
|
34 | zahl[0] = 0x00; //Die Werte für Zahl müssen noch
|
35 | zahl[1] = 0x01; //entsprechend den Pins der
|
36 | zahl[2] = 0x02; //7-Segment-Anzeigen angepasst werden
|
37 | zahl[3] = 0x03;
|
38 | zahl[4] = 0x04;
|
39 | zahl[5] = 0x05;
|
40 | zahl[6] = 0x06;
|
41 | zahl[7] = 0x07;
|
42 | zahl[8] = 0x08;
|
43 | zahl[9] = 0x09;
|
44 |
|
45 | DDRA = 0xFF; //alle Pins Ausgang (11111111)
|
46 | DDRB = 0xD0; //Pin 2 (INT2) Eingang, Rest Ausgang (11011111)
|
47 | DDRC = 0xFF; //alle Pins Ausgang (11111111)
|
48 | DDRD = 0xD0; //Pin 2 (INT0) Eingang, Rest Ausgang (11011111)
|
49 |
|
50 | //alle Ports zeigen 0 an
|
51 | PORTA = zahl[0]; //Port für 10er Sekunden
|
52 | PORTB = zahl[0]; //Port für Sekunden
|
53 | PORTC = zahl[0]; //Port für 1/10 Sekunden
|
54 | PORTD = zahl[0]; //Port für 1/100 Sekunden
|
55 |
|
56 | return 0;
|
57 | }
|
58 | //-----------------------------------
|
59 |
|
60 |
|
61 | //Hauptprogramm
|
62 | int main(void)
|
63 | {
|
64 | interrupt_init();
|
65 | const_init();
|
66 |
|
67 | sei();
|
68 |
|
69 | while(1) {
|
70 | PORTA = zahl[sek[0]];
|
71 | PORTB = zahl[sek[1]];
|
72 | PORTC = zahl[sek[2]];
|
73 | PORTD = zahl[sek[3]];
|
74 | }
|
75 | }
|
76 | //-----------------------------------
|
77 |
|
78 |
|
79 | //ISR für Timer
|
80 | ISR(TIMER0_OVF_vect)
|
81 | {
|
82 | sek[0]++;
|
83 |
|
84 | for(i = 0; i < 4; i++)
|
85 | {
|
86 | if (sek[i] > 9)
|
87 | {
|
88 | sek[i]=0;
|
89 | sek[i+1]++;
|
90 | }
|
91 | if (sek[3] > 9)
|
92 | {
|
93 | sek[0] = 0;
|
94 | sek[1] = 0;
|
95 | sek[2] = 0;
|
96 | sek[3] = 0;
|
97 | }
|
98 | }
|
99 | }
|
100 | //-----------------------------------
|
101 |
|
102 |
|
103 | //ISR für Start/Stop
|
104 | ISR(INT0_vect)
|
105 | {
|
106 | if(running == 0)
|
107 | {
|
108 | TCCR0 = 0x05; //Einstellung Prescaler (siehe S.80 im Datenblatt) (00000101)
|
109 | running = 1; //Indikator für "läuft"
|
110 | }
|
111 | else
|
112 | {
|
113 | TCCR0 = 0x00; //Timer0 aus (00000000)
|
114 | running = 0; //Indikator für "läuft nicht"
|
115 | }
|
116 | }
|
117 | //-----------------------------------
|
118 |
|
119 |
|
120 | //ISR für Reset
|
121 | ISR(INT2_vect)
|
122 | {
|
123 | TCCR0 = 0x00; //Timer0 deaktivieren (00000000)
|
124 |
|
125 | //alle Anzeigen auf 0
|
126 | PORTA = zahl[0];
|
127 | PORTB = zahl[0];
|
128 | PORTC = zahl[0];
|
129 | PORTD = zahl[0];
|
130 | }
|
131 | //-----------------------------------
|