ADC gibt seltsame Werte zurück ATMEGA32

OP #2975130
Lesenswert?

Nabend,

am ADC0 (PA0) meines ATMEGA32 will ich eine Spannung messen. Diese liegt 
zurzeit bei ca. 1.8V.
Nachdem ich meinen wie sonst üblichen Code verwendet habe, schwankten 
die Werte aber immer stark, meistens blieben sie aber bei 1023. Es ist 
auch vollkommen egal, ob Masse am Pin anliegt oder eine andere Spannung!
Es ist auch komischerweise egal, welchen Kanal ich wähle. JTAG ist 
ausgeschaltet und es sind auch keine Pull-Ups aktiviert. Langsam 
verzweifel ich daran.
Jetzt habe ich den Beispielcode aus dem AVR-Tutorial kopiert und 
abgeändert, aber das Ergebnis bleibt das Selbe!

Hier der Code:
1
#include <avr/io.h>
2
#include <stdio.h>
3
#include <util/delay.h>
4
#include <stdlib.h>
5
#include <avr/interrupt.h>
6
#include <string.h>
7
#include "uart/uart.h"
8
#include "main.h"
9

10
#define UART_BAUD_RATE     57600
11

12

13
void ADC_Init(void);
14
void Spg_Rauchmelder_abfragen(void);
15

16
int8_t i=0;
17

18
int main(void)
19
{
20
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
21
  
22
  ADC_Init();
23
  
24
  sei();
25
  
26
  while(1)
27
  {
28
    Spg_Rauchmelder_abfragen();
29
    _delay_ms(1000);
30
  }
31
}
32

33

34

35
void Spg_Rauchmelder_abfragen(void)
36
{
37
  uint16_t result = 0;
38

39
  ADMUX = (ADMUX & ~(0x1F)) | (0 & 0x1F);
40
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
41
  while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung warten
42
  }
43
  result = ADCW;                    // ADC auslesen und zurückgeben
44
  
45
  char SpgTempBuffer[30];
46
  
47
  sprintf(SpgTempBuffer, "Spg-Wert: %d\r\n", result);
48
  uart_puts(SpgTempBuffer);
49
}
50

51

52
void ADC_Init(void) {
53
 
54
  uint16_t result;
55
 
56
  // interne Referenzspannung als Refernz für den ADC wählen:
57
  ADMUX = (1<<REFS1) | (1<<REFS0);
58
  
59
  // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
60
  // schon auf 0, also single conversion
61
  ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
62
  ADCSRA |= (1<<ADEN);                  // ADC aktivieren
63
 
64
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
65
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
66
 
67
  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung 
68
  while (ADCSRA & (1<<ADSC) ) {         // auf Abschluss der Konvertierung warten
69
  }
70
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
71
     Wandlung nicht übernommen. */
72
  result = ADCW;
73
}

Folgendes kommt auf dem Terminalprogramm an:
Spg-Wert: 856<\r><\n>
Spg-Wert: 945<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 1023<\r><\n>
Spg-Wert: 817<\r><\n>
Spg-Wert: 828<\r><\n>
Spg-Wert: 856<\r><\n>
Spg-Wert: 944<\r><\n>

Was mache ich falsch?!?
Vielen Dank für eure Hilfe!
Gast #2975263
Lesenswert?

Hi,
Abblockkondensator an Vref vorhanden?
Avcc von Vcc entkoppelt?
Mit hochohm. Voltmeter schon mal Spannung an Vref gemessen?
Liegen da tats. 2.56V an?
Und Diese Anweisung ist irgendwie sinnlos
> ADMUX = (ADMUX & ~(0x1F)) | (0 & 0x1F);
Kannste genauso gut weglassen, Wenn admux nicht in anderen 
Programmteilen verwendet wird
OP #2975309
Lesenswert?

Katastrophenheinz schrieb:
> Und Diese Anweisung ist irgendwie sinnlos
>> ADMUX = (ADMUX & ~(0x1F)) | (0 & 0x1F);
> Kannste genauso gut weglassen, Wenn admux nicht in anderen
> Programmteilen verwendet wird

Ja, ich weiß :-) Zum probieren bin ich die anderen Kanäle vorher auch 
mal durchgegangen. Das ist davon noch übrig geblieben.

An AREF liegen 2,62 V an und verbunden ist AREF mit einem 100nF C mit 
GND, also kein Kurzschluß.
AVcc ist zwischen einem 100nF C und einer 0,47µ L geschaltet.

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