1 | #define F_CPU 8000000UL
|
2 |
|
3 | #include <stdlib.h>
|
4 | #include <avr/io.h>
|
5 | #include <avr/interrupt.h>
|
6 | #include <util/delay.h>
|
7 | #include <string.h>
|
8 | #include <stdio.h>
|
9 |
|
10 | #define UART_BAUDRATE 4800
|
11 | #define UART_SETTING ((F_CPU/16L/UART_BAUDRATE)-1)
|
12 |
|
13 |
|
14 | volatile uint16_t sekunden, msekunden;
|
15 |
|
16 |
|
17 |
|
18 | ISR(TIMER2_COMP_vect)
|
19 | {
|
20 | static int count, count_sek;
|
21 |
|
22 | count_sek++;
|
23 |
|
24 | if(count_sek == 10)
|
25 | {
|
26 | msekunden++;
|
27 | count_sek = 0;
|
28 |
|
29 | if(msekunden == 1000)
|
30 | {
|
31 | sekunden++;
|
32 | msekunden = 0;
|
33 | }
|
34 | }
|
35 | }
|
36 |
|
37 | void init_time()
|
38 | {
|
39 | TIMSK|=(1<<OCIE2);
|
40 | TCCR2 |= (1<<WGM21) | (1<<CS21);
|
41 | OCR2 = F_CPU/8/10000;
|
42 | }
|
43 |
|
44 |
|
45 |
|
46 | /* ADC initialisieren */
|
47 | void ADC_Init(void) {
|
48 |
|
49 | uint16_t result;
|
50 |
|
51 |
|
52 | ADMUX = (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
|
53 |
|
54 | // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
|
55 | // schon auf 0, also single conversion
|
56 | ADCSRA = (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler
|
57 | ADCSRA |= (1<<ADEN); // ADC aktivieren
|
58 |
|
59 | /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
|
60 | also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
|
61 |
|
62 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
63 |
|
64 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
65 | /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
|
66 | Wandlung nicht übernommen. */
|
67 | result = ADCW;
|
68 | }
|
69 |
|
70 | /* ADC Einzelmessung */
|
71 | uint16_t ADC_Read( uint8_t channel )
|
72 | {
|
73 | // Kanal waehlen, ohne andere Bits zu beeinflußen
|
74 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
|
75 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
|
76 | while (ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten
|
77 | return ADCW; // ADC auslesen und zurückgeben
|
78 | }
|
79 |
|
80 | /* ADC Mehrfachmessung mit Mittelwertbbildung */
|
81 | uint16_t ADC_Read_Avg( uint8_t channel, uint8_t average )
|
82 | {
|
83 | uint32_t result = 0;
|
84 |
|
85 | for (uint8_t i = 0; i < average; ++i )
|
86 | result += ADC_Read( channel );
|
87 |
|
88 | return (uint16_t)( result / average );
|
89 | }
|
90 |
|
91 | void setup_uart()
|
92 | {
|
93 | UBRRH = (char) (UART_SETTING >> 8);
|
94 | UBRRL = (char) (UART_SETTING);
|
95 | UCSRB = (1<<RXEN) | (1<<TXEN);
|
96 |
|
97 | UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0);
|
98 | }
|
99 |
|
100 | void uart_putchar(char c)
|
101 | {
|
102 | // Warten bis Buffer bereit ...
|
103 | while (!(UCSRA & (1 << UDRE)))
|
104 | ;
|
105 |
|
106 | // Senden...
|
107 | UDR = c;
|
108 | }
|
109 |
|
110 | void uart_putstring(char *str)
|
111 | {
|
112 | unsigned char i;
|
113 |
|
114 | for (i=0;i<255;i++)
|
115 | {
|
116 | if (str[i] != 0)
|
117 | uart_putchar(str[i]);
|
118 | else
|
119 | break; // Ende des Strings erreicht
|
120 | }
|
121 | }
|
122 |
|
123 |
|
124 |
|
125 | char uart_getchar()
|
126 | {
|
127 | // Ist schon ein Zeichen im Buffer?
|
128 | if (bit_is_set(UCSRA, RXC))
|
129 | return UDR;
|
130 | else
|
131 | return -1;
|
132 | }
|
133 |
|
134 | void uart_readline(char *str)
|
135 | {
|
136 | char c;
|
137 | unsigned char index;
|
138 |
|
139 | index = 0;
|
140 |
|
141 | while (1)
|
142 | {
|
143 | c = uart_getchar();
|
144 | if (c != -1)
|
145 | {
|
146 |
|
147 |
|
148 |
|
149 | if (c == 13)
|
150 | {
|
151 | str[index] = 0;
|
152 |
|
153 | return;
|
154 | }
|
155 | else
|
156 | {
|
157 |
|
158 |
|
159 | str[index] = c;
|
160 | index++;
|
161 | }
|
162 | }
|
163 | }
|
164 | }
|
165 |
|
166 |
|
167 |
|
168 |
|
169 | int main()
|
170 | {
|
171 |
|
172 | uint16_t adcval;
|
173 |
|
174 | int last_sek;
|
175 |
|
176 | char Buffer[25];
|
177 |
|
178 |
|
179 | ADC_Init();
|
180 |
|
181 | DDRB=0xff;
|
182 | PORTB=0x00;
|
183 |
|
184 | sei(); // Interrupts global an
|
185 |
|
186 | last_sek = 0;
|
187 | sekunden = 0;
|
188 | msekunden = 0;
|
189 |
|
190 |
|
191 | init_time();
|
192 | setup_uart();
|
193 |
|
194 | uart_putstring("Setup UART: check\r\n");
|
195 | uart_putstring("Setup ADC: ");
|
196 |
|
197 | _delay_ms(1000);
|
198 |
|
199 | uart_putstring("check\r\n");
|
200 |
|
201 |
|
202 | while( 1 )
|
203 | {
|
204 |
|
205 | if(sekunden>last_sek)
|
206 | {
|
207 | last_sek = sekunden;
|
208 | adcval = ADC_Read_Avg(0,5);
|
209 |
|
210 |
|
211 |
|
212 | sprintf( Buffer, "Wert: %d", adcval );
|
213 |
|
214 | uart_putstring(Buffer);
|
215 | }
|
216 |
|
217 | }
|
218 | }
|