Forum: Mikrocontroller und Digitale Elektronik AT90USB1287 und ADC


von burnout (Gast)


Lesenswert?

Hallo zusammen.

Ich habe ein "mich in den Wahnsinn treibendes Problem" mit meinem ADC im 
oben genannten Mikrocontroller.

Ich möchte 4 Spannungswerte an den Kanälen ADC0-3 nacheinander messen.
Das erste Mal funktioniert es auch super.

Bei ADC_Init() : AREF, ADC Interrupt Enable, ADC Prescaler 64 (8MHZ 
Systemtakt)
Bei ADC_Start(); erster Parameter=ADC Kanal zweiter Parameter=single 
conversion. ADEN=1 ADSC=1

Wenn aber jetzt in der do-while Schleife der ADC Wert gelesen werden 
soll, steht nach jeder Messung 509/510 im ADC Register.
Ich kann mir nicht erklären warum, weil es ja bei der ersten Messung, 
vor Do-while, funktioniert.

Hat jemand ne Idee woran das liegen könnte???
Vielen Dank im Vorraus
Björn
1
int main(void)
2
{
3
    ADC_Init();
4
    for  (adc_loop = 0; adc_loop < 4; adc_loop++)     
5
   {
6
       ADC_Start(adc_loop, 0);
7
       while(ADCSRA & (1 << ADSC));        
8
   }
9
10
do{
11
    for  (adc_loop = 0; adc_loop < 4; adc_loop++)     
12
   {
13
       ADC_Start(adc_loop, 0);
14
       while(ADCSRA & (1 << ADSC));       
15
   }
16
17
18
19
}while(1);
20
}

von holger (Gast)


Lesenswert?

>Hat jemand ne Idee woran das liegen könnte???

Das liegt an dem Teil vom Code der NICHT zu sehen ist.

von burnout (Gast)


Lesenswert?

Code von ADC_Init
1
void ADC_Init(void)
2
{
3
  ADMUX =    (  (0 << REFS1)    
4
        |  (0 << REFS0)      // Voltage Reference Selection, set to AREF. refer to datasheet pg. 327
5
  //      |  (0 << ADLAR)      // ADC Left Adjust Result
6
  //      |  (0 << MUX4)        
7
  //      |  (0 << MUX3)
8
  //      |  (0 << MUX2)        // ADC Channel Selection
9
  //      |  (0 << MUX1)
10
  //      |  (0 << MUX0)  
11
        );
12
        
13
  
14
  ADCSRA |=  (  (0 << ADEN)        // ADC Disabled
15
        |  (0 << ADSC)        // ADC Conversion Stopped
16
        |  (0 << ADATE)      // ADC Auto Trigger Disabled
17
        |  (1 << ADIF)        // ADC Interrupt Flag
18
        |  (1 << ADIE)        // ADC Interrupt Enabled
19
        |  (1 << ADPS2)      // ADC Prescaler Bits
20
        |  (1 << ADPS1)      // set to XTAL freq / 64 = 125kHz
21
        |  (0 << ADPS0)      // refer to datasheet pg. 329
22
        );
23
24
25
26
27
  /*
28
  DIDR0 |=  (  (1 << ADC7D)      // Digital Input Disable - Port F
29
        |  (1 << ADC6D)
30
        |  (1 << ADC5D)
31
        |  (1 << ADC4D)
32
        |  (1 << ADC3D)
33
        |  (1 << ADC2D)
34
        |  (1 << ADC1D)
35
        |  (1 << ADC0D)
36
        );  */                    
37
}


Code von ADC-Start()
1
void ADC_Start(char channel, char mode)
2
{
3
  //*************************
4
  //* Available "channels"  *
5
  //* channel 0: ADC0      *
6
  //* channel 1: ADC1       *
7
  //* channel 2: ADC2       *
8
  //* channel 3: ADC3       *
9
  //*************************
10
11
12
  switch (channel)
13
  {
14
    case 0:      ADMUX |= ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (0 << MUX0));
15
            break;  
16
    case 1:       ADMUX |= ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (1 << MUX0));
17
            break;
18
    case 2:      ADMUX |= ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (1 << MUX1) | (0 << MUX0));
19
            break;
20
    case 3:      ADMUX |= ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (1 << MUX1) | (1 << MUX0));
21
            break;
22
  }
23
24
  //******************************************
25
  //* Available "modes"                      *
26
  //* mode 0: single conversion         *
27
  //* mode 1:  free running mode              *
28
  //* mode 2: timer/counter0 compare match   *
29
  //* mode 3: timer/counter0 overflow        *
30
  //* mode 4: timer/counter1 compare match b *
31
  //* mode 5: timer/counter1 overflow        *
32
  //* mode 6: timer/counter1 capture event   *
33
  //******************************************
34
35
  
36
37
  switch (mode)
38
  {  
39
    case 0:     ADCSRA |= ((0 << ADATE));
40
            break;
41
    case 1:      ADCSRA |= ((1 << ADATE));
42
            ADCSRB |= ((0 << ADTS2) | (0 << ADTS1) | (0 << ADTS0));
43
            break;
44
    case 2:      ADCSRA |= ((1 << ADATE));
45
            ADCSRB |= ((0 << ADTS2) | (1 << ADTS1) | (1 << ADTS0));
46
            break;
47
    case 3:      ADCSRA |= ((1 << ADATE));
48
            ADCSRB |= ((1 << ADTS2) | (0 << ADTS1) | (0 << ADTS0));
49
            break;
50
    case 4:      ADCSRA |= ((1 << ADATE));
51
            ADCSRB |= ((1 << ADTS2) | (0 << ADTS1) | (1 << ADTS0));
52
            break;
53
    case 5:      ADCSRA |= ((1 << ADATE));
54
            ADCSRB |= ((1 << ADTS2) | (1 << ADTS1) | (0 << ADTS0));
55
            break;
56
    case 6:      ADCSRA |= ((1 << ADATE));
57
            ADCSRB |= ((1 << ADTS2) | (1 << ADTS1) | (1 << ADTS0));
58
            break;
59
  }
60
  
61
62
      
63
  ADCSRA |=  (  (1 << ADEN)        // ADC Enable
64
        |  (1 << ADSC)        // ADC Start Conversion
65
        );  
66
        
67
      
68
        
69
}


ADC Interrupt Code:
1
ISR(ADC_vect)
2
{  
3
  adc_result[adc_loop] = ADC;  
4
}

von holger (Gast)


Lesenswert?

>    case 0:      ADMUX |= ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) 
| (0 << MUX0));

So bekommst du gesetze Bits nicht wieder auf Null.
0 oder 1 ist 1.

von burnout (Gast)


Lesenswert?

Tatsächlich!
Mist das hab ich total übersehen.
Dann messe ich ja ab Kanal 2 immer das Selbe.
Vielen Dank für deine Hilfe!
Werde gleich mal testen

von burnout (Gast)


Lesenswert?

wow, tolle Sache!
es funktioniert! happy
DANKE!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.