Forum: Mikrocontroller und Digitale Elektronik ADC-Wert um die Hälfte falsch


von Luca E. (derlucae98)


Lesenswert?

Hallo,

ich habe hier ein HF Powermeter Modul von SV1AFN und bekomme es nicht 
richtig zum laufen.
https://www.sv1afn.com/ad8318.html
Schaltplan: 
https://nebula.wsimg.com/d41306bc9bd03c6e4d0503ceb3a5fab8?AccessKeyId=DAA432FA80C5DABC0234&disposition=0&alloworigin=1

Dort sitzt ein AD7887 12-Bit ADC drauf. Ich kann ihn auch per SPI 
auslesen, allerdings sind die Werte um die Hälfte falsch.
Wenn ich den Eingang des AD8318 mit 50Ω terminiere, erhalte ich 2,13V am 
Ausgang des AD8318, die auch am Eingang des ADC anliegen.
Die Referenzspannung beträgt 2,49V, so wie es sein soll.
Als ADC Wert würde man jetzt etwa 3500 erwarten, ich erhalte aber nur 
etwa 1750, also die Hälfte.
Damit ist natürlich auch die berechnete Spannung nur halb so groß.

Ich vermute, dass der ADC nicht die externe Referenz, sondern VDD (5V) 
als Referenz verwendet. Das wäre der Fall, wenn das "SIN/DUAL" Bit auf 0 
gesetzt wird. Ich setze es jedoch auf 1 und deaktiviere die interne 
Referenz.
Vielleicht habe ich auch nur das Kontrollregister auf S. 10 des 
Datenblatts falsch verstanden.
http://www.analog.com/media/en/technical-documentation/data-sheets/AD7887.pdf


Was läuft hier falsch?


Hier noch der Code:
1
$regfile = "m88adef.dat"
2
$crystal = 8000000        'Interner Oszillator (CLKDIV8 deaktivieren)
3
$baud = 19200
4
5
config portb.2 = output
6
cs alias portb.2
7
cs = 1
8
config PORTB.3 = Output
9
config pinb.4 = input
10
config PORTB.5 = Output
11
12
config serialout = buffered, size = 30
13
14
dim adc_contr as Byte
15
dim adc_value_1 as Byte
16
dim adc_value_2 as Byte
17
dim conversion_result as word
18
dim dbm_voltage as single
19
20
config spi = hard, interrupt = off, Data_order = msb, master = yes, polarity = high, phase = 0, clockrate = 16, noss = 1
21
Enable Spi
22
Spiinit
23
enable interrupts
24
25
Config Single = Scientific , Digits = 3
26
27
28
do
29
   cs = 0
30
   adc_contr = &B00100001 'ADC Kontrollregister
31
   adc_value_1 = spimove(adc_contr)
32
   spiin adc_value_2, 8
33
   cs = 1
34
35
   conversion_result = makeint(adc_value_2, adc_value_1) 'ADC-Wert zusammenführen
36
37
   wait 3
38
39
   print "Wert1: "; adc_value_1
40
   print "Wert2: "; adc_value_2
41
   print "Ergebnis: "; conversion_result
42
43
   dbm_voltage =  conversion_result * 0.000610351  'Adc-Wert in Spannung umrechnen (0.000610351 = 2.5/2^12)
44
   print "Spannung: "; dbm_voltage
45
   dbm_voltage = dbm_voltage*2
46
   print "Spannung (korrigiert): "; dbm_voltage
47
loop

von Bernadette (Gast)


Lesenswert?

Füge mal

Config Adc = Single , Prescaler = Auto , Reference = Internal

ein.

Danch kannst du ja das Kontrollregister auslesen und vergleichen, ob 
deine Bits richtig waren.

von Bernadette (Gast)


Lesenswert?

Ups,

hat sich erledigt.
Du willst ja die Register im Modul schreiben.

von Luca E. (derlucae98)


Lesenswert?

Bernadette schrieb:
> Füge mal
>
> Config Adc = Single , Prescaler = Auto , Reference = Internal
>
> ein.

Damit würde ich ja den internen ADC des Atmega88 ansprechen. Ich habe 
aber einen externen ADC, der per SPI angesprochen wird.

von Thomas (Gast)


Lesenswert?

Hallo Luca,

SV1AFN sendet als Control Word 10100001 während Du 00100001 sendest.

Quelle: https://www.sv1afn.com/ad8318.html

Das MSB ist zwar aut Datenblatt "Don't care", aber einen Versuch ists 
doch wert!

von Thomas (Gast)


Lesenswert?

Unter

https://nebula.wsimg.com/9d68a95463bc9965bb6c92637ac085d8?AccessKeyId=DAA432FA80C5DABC0234&disposition=0&alloworigin=1

habe ich SV1AFNs Arduino-Code für den AD7887 gefunden. Vergleiche doch 
mal, was er vielleicht anders macht!

von Luca E. (derlucae98)


Lesenswert?

Thomas schrieb:
> Das MSB ist zwar aut Datenblatt "Don't care", aber einen Versuch ists
> doch wert!

Habe ich alles schon versucht. Keine Veränderung.

Thomas schrieb:
> Vergleiche doch
> mal, was er vielleicht anders macht!

Er macht die SPI Ausgabe manuell, weil er die SPI Bibliothek nicht zum 
laufen bekommt. Außer dass er, nachdem er /CS auf low gezogen hat, mit 
den 10x digitalWrite(SPICLOCK,HIGH); ein Delay einfügt, sehe ich da 
jetzt keine Unterschiede.

Ich habe mir die Clock und die MOSI Leitung mal mit dem Oszi angesehen. 
Offensichtlich hatte ich den falschen SPI Mode erwischt. Mit CPOL = 1 
und CPHA = 1 bekomme ich jetzt den Wert 4090. Das ist wiederum etwas zu 
hoch.

Dann ist mir aufgefallen, dass da 9 Clockpakete rausgehen. Der Fehler 
war also offensichtlich:
1
spiin adc_value_2, 8

Die 8 steht also nicht für die Anzahl der Clockpulse, sondern für die 
Anzahl der einzulesenden Bytes. Nachdem ich das auf
1
spiin adc_value_2, 1

geändert habe, erhalte ich den Wert 3480. Das scheint also jetzt zu 
passen.

Was lernen wir daraus? Nächstens direkt das Oszi auspacken...

: Bearbeitet durch User
von MWS (Gast)


Lesenswert?

Luca E. schrieb:
> Die 8 steht also nicht für die Anzahl der Clockpulse, sondern für die
> Anzahl der einzulesenden Bytes.
Würdest Du die Hilfe zur Programmiersprache und dort zu Spiin lesen, 
wäre Dir das zu Beginn an klar gewesen.

> Was lernen wir daraus? Nächstens direkt das Oszi auspacken...
Nein, wir lernen daraus, dass man das Werkzeug beherrschen sollte, mit 
dem man arbeitet.

von Thomas (Gast)


Lesenswert?

Luca E. schrieb:
> Dann ist mir aufgefallen, dass da 9 Clockpakete rausgehen. Der Fehler
> war also offensichtlich:spiin adc_value_2, 8

War mir gar nicht aufgefallen. Stimmt natürlich.

Insofern war es doch gut, das Du den Oszi zumindest soweit beherrschst, 
um den Fehler damit zu finden =;-)

von Wolfgang (Gast)


Lesenswert?

Luca E. schrieb:
> Was lernen wir daraus? Nächstens direkt das Oszi auspacken...

Das wäre sogar mit einem kleinen Logikanalysator für unter 5€ 
aufgefallen.

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.