Forum: Compiler & IDEs ADC gibt seltsame Werte zurück ATMEGA32


von Bene J. (terfagter)


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!

von Georg A. (georga)


Lesenswert?

Gibts da einen Kurzschluss zwischen AREF und GND?

von Katastrophenheinz (Gast)


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

von Bene J. (terfagter)


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.

von Ingo (Gast)


Lesenswert?

Da scheint ein Hardwarefehler vorzuliegen, wenn der Code, den du nutzt 
sonst funktioniert. Überprüf nochmal den Aufbau bzw Schaltung


Ingo

von Bene J. (terfagter)


Lesenswert?

So das Problem ist endlich gelöst. Das Problem war ein Masse Problem. 
Irgendwie war bei meinem Aufbau die Masse nicht richtig verbunden, 
wodurch die Werte am ADC und an meinem Spannungteiler immer gewandert 
sind.
Danke für eure Hilfe!

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.