Hallo, ich möchte gerne vier Kanäle (MUX: 00000, 00001, 00010 und 00011) nacheinander wandeln. Eine Lösung mittels Flagauswertung funktioniert einwandfrei. Diesen Quelltext (wichtige Auszüge der einzelnen c-Files) habe ich per Textdatei eingefügt. Bitte nicht gleich die Art und Weise meiner ersten "modularen" Programmierung bemängeln -> wird bestimmt noch besser ;-))) Nun zum eigentlichen Problem. Ich möchte den Controller nicht jeder Conversion im Leerlauf warten lassen. Deshalb die Idee, eine Wandlung (Single-Conversion) anstoßen und das Ergebnis via ISR auszulesen.
1 | #include <avr/io.h> |
2 | #include <stdint.h> |
3 | #include <avr/interrupt.h> |
4 | #include <avr/signal.h> |
5 | |
6 | #include <main.h> |
7 | |
8 | |
9 | //initalize values
|
10 | volatile uint8_t AdcChannel = 0; |
11 | volatile uint8_t AdcBuffer[3] = {0x00,0x00,0x00,0x00}; |
12 | |
13 | int main(void) |
14 | {
|
15 | InitTimer16(); //PWM at PORTB7...5 for Buffer 0..2 -> is okay |
16 | DDRC = 0xFF; //für Buffer 3 -> is okay |
17 | |
18 | while(1) |
19 | {
|
20 | |
21 | if(AdcChannel > 3) AdcChannel = 0; |
22 | |
23 | AdcConv(AdcChannel); |
24 | |
25 | //test
|
26 | OCR1AL = AdcBuffer[0]; |
27 | OCR1BL = AdcBuffer[1]; |
28 | OCR1CL = AdcBuffer[2]; |
29 | PORTC = AdcBuffer[3]; |
30 | }
|
31 | return(0); |
32 | }
|
33 | |
34 | --------------------------------------------------------------------------------
|
35 | |
36 | #ifndef __MAIN_H
|
37 | #define __MAIN_H
|
38 | |
39 | |
40 | //Prototype
|
41 | extern void AdcConv(uint8_t); //set ch and start a conversation |
42 | extern void InitTimer16(void); //Initialize Timer |
43 | |
44 | //Variables
|
45 | //Analog Inputs Channel 0...3
|
46 | extern volatile uint8_t AdcChannel; //counter for adc channels |
47 | extern volatile uint8_t AdcBuffer[3]; |
48 | |
49 | #endif
|
50 | |
51 | --------------------------------------------------------------------------------
|
52 | |
53 | /*AdcConv*/
|
54 | |
55 | void AdcConv(uint8_t mux) |
56 | {
|
57 | ADMUX = mux; //channel |
58 | ADMUX |= (1<<ADLAR); //left adjust result |
59 | ADMUX |= (1<<REFS0); //Vref to AVcc with capacitor |
60 | ADCSRA = 0xC0; //start conversion |
61 | }
|
62 | |
63 | --------------------------------------------------------------------------------
|
64 | |
65 | /*ISR_M128*/
|
66 | |
67 | //ISR
|
68 | SIGNAL(SIG_ADC) |
69 | {
|
70 | cli(); |
71 | ADCSRA &= ~(1<<ADEN); //disable ADC |
72 | AdcBuffer[AdcChannel] = ADCH; //save ADC result |
73 | AdcChannel++; |
74 | sei(); |
75 | }
|
Leider wird dabei nur die erste Wandlung gemacht und danach wird's Müll. Irgendwie vermute ich das Problem zwischen Aufruf der Funktion AdcConv[AdcChannel] und der Wertzuweisung in der ISR. Hat jemand einen Tipp, wie ich dies besser realisieren könnte? Viele Grüße müllo