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