ADC - Atmega128

Gast #2050007
Lesenswert?

Hallo Leute,
ich hab jetzt schon einige Zeit gesucht aber nix gefunden...
Hier mein Problem:
Ich habe die ADC Routine aus dem GCC Tutorial genommen aber leider tut 
die nicht ganz.

Ich bekomme folgende Werte:
Init done!
Systime:0 ms
ADC 0: 511  ADC 1: 479  ADC 2: 476  ADC 3: 514  ADC 4: 536  ADC 5: 550 
ADC 6: 552  ADC 7: 550      ADC BG: 373  ADC 0V: 0

Systime:520 ms
ADC 0:  57  ADC 1:  70  ADC 2:  82  ADC 3: 106  ADC 4: 129  ADC 5: 154 
ADC 6: 177  ADC 7: 200      ADC BG: 373  ADC 0V: 0

Systime:1050 ms
ADC 0:   1  ADC 1:   0  ADC 2:   0  ADC 3:   1  ADC 4:   1  ADC 5:   0 
ADC 6:   2  ADC 7:   3      ADC BG: 373  ADC 0V: 0

wie man sieht fallen die Werte langsam gegen 0, doch das tun sie auch 
wenn ich VCC anschließe oder die PORTS anschalte (wie in diesem Fall 
DDRA=0xFF PORTA=0xFF).
Die Werte von der BG (MUX=30) und GND (MUX=31) stimmen sofort 
(373/1,23V*1024 = 3,37V)

Hat jemand eine Idee oder einen Link (bitte nicht das Tutorial)?
Gast #2050040
Lesenswert?

Das Board läuft mit 7,273800Mhz und das hier ist es:
http://www.chip45.com/AVR-Mikrocontroller-System-Platinen/Savvy128-V1-3-ATmega128-USB-RS232-RS485-Echtzeituhr-SD-Karte.html

Hier die Main:
1
int main()
2
{
3
  adc_init();
4
  timer_init();
5
  uart_init(UART_BAUD_SELECT(19200,F_CPU));
6
  stdout = &mystdout;
7
  sei();
8
  printf("Init done!\r\n");
9

10
  DDRA = 0xFF;
11
  PORTA= 0x0F;
12

13
  while(1){
14
  printf("Systime:%lu ms\r\n",ulTime);
15
  _delay_ms(200);
16

17
  for(uint8_t i= 0 ; i<8 ; i++){
18
    uint16_t val = getAdcValueAvg(i);
19
    printf("ADC %d: %3d  ",i,val);
20
  }   
21
  printf("ADC BG: %3d  ",getAdcValueAvg(30));
22
  printf("ADC 0V: %3d\r\n",getAdcValueAvg(31));
23
  }
24
}

und hier die ADC Routine
1
void adc_init(){
2
 
3
  uint16_t result;
4
 
5
  ADMUX = (0<<REFS1) | (1<<REFS0);            // AVcc als Referenz benutzen
6
  ADCSRA = (1<<ADPS2)|(1<<ADPS1) | (0<<ADPS0);// Frequenzvorteiler
7
  ADCSRA |= (1<<ADEN);                        // ADC aktivieren
8
 
9
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
10
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
11
 
12
  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung 
13
  while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten
14
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
15
     Wandlung nicht übernommen. */
16
  result = ADCW;
17
}
18

19
uint16_t getAdcValue(uint8_t bChannel){
20
  // Kanal waehlen, ohne andere Bits zu beeinflußen
21
  ADMUX = (ADMUX & ~(0x1F)) | (bChannel & 0x1F);
22
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
23
  while (ADCSRA & (1<<ADSC) ) {}  // auf Abschluss der Konvertierung warten
24
  return ADCW;                    // ADC auslesen und zurückgeben
25
}
26

27

28
uint16_t getAdcValueAvg(uint8_t bChannel){
29
  uint32_t result = 0;
30
  for (uint8_t i = 0; i < 128; ++i )
31
    result += getAdcValue( bChannel );
32
  return (uint16_t)( result / 128 );
33
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren