1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 | #include <avr/interrupt.h>
|
4 | #include <stdlib.h>
|
5 |
|
6 | #define F_CPU 12000000L
|
7 | #define BAUD 9600L
|
8 |
|
9 | #define UBRR_VAL ((F_CPU+BAUD * 8)/(BAUD*16)-1) //clever runde
|
10 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) //reale Baudrate
|
11 |
|
12 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) //Fehler in Promille
|
13 |
|
14 | #if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
|
15 | #error Systematischer Fehler in der Baudrate größer 1% und damit zu hoch!
|
16 | #endif
|
17 |
|
18 | #define Adresse_A PC0
|
19 | #define Adresse_B PC1
|
20 | #define Adresse_c PC2
|
21 |
|
22 | #define Signal PD2
|
23 |
|
24 | #define Taster PC3
|
25 |
|
26 | unsigned int high_byte = 0;
|
27 | unsigned int low_byte = 0;
|
28 | unsigned int periodendauer = 0;
|
29 | unsigned int ergebnis[3];
|
30 | int counter = 0;
|
31 | unsigned int kanal = 1;
|
32 | int alt = 0;
|
33 | unsigned int uart = 0, messung = 0;
|
34 |
|
35 |
|
36 |
|
37 | ISR (TIMER1_CAPT_vect) //4)Führe diese ISR bei Overflow von TCNT0 aus
|
38 | {
|
39 | low_byte = ICR1L;
|
40 | high_byte = ICR1H;
|
41 | periodendauer = (high_byte * 256) + low_byte - (alt); // Differenz des Timers zum letzten Interrupt berechnen
|
42 | alt = (high_byte * 256) + low_byte; // Aktuellen Timerstand abspeichern
|
43 | messung ++;
|
44 | if (messung == 4)
|
45 | {
|
46 | ergebnis[kanal -1] = periodendauer; // Das Ergebnis in der zum Kanal passenden Variablen speichern
|
47 | kanal ++; // nächsten Kanal wählen
|
48 | if (kanal == 4)
|
49 | {
|
50 | kanal = 1;
|
51 | }
|
52 | if (kanal == 1)
|
53 | {
|
54 | PORTC &= ~((1<<PC0) | (1<<PC1) | (1<<PC2)); // Alle Adressleitungen auf 0
|
55 | }
|
56 | else if(kanal == 2)
|
57 | {
|
58 | PORTC |= (1<<PC0);
|
59 | PORTC &= ~((1<<PC1) | (1<<PC2)); // A auf 1 B und C auf 0
|
60 | }
|
61 | else if(kanal == 3)
|
62 | {
|
63 | PORTC |= (1<<PC1);
|
64 | PORTC &= ~((1<<PC2) | (1<<PC0)); // B auf 1 A und C auf 0
|
65 | }
|
66 | messung = 0;
|
67 | }
|
68 | }
|
69 |
|
70 | ISR (TIMER1_OVF_vect)
|
71 | {
|
72 | alt = 0-(65535 - alt);
|
73 | }
|
74 |
|
75 | int uart_putc(unsigned char c)
|
76 | {
|
77 | while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
|
78 | {
|
79 | }
|
80 |
|
81 | UDR0 = c; /* sende Zeichen */
|
82 | return 0;
|
83 | }
|
84 |
|
85 |
|
86 |
|
87 | void uart_puts (char *s)
|
88 | {
|
89 | while (*s)
|
90 | { /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
|
91 | uart_putc(*s);
|
92 | s++;
|
93 | }
|
94 | }
|
95 |
|
96 |
|
97 | int main(void)
|
98 | {
|
99 | DDRC |= (1<<PC0) | (1<<PC1) | (1<<PC2);
|
100 | PORTC &= !((1<<PC0) | (1<<PC1) | (1<<PC2));
|
101 | /* Signal und Tasterpin bleiben Eingänge und kriegen Pull-Ups */
|
102 | PORTD |= (1<<Signal); // Pull-Up Signal
|
103 | PORTC |= (1<<Taster); // Pull-Up Taster
|
104 |
|
105 | /*Timer initialisieren und aktivieren */
|
106 |
|
107 | TCCR1B = (1<<CS11); // Prescaler 8 / 12MHz:8 = 1,5MHz
|
108 | TIMSK1|=(1<<ICIE1); // ICP aktivieren
|
109 |
|
110 |
|
111 |
|
112 | /* UART initialisieren und aktivieren */
|
113 | UBRR0H = UBRR_VAL >> 8;
|
114 | UBRR0L = UBRR_VAL & 0xFF;
|
115 |
|
116 |
|
117 | UCSR0B = (1<<RXEN0)|(1<<TXEN0); //UART einschalten
|
118 | UCSR0C = (1<<USBS0)|(3<<UCSZ00); //Asynchron 8N1
|
119 |
|
120 |
|
121 | sei(); // Interrupts aktivieren
|
122 |
|
123 |
|
124 | char s[7];
|
125 |
|
126 | while (1)
|
127 | {
|
128 | if(uart >= 60000) // Bei jedem Timerdurchlauf 1 mal ausführen
|
129 | { // Taster entfernt, da nicht unbedingt notwendig
|
130 | for (int count = 1; count < 4; count++)
|
131 | {
|
132 | uart_puts("S");
|
133 | uart_puts( itoa( count, s, 10 ) );
|
134 | uart_puts(": ");
|
135 | uart_puts( itoa( ergebnis[count - 1], s, 10 ) );
|
136 | uart_puts(" ");
|
137 | }
|
138 | uart = 0;
|
139 | }
|
140 | uart ++;
|
141 |
|
142 | }
|
143 |
|
144 | return 0;
|
145 | }
|