Forum: Compiler & IDEs Atmega32l + ADC - wo ist der Fehler?


von Jan D. (asd_d)


Lesenswert?

Hallo Zusammen,

hoffe ich bin hier richtig gelandet. Ich habe einen Atmega32l mit 1Mhz 
und versuche den ADC ans Laufen zu bekommen - stehe aber ein wenig auf 
dem Schlauch. Wandeln lassen möchte ich mir zum Testen GND (MUX0 bis 3 = 
"1"). Ich erhalte per UART folgende Ausgabe (Nr.Druchgang  HighByte 
LowByte):
1
0   3   253
2
1   0   1
3
2   3   252
4
3   0   0
5
4   0   0
6
5   3   254
7
6   3   255
8
7   3   252
9
8   3   255
10
9   0   0
11
10   3   253
12
11   3   251
13
12   3   251
14
13   0   2
15
14   3   255
16
15   3   251
17
16   3   248
18
17   3   253
19
18   0   2

Hier der Code:
1
ADMUX = (1<<REFS0) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0);  //internal reference
2
3
ADCSRA = (1<<ADIE) | (1<<ADEN) | (1<<ADPS2) | (0<<ADPS1) | (0<<ADPS0); // adc on, prescaler = 8 => 125kHz
4
MCUCR  |= (1<<SE);    // sleep enable
5
sei();        // int enable
6
7
int count = 0;
8
while(1)
9
{
10
    ADCSRA |= (1<<ADSC);  // run adc
11
    while( ADCSRA & (1<<ADSC) )  // wait for adc
12
      asm volatile ("sleep");
13
14
    uint8_t adcValueLow = ADCL;    // low byte first
15
    uint8_t adcValueHigh = ADCH;  // locked high byte
16
17
    uart_printf( "%d   %d   %d\r\n", count++, adcValueHigh, adcValueLow );
18
19
    long_delay(1000);
20
}

Jemand eine Idee?

: Bearbeitet durch User
von Uwe (de0508)


Lesenswert?

Hallo,

was soll damit bezweckt werden?
1
while( ADCSRA & (1<<ADSC) )  // wait for adc
2
      asm volatile ("sleep");

Und ja, ich kann den Code lesen.

von holger (Gast)


Lesenswert?

>Ich habe einen Atmega32l mit 1Mhz
>und versuche den ADC ans Laufen zu bekommen

Dann mach das erst mal ohne das ganze Sleep Geraffel.

>ADCSRA = (1<<ADIE)

Wo ist dein Code für den ADC Interrupt Vector?

von Jan D. (asd_d)


Lesenswert?

Also der Plan hinter dem sleep ist, diesen noise reduction-Modus zu 
verwenden. Ich dachte mir, vielleicht ist das die Fehlerquelle. Mit ADIE 
wird dieser eingestell und mit dem sleep gestartet. Sollte jetzt ein 
anderer Interrupt die CPU vorzeitig wecken, dann schickt die Schleife 
ihn so lange wieder schlafen, bis der ADC durch ist.

Meine Test-ISR ist folgende:
1
ISR(ADC_vect)
2
{
3
}
Da ich jedoch ADIF nicht setze, wird diese nicht angesprungen - soweit 
mein Verständnis der Doku :)

Hier ohne sleep - die Ausgabe ist leider analog:
1
ADMUX = (1<<REFS0) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0);  //internal reference
2
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (0<<ADPS1) | (0<<ADPS0); // adc on, prescaler = 8 => 125kHz
3
4
int count = 0;
5
while(1)
6
{
7
    ADCSRA |= (1<<ADSC);  // run adc
8
    while( ADCSRA & (1<<ADSC) );  // wait for adc
9
10
    uint8_t adcValueLow = ADCL;    // low byte first
11
    uint8_t adcValueHigh = ADCH;  // locked high byte
12
13
    uart_printf( "%d   %d   %d\r\n", count++, adcValueHigh, adcValueLow );
14
15
    long_delay(1000);
16
}

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.