Hallo zusammen,
ich möchte eine Spannung differentiell zwischen ADC1 und ADC0 mit
10facher Verstärkung messen.
Als Referenzspannung verwende ich AVCC. (5 V)
In einer Testschaltung gebe ich mithilfe eines Spannungsteilers
verschiedene positive Spannungen auf ADC1. ADC0 liegt auf Ground.
Gebe ich keine Spannung auf ADC1, so gibt das ADC-Register einen Wert
von 1023 aus.
Wenn ich eine Spannung von 0,5 Volt auf ADC1 gebe, sollte das Register
einen Wert von 511 ausgeben. Tut es aber nicht. Egal was ich tue, ich
kann das register nicht über den Wert 495 hinaus erhöhen.
Habt ihr eine Idee, woran es liegen kann?
Ich takte extern mit 8 MHz und setze den Prescaler für den ADC daher auf
128.
Ich habe auch schon ausprobiert, ob vielleicht das BIT4 defekt ist. Dies
ist aber nicht der Fall.
Viele Grüße
Tobias
hier noch ein paar Code-Schnipsel:
1
intADC_read_diff(void)
2
{
3
4
intADC_temp,ADCH_temp;
5
6
7
8
ADC_START_CONVERSION;
9
while(!(ADCSRA&0x10));// wait for conversion done, ADIF flag active
10
ADCSRA|=(1<<ADIF);
11
12
ADC_temp=ADCL;// read out ADCL register
13
ADCH_temp=ADCH;// read out ADCH register
14
ADC_temp+=(ADCH_temp<<8);
15
16
17
18
returnADC_temp;
19
}
20
21
voidreadDifferentialVoltage()
22
{
23
intvalue;
24
floatvolt;
25
26
ADMUX=(1<<REFS0)|(1<<MUX0)|(1<<MUX3);
27
28
_delay_ms(1);
29
value=ADC_read_diff();
30
//erste Messung soll laut Datenblatt verworfen werden.
31
_delay_ms(1);
32
value=ADC_read_diff();
33
34
35
charbuffer[64];
36
intviertesBit=(value&(1<<4))>>4;
37
38
sprintf(buffer,"\nADC-Wert = %d von 1023, viertes Bit: %d",value,viertesBit);
Tobi R. schrieb:> Gebe ich keine Spannung auf ADC1, so gibt das ADC-Register einen Wert> von 1023 aus.
Mit "keine Spannung" meinst du 0V, also Anschluß an GND?
Dafür paßt aber der Meßwert nicht, der übrigens nicht 1023 ist, sondern
in wirklichkeit -512. Bei differentieller Messung entstehen
vorzeichenbehaftete Meßwerte, allerdings begrenzt auf die gewählte Zahl
von 8 bzw. hier 10 Bits.
Bei 8 bit ist das kein Problem, da kannst du einfach mit signed char
bzw. besser int8_t arbeiten. Bei 10 Bit gibt's aber keinen direkt
passenden Datentyp, da mußt du selber Hand anlegen, um die 10 Bit
vorzeichenrichtig auf die 16 Bit von int bzw. besser int16_t zu
erweitern.
Aber das nur nebenbei, der eigentliche Punkt ist: Bei 0V Differenz hat
auch bei diffenzieller Messung mit vorzeichenbehafteten Zahlen natürlich
Null im Register zu stehen. Da stimmt also schon grundsätzlich was nicht
an der Hardware.
Wenn du die differentiellen Kanäle nutzt kannst du AVCC nicht als
Referenzspannung verwenden, die muss min. 0,5V niedriger sein.
(Datenblatt, Electrical ADC Characteristics)
Hi
>Aber das nur nebenbei, der eigentliche Punkt ist: Bei 0V Differenz hat>auch bei diffenzieller Messung mit vorzeichenbehafteten Zahlen natürlich>Null im Register zu stehen. Da stimmt also schon grundsätzlich was nicht>an der Hardware.
1023 wären -1. Also recht nah an Null heran.
> Tut es aber nicht. Egal was ich tue, ich>kann das register nicht über den Wert 495 hinaus erhöhen.
Das ist eine Abweichung von knapp über 3%. Würde mich eher wundern, wenn
es bei differentieller Messung und Gain 10 ohne Kalibrierung besser
wäre.
AppNotes zum ADC:
http://www.atmel.com/Images/doc2559.pdfhttp://www.atmel.com/Images/Atmel-8456-8-and-32-bit-AVR-Microcontrollers-AVR127-Understanding-ADC-Parameters_Application-Note.pdf
MfG Spess
Tobi R. schrieb:> while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active> ADCSRA|=(1<<ADIF);
ich würde hier, wie im Datenblatt empfohlen, das ADSC Bit in ADCSRA
pollen, statt des Interruptflags! Bei mir gab das schonmal Probleme...
1
while(ADCSRA&(1<<ADSC));
> ADC_temp = ADCL; // read out ADCL register> ADCH_temp = ADCH; // read out ADCH register> ADC_temp +=(ADCH_temp << 8);
... würde ich ebenfalls gegen:
Vielen Dank für eure Hilfe!
Ich denke, Fritz hat den Fehler gefunden.
Fritz schrieb:> Wenn du die differentiellen Kanäle nutzt kannst du AVCC nicht als> Referenzspannung verwenden, die muss min. 0,5V niedriger sein.> (Datenblatt, Electrical ADC Characteristics)
Allerdings finde ich die Information nicht in meinem Datenblatt.
http://www.atmel.com/Images/Atmel-8155-8-bit-Microcontroller-AVR-ATmega32A_Datasheet.pdf
An einer Stelle steht:
"If differential channels are used, the selected reference should not be
closer to AVCC than indicated in Table 27-4
on page 303."
Aber diese Tabelle gibt es nicht auf Seite 303 und ich habe sie auch
nicht auf einer anderen Seite gefunden.
Super!
Vielen, vielen Dank!
Fritz schrieb:> Ähh, jetzt habs ich auch falsch gemacht:> Tabelle 28-5, Seite 286 ist richtig
Habt ihr eventuell noch Tipps, wie ich jetzt eine genaue Spannung messen
kann?
Ich habe mit dem Multimeter AREF gemessen und messe 2,59 V anstatt 2,56.
Das habe ich in den Code zum ermitteln der Spannung eingebaut.
Jetzt sollte mein Mikrocontroller doch eigentlich die gleiche Spannung
zwischen ADC1 und ADC0 ausgeben, wie ein mit dem Multimeter gemessener
Wert, oder?
Allerdings zeigt das Multimeter 0,126 V und der Mikrocontroller 0,130 V.