Forum: Mikrocontroller und Digitale Elektronik Verständnisfrage Zweierkomplement bei ADC


von Иван S. (ivan)


Lesenswert?

Hallo,

ich habe einen ADC, dessen Werte im Zweierkomplement vorliegen sollen.
Die interne Referenz des ADCs beträgt 2 Volt.
Ich habe mir einen (unbelasteten) Spannungsteiler gebaut, die gemessene 
Spannung am Teiler liegt bei 1,097 (=1,1) Volt. Diese Spannung wird 
durch den ADC gemessen. Als Ergebnis erhalte ich im Register 4108 (hex). 
Davon sind die oberen 13 bits der ADC-Wert. Das Datenblatt sagt "The 
output is an 13-bit two’s complement value." Nur wie ich auch rechne, 
von 4108 hex komme ich nie zurück auf meine 1,1 Volt.

Ich bitte daher ergebenst um Erleuchterung.

von Karl H. (kbuchegg)


Lesenswert?

Иван S. schrieb:

> Davon sind die oberen 13 bits der ADC-Wert. Das Datenblatt sagt "The

   Sicher, dass es die oberen sind.
   Die unteren würde viel besser zu deinen Werten passen.


> output is an 13-bit two’s complement value." Nur wie ich auch rechne,
> von 4108 hex komme ich nie zurück auf meine 1,1 Volt.


Überschlagsmässig

  13 Bit  ->  Maximalwert: 8191    bei 2 Volt

Du hast einen Messwert von 4108, das ist etwas mehr als die Hälfte von 
8191. Also wird wohl auch die Spannung etwas mehr als die Hälfte von 2V 
betragen haben.
Bingo: 1.1V ist etwas mehr als die Hälfte


Simple Dreisatzrechnung:
8191 Äpfel kosten 2 Euro. Wieviel kosten 4108 Äpfel?

von Gast (Gast)


Lesenswert?

> Als Ergebnis erhalte ich im Register 4108 (hex).

Das ist doch kein Hex.

Was für ein geheimer ADC ist das denn?

von Иван S. (ivan)


Lesenswert?

Karl heinz Buchegger schrieb:
> Иван S. schrieb:
>
>> Davon sind die oberen 13 bits der ADC-Wert. Das Datenblatt sagt "The
>
>    Sicher, dass es die oberen sind.
>    Die unteren würde viel besser zu deinen Werten passen.

Das Datenblatt meint die oberen.

>> output is an 13-bit two’s complement value." Nur wie ich auch rechne,
>> von 4108 hex komme ich nie zurück auf meine 1,1 Volt.
>
> Überschlagsmässig
>
>   13 Bit  ->  Maximalwert: 8191    bei 2 Volt

Genau, so weit war ich schon.

> Du hast einen Messwert von 4108, das ist etwas mehr als die Hälfte von
> 8191.

Hmm, nur 4108 ist doch Hex unde 8191 ist dezimal. Ich dachte immer, ich 
darf keine Äpfel mit Birnen vergleichen.

> Simple Dreisatzrechnung:
> 8191 Äpfel kosten 2 Euro. Wieviel kosten 4108 Äpfel?

Ist es wirklich so einfach?

von (prx) A. K. (prx)


Lesenswert?

Zweierkompletement heisst doch wohl Differenzmessung, also
0xFFF8 .. 0x0000 .. 0x7FF8 = -2,0V .. 0V .. +2,0V(knapp drunter)

Wenn bei dir die Differenz zu 0V gemessen wird, dann passt es:
  2.0V => 0x7FF8
  1,1V => 0x4108 => 0x4108/0x8000 * 2,0V = ~1,02V
  0.0V => 0x0000

von Hc Z. (mizch)


Lesenswert?

2/2^12 ⋅ 0x4108/8 = 1,0161

Erläuterung:

2/2^12 = Wert eines Bits vom ADC (MSB ist Vorzeichen, bleiben 12)

0x4108/8 = Der ausgelesene Wert, unterstes Bit in die Einerstelle 
verschoben (0x4108>>3).

von Иван S. (ivan)


Lesenswert?

Gast schrieb:
>> Als Ergebnis erhalte ich im Register 4108 (hex).
>
> Das ist doch kein Hex.

Ich denke schon.

> Was für ein geheimer ADC ist das denn?

Es handelt sich um den eingebauten ADC des z8 encore! XP. Das Datenblatt 
meint: "The ADC Data High Byte (ADCD_H) register contains the upper 
eight bits of the ADC output." Mein ADCD_H ist 41h. Ähnlich verhält es 
sich mit dem ADCD_L, nur dass hier nur die oberen 5 Bits zum ADC-Wert 
beitragen. Mein ADCD_L-Wert beträgt (laut Debugger) 08h.

von Karl H. (kbuchegg)


Lesenswert?

Иван S. schrieb:

>> Du hast einen Messwert von 4108, das ist etwas mehr als die Hälfte von
>> 8191.
>
> Hmm, nur 4108 ist doch Hex unde 8191 ist dezimal. Ich dachte immer, ich
> darf keine Äpfel mit Birnen vergleichen.

:-)
Mein Fehler.
Hab mich von der Zahl blenden lassen

Aber A.K. hat das ja schon aussortiert.

> Ist es wirklich so einfach?

Ja. Wenn man die Obergrenze richtig einsetzen würde :-)

  0x8000 Äpfel kosten 2 Euro. Wieviel kosten 0x4108 Äpfel.

(0x8000, weil 0x7FF8 die größte positive Zahl ist, die vom ADC kommen 
kann und der ADC in Schritten von 0x0008 erhöht. Genau das ist 
letztendlich die Bedeutung von 'die oberen 13 Bit'. Man könnte aber auch 
ganz einfach alle Zahlen signed um 3 Stellen nach rechts shiften. Dann 
hat man schöne kleine Zahlen ohne 0x0008 Schritte.

von Иван S. (ivan)


Lesenswert?

Danke euch allen, mir ist jetzt vieles klarer. Jetzt muss ich es nur 
noch verstehen. Übung macht den Meister.

Iwan, der sich jetzt eine Pizza genehmigt und allen gute Mahlzeit 
wünscht.

von Иван S. (ivan)


Lesenswert?

Ich habe wieder neue Messungen angestellt, aber die Werte passen nicht 
so recht mit den vom Multimeter gemessenen zusammen.

Beispiel 1:
Der Maximalwert des ADCS beträgt 7FF8h, das ist 32760d.
Die gemessene Spannung laut Multimeter beträgt 1,650V
Das ADC-Register beinhaltet nach Messung 6400h, das ist 25600d.
25600d entspricht umgerechnet 1,56V
Der Fehler beträgt 0,09V

Beispiel 2:
Der Maximalwert des ADCS beträgt 7FF8h, das ist 32760d.
Die gemessene Spannung laut Multimeter beträgt 0,827V
Das ADC-Register beinhaltet nach Messung 3100h, das ist 12544d.
16648d entspricht umgerechnet 0,766V
Der Fehler beträgt 0,061V

Wo liegt also das Problem? Ist die interne ADC-Referenz dermaßen 
ungenau?
Kann ich mir eigentlich nicht vorstellen, immerhin handelt es sich um 
eine Bandgap. Oder bescheißt mich mein Multimeter? Kann ich mir aber 
auch kaum Vorstellen, das Multimeter ist ein besseres von Velleman und 
die am Spannungsteiler gemessenen Werte sind sehr plausibel.

Wo kann das Problem liegen?

Ehrlich gesagt hab' ich das mit dem Zweierkomplement nicht so recht 
verstanden, wir habe doch nie umgerechnet. Liegt hier eventuell der 
Fehler begraben?

Mit bestem Dank und schlumpfigem Gruß, Iwan

von Bernd (Gast)


Lesenswert?

Rechne doch den Fehler mal über 2 Stützpunkte... immer diese AD Wandler 
Verunsicherung hier :-)

Also, les den rohen AD Wert bei Eingangsspannung 0,4 V und dann bei z.B. 
bei 2 V. Dann hast du nen Delta U und nen Delta ADC. Nun kannst Du die 
Steigung ausrechnen und den Wandler mal korregieren.

Genaus kannst Du den Offset so bestimmen.

Beispiel: Faktor = Umax-Umin/ADCmax-ADCmin => Steigung
Offset = Umin - (Faktor * ADCmin)

Nun verwendest du (ADC_Wert * Faktor) + Offset

Wetten dann paßt es :-)

Dazu brauchst du weder zu wissen wie die interne RefSpannung ist noch 
sonstwas. Kannst ne schöne Autokalibrierung daraus machen.

Es gibt keinen fehlerfreien Wandler.

von Hannes L. (hannes)


Lesenswert?

> Ehrlich gesagt hab' ich das mit dem Zweierkomplement nicht so recht
> verstanden,

Nur zu Zweierkomplement, ohne jetzt auf Deinen Controller einzugehen:

Schau Dir das Format der Integer-Zahl (signed) oder Signed Byte an. Die 
untere Hälfte des Wertebereiches sind positive Zahlen. Die obere Hälfte 
des Wertebereiches sind negative Zahlen in Zweierkomplement-Darstellung.

Beispiel Signed Byte:

$fe   -2
$ff   -1
$00    0
$01    1
$02    2
...
$7e  126
$7f  127
$80 -128
$81 -127
...
$fe   -2

Wenn Dein Messwert im Zweierkomplement vorliegt, dann musst Du anhand 
des höchsten Bits das Vorzeichen feststellen. Ist es positiv, dann ist 
alles gut, ist es negativ, dann merkst Du es Dir (das es negativ ist) 
und bildest das Zweierkomplement des Messwertes, um den absoluten 
Zahlenwert (z.B. für Ziffernausgabe) zu erreichen. Musst Du das Ergebnis 
"verrechnen", so kannst Du es gleich im Zweierkomplement lassen, denn 
das wurde erfunden, damit das Rechnen einfacher wird.

...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Ist die interne ADC-Referenz dermaßen ungenau?
Das steht im Datenblatt:
1
VREF Internal Reference Voltage 
2
min. 1.9   typ. 2.0   max. 2.4  V
Soviel zum Thema GENAU :-/

von Karl H. (kbuchegg)


Lesenswert?

Vergiss die Sache mit dem 2-er Komplement.
Der Hersteller will dadurch nur ausdrücken, dass der Ergebniswert zwar 
linksbündig im Register sitzt, du den Wert aber ohne Probleme nach 
rechts shiften kannst. Und zwar unabhängig davon, ob du den Wert als 
signed oder unsigned ansiehst.
Wenn du ihn als signed ansehen würdest, und wenn das MSB eine 1 wäre, 
dann hättest du negative Zahlen. Da es sich um einen 12-Bit ADC handelt, 
hat der Hersteller diese 12 Bit so im Register ausgerichtet, dass er die 
13 höherwertigsten Bit benutzt von denen das MSB immer 0 sein wird. 
Damit hast du auch dann, wenn das Ergebnis als signed angesehen wird 
immer eine positive Zahl. Und die bleibt auch positiv, wenn du die Zahl 
arithmetisch nach rechts shiftest (in dem Fall wird ja das MSB 
dupliziert)

Vereinfacht gesagt bedeutet die Aussage:
Mach dir keine Gedanken. Hol dir den ADC Wert in einen int und rechne 
damit wie du willst und es wird immer das Richtige rauskommen ohne dass 
du aufpassen musst, dass du zwischendrinn einen unsigned Schritt haben 
müsstest.

(Alles betrachtet für den Fall: Absoluter Wert wird gemessen, also keine 
Differenzmessung 2-er Eingänge)

von Иван S. (ivan)


Lesenswert?

Bernd schrieb:
> Also, les den rohen AD Wert bei Eingangsspannung 0,4 V und dann bei z.B.
> bei 2 V. Dann hast du nen Delta U und nen Delta ADC. Nun kannst Du die
> Steigung ausrechnen und den Wandler mal korregieren.

Ok, mal gemessen bei 0,658V: ADC-Wert 2700h (= 9984dec)
Nun mal gemessen bei 1,979V: ADC-Wert 7600h (=30208dec)

> Genaus kannst Du den Offset so bestimmen.
> Beispiel: Faktor = Umax-Umin/ADCmax-ADCmin => Steigung

Faktor = (1,979-0,658)/(30208-9984) = 6,532*10^-5

> Offset = Umin - (Faktor * ADCmin)

Offset = 0,658 - (6,532*10^-5 * 9984) = 0,0058

> Nun verwendest du (ADC_Wert * Faktor) + Offset

Ok, ADC-Wert 30208 * 6,532*10^-5 + 0,0058 = 1,979V

> Wetten dann paßt es :-)

Schön, das würde ganz genau passen.

> Es gibt keinen fehlerfreien Wandler.

Naja, ehrlich gesagt hätte ich mir von "Factory Calibratet Bandgap 
Reference" etwas mehr erwartet. Schade. Denn die ganze Rechnerei ist 
ziemlich aufwändig, immerhin sind da viele sehr große (Word-) Werte, als 
auch sehr kleine (10^-5) im Spiel. Für meine persönlichen Begriffe ist 
diese Rechnerei auf einem 8bitter ganz schön sportlich.

Großes Danke für Deine Hilfe!

von Bernd (Gast)


Lesenswert?

Das geht ganz gut wenn du es entsprechend skalierst, probiers halt mal.

von Иван S. (ivan)


Lesenswert?

Hannes Lux schrieb:
> Musst Du das Ergebnis "verrechnen", so kannst Du es gleich im
> Zweierkomplement lassen, denn das wurde erfunden, damit das Rechnen
> einfacher wird.

In wie Fern das einfacher ist, erschließt sich mir noch nicht ganz. Aber 
ich bin ehrlich gesagt auch erst bei den ersten Schritten auf einem 
langen Weg.

Wie ich die Großen und kleinen Zahlen umrechen Werde, dazu habe ich in 
den nächsten Wochen ja noch gelegenheit zum Üben.

Danke für Deine Antwort!

von Иван S. (ivan)


Lesenswert?

Karl heinz Buchegger schrieb:

> Wenn du ihn als signed ansehen würdest, und wenn das MSB eine 1 wäre,
> dann hättest du negative Zahlen. Da es sich um einen 12-Bit ADC handelt,
> hat der Hersteller diese 12 Bit so im Register ausgerichtet, dass er die
> 13 höherwertigsten Bit benutzt von denen das MSB immer 0 sein wird.

Das ist schon 'mal ein Lichtblick!

> Damit hast du auch dann, wenn das Ergebnis als signed angesehen wird
> immer eine positive Zahl. Und die bleibt auch positiv, wenn du die Zahl
> arithmetisch nach rechts shiftest (in dem Fall wird ja das MSB
> dupliziert)

Sehr gut, das macht Hoffnung.

> Vereinfacht gesagt bedeutet die Aussage:
> Mach dir keine Gedanken. Hol dir den ADC Wert in einen int und rechne
> damit wie du willst und es wird immer das Richtige rauskommen ohne dass
> du aufpassen musst, dass du zwischendrinn einen unsigned Schritt haben
> müsstest.
> (Alles betrachtet für den Fall: Absoluter Wert wird gemessen, also keine
> Differenzmessung 2-er Eingänge)

Super, Danke für Deine Aufmunterung!

Für's Erste werde ich wohl trotzdem eher eine externe Referenz bemühen, 
das scheint mir um einiges einfacher.

von Karl H. (kbuchegg)


Lesenswert?

Иван S. schrieb:

>> Wetten dann paßt es :-)
>
> Schön, das würde ganz genau passen.

Logisch.
Du hast ja die Gerade exakt so berechnet, dass sie durch deine 
Messpunkte geht. Wenn dann die Messpunkte nicht auf der Geraden liegen 
würden mit der du die Gerade berechnet hast, hättest du dich verrechnet 
:-) (Im Grunde hast du mit dem Test mit 30208 nichts anderes gemacht als 
die Probe ob du dich nicht verrechnet hast)

Interessanter ist aber der Fall: Wie ist das mit anderen Messwerten und 
derselben Kalibriergeraden? Stimmt dann das Ergebnis immer noch?

von Bernd (Gast)


Lesenswert?

Karl Heinz, die muß stimmen, es geht um die Korrektur eines linearen 
Fehlers. Keine Ahnung wie du ADC's korregierst, ich machs in der Regel 
immer so und berechne auf diesem Weg auch die tatsächliche interne VREF.

Kennst Du einen besseren Weg ?

von Karl H. (kbuchegg)


Lesenswert?

Bernd schrieb:
> Karl Heinz, die muß stimmen, es geht um die Korrektur eines linearen
> Fehlers. Keine Ahnung wie du ADC's korregierst, ich machs in der Regel
> immer so und berechne auf diesem Weg auch die tatsächliche interne VREF.
>
> Kennst Du einen besseren Weg ?

Nein, das wollte ich auch nicht damit sagen.
Ich wollte ivan eigentlich nur zum Nachdenken anregen, ob der Test den 
er da gemacht hat, die Aussage "Stimmt ganz genau" rechtfertigt oder 
nicht.
Wenn ich mit einem Lineal eine Gerade durch eine Punkteschar lege, die 
angeblich(*) alle auf einer Geraden liegen und ich benutze zur Kontrolle 
genau die beiden Punkte die ich benutzt habe um das Lineal anzulegen, 
dann ist diese Kontrolle ein wenig witzlos. Klar liegen die auf der 
Linie, ich habe ja das Lineal genau so angelegt, dass diese beiden 
Punkte genau drauf liegen.


(*) angeblich sage ich deshalb, weil das zunächst eine Annahme ist. Es 
gibt gute Gründe dafür, dass diese Annahme richtig ist. Wenn ich aber 
bei 0 anfange, ist es erst einmal eine Annahme, die man glauben kann 
oder auch nicht, die man aber auch einfach austesten kann. Nur wenn man 
sie testet, sollte man das auch richtig machen.

von Иван S. (ivan)


Lesenswert?

Karl heinz Buchegger schrieb:
> Иван S. schrieb:

> Interessanter ist aber der Fall: Wie ist das mit anderen Messwerten und
> derselben Kalibriergeraden? Stimmt dann das Ergebnis immer noch?

Gut, dann probieren wir es eben mit 1,318V

ADC-Wert 4E00h -> 19968 dec.

> Nun verwendest du (ADC_Wert * Faktor) + Offset

1,310 Volt. Passt ziemlich genau :-)

Ich werd' wohl für's erste doch mit externen Referenzen Arbeiten, mir 
fehlen einfach noch die Assembler-Kenntnisse um's berechnen zu können.

Jedenfalls vielen Dank für die Formeln, da wär' ich nie draufgekommen.
Die sind ja wohl allgemeingültig, da sollte man mal was ins Wiki 
schreiben :-)

LG aus Österreich, Iwan

von Иван S. (ivan)


Lesenswert?

Karl heinz Buchegger schrieb:
> Ich wollte ivan eigentlich nur zum Nachdenken anregen, ob der Test den
> er da gemacht hat, die Aussage "Stimmt ganz genau" rechtfertigt oder
> nicht.
> Wenn ich mit einem Lineal eine Gerade durch eine Punkteschar lege, die
> angeblich(*) alle auf einer Geraden liegen und ich benutze zur Kontrolle
> genau die beiden Punkte die ich benutzt habe um das Lineal anzulegen,
> dann ist diese Kontrolle ein wenig witzlos.

Ja, zu meiner Schande muss ich gestehen, daß ich das einfach übersehen 
habe.
Mit der neuen (letzten) Messung mit einem neuen Wert zeigt sich jedoch, 
daß meine Rechnerei passt. Netter Nebeneffekt: Jetzt weiss ich auch, daß 
mein Multimeter so genau ist, wie ich es mir gedacht hatte.

LG, Iwan

von Bernd (Gast)


Lesenswert?

>> Die sind ja wohl allgemeingültig

Sind sie. Ich verwende so eine Rechnung auf nem ATTINY-26 und der ist 
kein Speicherwunder (2K). Dabei macht der noch oversampling und liefert 
ein wunderbares Ergenbis auf seiner 4 Stelligen 7-Segementanzeige ab. So 
baut man Meßgeräte für nen Euro statt für 5 :-)

von (prx) A. K. (prx)


Lesenswert?

Иван S. schrieb:

> Wo liegt also das Problem? Ist die interne ADC-Referenz dermaßen
> ungenau? Kann ich mir eigentlich nicht vorstellen, immerhin handelt
> es sich um eine Bandgap.

Unkalibrierte Bandgaps sind nicht genau, wie man im Datasheet sieht. Sie 
sind aber ziemlich stabil gegenüber Änderungen von Vcc und Temperatur.

von Иван S. (ivan)


Lesenswert?

A. K. schrieb:
> Иван S. schrieb:
>
>> Wo liegt also das Problem? Ist die interne ADC-Referenz dermaßen
>> ungenau? Kann ich mir eigentlich nicht vorstellen, immerhin handelt
>> es sich um eine Bandgap.
>
> Unkalibrierte Bandgaps sind nicht genau, wie man im Datasheet sieht.

Naja, ehrlich gesagt hatte ich im DB nicht gelesen, daß sie zwischen 2,0 
und 2,4 V liegen kann. Das ist das erste definitive Manko, das ich an 
den Zilogs ausmachen kann. Unter "Factory calibrated Bandgap" hätte ich 
mir ehrlich gesagt schon ein bischen mehr erwartet. Gut, daß ich hier 
noch ein paar AD360-Referenzen rumliegen hab'.

> Sie sind aber ziemlich stabil gegenüber Änderungen von Vcc und Temperatur.

Immerhin etwas.

Lieber und schlumpfiger Gruß, Iwan

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Naja, ehrlich gesagt hatte ich im DB nicht gelesen, daß sie zwischen 2,0
> und 2,4 V liegen kann. Das ist das erste definitive Manko, das ich an
> den Zilogs ausmachen kann.
Andere sind nicht signifikant besser: ein ATmega32 hat z.B.
1
VBG Bandgap reference voltage  min 1.15   typ 1.23   max 1.35 V

von Bernd (Gast)


Lesenswert?

Ivan, noch mal eine Gedankenstütze.

>> Offset = 0,658 - (6,532*10^-5 * 9984) = 0,0058

Den wirst du auch nicht durch eine externe Referenz los.

Beim erweitern von Zahlen sind wir ja z.B. gewohnt:

2,345 * 1000 = 2345.

Hast Du dir mal überlegt das man auch anders erweitern kann ?

2,345 * 16384 = 38420,34

38420 >> 14 = 2,345

:-)

Nen MC teilt gerne durch 2.

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.