N'Abend Leute!
Vielleicht habe ich ja Glück und es hat schonmal jemand mit diesem ADC
gearbeitet...also wie gesagt, es handelt sich um den AD7794 von Analog
Devices. Dies ist ein 24Bit Sigma-Delta-Wandler. An dieser Stelle bitte
keine Diskussion über die Sinnhaftigkeit vom Einsatz eines
24Bit-Wandlers - ich verwende diesen, da er von den Features her perfekt
passt und weil er auch noch zwischen -40°C und +125°C super Ergebnisse
liefert. Die 24Bit sind dabei nicht nötig, da es sich bei dem Aufbau
aber um ein Einzelstück handelt, ist der horrende Preis nicht
ausschlaggebend.
Also: Ich habe den ADC bereits erfolgreich im Betrieb - er läuft in
einer Temperaturkammer und misst zyklisch verschiedene Probanden, welche
durch einen Multiplexer auf seine Eingänge gelegt werden. Soweit erstmal
alles problemlos.
Was aber leider passiert: Irgendwann steigt er aus...völlig sporadisch
liefert er nurnoch Müll zurück. Wohl gemerkt auch bei Raumtemperatur,
also daran liegt es nicht. Starte ich alles neu (egal ob Strom weg und
wieder dran, oder nur durch einen Reset des Programms während des
Debuggens), dann ist wieder alles in Ordnung...bis er dann irgendwann
wieder aussteigt.
Angesteuert wird er durch eine State-Machine, welche im Hintergrund
ihren Dienst verrichtet - und dies auch perfekt, bis eben dann
irgendwann...
Was hilft ist, wenn ich zwischendurch einen Software-Reset an den ADC
sende (4 Bytes mit 0xFF), dann geht es wieder, aber dann muss ich auch
immer alle Register wieder neu beschreiben. Dies ist natürlich möglich,
aber im Prinzip darf das ja nicht sein - ich habe so etwas jedenfalls
noch nie erlebt bei anderen Bausteinen.
Vor dem Holen des Ergebnisses frage ich immer schön den Status ab und
hole das Ergebnis nur dann, wenn es auch als fertig angezeigt wird.
An dieser Stelle würde ich erstmal gerne wissen, ob evtl. auch schonmal
jemand mit dem ADC gearbeitet hat und ggf. auch ein Problem damit hatte
- vielleicht kann man sich ja austauschen. Ansonsten gebe ich natürlich
gerne weitere Infos.
Danke erstmal.
Eine wichtige Sache noch hinterher:
Der uC und der ADC sind nicht auf der selben Platine, sondern mit einem
Kabel verbunden. Also SPI geht über das Kabel. Habe erst gedacht, dass
es halt an der Leitung liegt, aber auch mit 20cm und einem Takt von ca.
900kHz geht es irgendwann nicht mehr. Das muss doch wohl machbar sein,
oder?
Das ist machbar, habe den AD7794 in diversen Schaltungen ohne Probleme
im Einsatz.
Ein "netter" Effekt trat mal beim Testen auf: Hatte denselben Wert
sowohl in Mode-High, als auch Mode-Low geschrieben mit dem Effekt, dass
der ADC mit einem nicht vorhandenen externen Takt laufen sollte...
Und wie steuerst du ihn an? Fragst du das Status-Flag im Register ab und
holst dann das Ergebnis, oder nimmst du den DOUT-Pin und schaust, ob
dieser sich ändert?
Die GND der beiden Schaltungen sind verbunden ? Dieser chip ja ja genau
deswegen Differentielle eingaenge, dass man die analogen signale fuehren
kann. Platzier den mal neben den Prozessor. Sonst wuerde ich auf EMV
tippen. Genau so schaut's aus.
Also letzteres scheint wohl so zu sein.
Massen sind verbunden, klar.
Ich habe jetzt mal probehalber in die Datenleitungen einen 100R
eingeschleift, brachte aber nichts. Weiterhin habe ich einen 74HC565 als
Buffer sowohl an die ADC-Karte, wie auch an die uC-Karte gepackt. Aber
dennoch Fehler nach einer gewissen Zeit.
Womit es jetzt erstmal zu 99,99% stabil läuft, ist die Verringerung des
SPI-Taktes auf 100kHz. Wie lange wird sich jetzt zeigen. Die Sample-Rate
ist zum Glück nicht relevant, da ich lediglich Abweichungen der
DC-Spannung unter Temperatureinfluss messen muss und da eh nichts
schnelles passiert.
Wie sieht es generell aus mit Serienwiderständen in den Leitungen? Gut
oder eher noch hinderlicher? Wenn gut, dann wie groß? 100R zuviel?
Gruß, die Wurscht
GB schrieb:> Dann hast Du Störungen auf dem SPI-Clock, das schmeisst ihn> durcheinander (hatten wir mit einem AD7719, auch SPI über Kabel).
Und wie habt ihr das gelöst?
HansWurscht schrieb:> Und wie steuerst du ihn an? Fragst du das Status-Flag im Register ab und> holst dann das Ergebnis, oder nimmst du den DOUT-Pin und schaust, ob> dieser sich ändert?
Nur Abfrage des Status-Flags, keine Abfrage des DOUT-Pins. Bei einem
Projekt bspw. insgesamt 6x AD7794 auf zwei Platinen, längste Verbindung
ca. 15 cm FFC, SPI-Takt 4 MHz, SPI-Mode 0.
Edit: 27R jeweils auf Seiten der ADCs und des Controllers
Vielleicht noch interessant: Das Setzen/Lesen von Registern läuft hier
nach dem Muster:
ADC CS -> low
Ein Register (Byte, Wort oder 24-Bit) lesen/schreiben
ADC CS -> high
10 us warten
und dasselbe für das/die nächste/n Register
OK, danke!
Bei mir läuft es so ab: Ich setze aus der main per Funktion ein Flag,
welches durch die State-Machine des ADCs abgearbeitet wird. Die
State-Machine wird jedesmal in der main aufgerufen. Hier wird dann
geguckt, ob ein Flag z.b. zum Schreiben eines Registers gesetzt ist und
falls ja, dieses abgearbeitet. Während dieser Zeit wird ein anderes Flag
gesetzt, durch welches ich aus der main sehen kann, ob ein ADC-Ergebnis
abzuholen ist oder ob der ADC gerade mit anderen Dingen beschäftigt ist.
Alle Operationen haben Vorrang vor dem samplen eines Wertes. Erst wenn
alle Flags abgearbeitet sind, nimmt der ADC automatisch wieder Messungen
und meldet eine fertige Wandlung durch ein....ratet...Flag ;-)
Nun gut, also 100R sind übertrieben meinste.
Hallo OP.
Schau' dir mal die FAQs zu dem Wandler an, insbesondere den Teil zur
Robustheit des Interfaces.
http://www.analog.com/static/imported-files/faqs/AD779x_FAQ_Instru_Conv.pdf>Das hilft ist, wenn ich zwischendurch einen Software-Reset an den ADC>sende (4 Bytes mit 0xFF), dann geht es wieder, aber dann muss ich auch>immer alle Register wieder neu beschreiben.>Dies ist natürlich möglich, aber im Prinzip darf das ja nicht sein
Ein Reset ist keine Schande.
Ich hantiere mit ähnlichen Wandlern herum, allerdings in einer sehr
EMV-versauten Umgebung. Natürlich kann/muss man seine Hardware durch
geeignete Maßnahmen gegenüber externen Störungen robuster machen.
Aber ein periodischer Reset, der den Wandler alle 5000ms neu
initialisiert, war bei meinen Anwendungen noch nie verkehrt.
Hey!
Danke für den Link! Das werde ich mir mal gründlich durchlesen.
Ein Reset ist keine Schande, klar - war halt nur der Meinung, dass das
ja wohl nicht Sinn der Sache sein kann...also dass das zwingend
notwendig ist.
Ich sehe es ja ein, dass der Controller evtl. Mist liefert bei einer
Übertragung, bei der der CLK mies ist. Dachte darüber hinaus aber auch,
dass der Wandler ja eigentlich nach !CS bei der nächsten Übertragung
wieder klarkommen sollte und nicht ab da nurnoch konstant Müll rausgibt.
Aber wer weiß, welches Register ich durch die fehlerhafte Übertragung
beim eigentlichen Auslesen ggf. nun neu BESCHRIEBEN habe.
Hallo,
ich versuch einen AD7794 anzusteuern, jedoch ohne Erfolg.
Kann mir jemand von euch ein Beispiel bzw. eine Bibliothek zu dem Chip
geben?
schon mal viele Dank
Arc Net schrieb:> HansWurscht schrieb:>> Und wie steuerst du ihn an? Fragst du das Status-Flag im Register ab und>> holst dann das Ergebnis, oder nimmst du den DOUT-Pin und schaust, ob>> dieser sich ändert?>> Nur Abfrage des Status-Flags, keine Abfrage des DOUT-Pins. Bei einem> Projekt bspw. insgesamt 6x AD7794 auf zwei Platinen, längste Verbindung> ca. 15 cm FFC, SPI-Takt 4 MHz, SPI-Mode 0.> Edit: 27R jeweils auf Seiten der ADCs und des Controllers> Vielleicht noch interessant: Das Setzen/Lesen von Registern läuft hier> nach dem Muster:> ADC CS -> low> Ein Register (Byte, Wort oder 24-Bit) lesen/schreiben> ADC CS -> high> 10 us warten> und dasselbe für das/die nächste/n Register
Bin ich bescheuert, oder sieht das im AD7794-Datenblatt auf Seite 9 so
aus, als ob der ADC eigentlich gerne SPI-Mode 3 hätte?
Ich bin auch gerade dabei, das Ding an einem Atmega32M1 in Betrieb zu
nehmen. Habe einen Logic-Analyzer, die Software zur Ansteuerung der SPI
auf dem Atmega und die dafür verwendete state-machine kann ich also
schonmal ausschließen. Ich bekomme bei Abfrage des Status-registers für
Bit SR3 häufig eine 0 zurück - was laut Datenblatt des AD7794 (Seite 18)
nicht sein kann.
Momentan betreibe ich den AD7794 im SPI-Mode 3 (SPCR |=
(1<<CPOL)|(1<<CPHA)), Mode 0 brachte leider auch keine Abhilfe. (Das
Verhalten wird anders, aber ich vbekomme immer noch 0x00 als Inhalt des
Status-Registers)
Ich kann leider nicht direkt die MISO-Leitung als Interruptquelle
nutzen, da noch andere Komponenten die SPI-Schnittstelle verwenden
sollen (momentan aber noch nichts dergleichen realisiert).
Dementsprechend polle ich das Status-Register, und genau da Fällt auf,
das irgendwas nicht stimmt.
Vielleicht ist auch meine Initialisierung zu kompliziert. Ich schicke
momentan folgende Befehle (pro zeile ein Datenframe, nach jeder Zeile
wird _CS wieder auf high gesetzt):
0xFF FF FF FF //spi-reset
2ms warten
0x10 10 00 //write config register, unipolar mode, channel 1
0x08 80 03 //write mode register, internal zero scale calibration,
123Hz Update rate
2ms warten
0x40 00 //read status register
der letzte dieser Schritte wird solange wiederholt, bis das _RDY-Bit auf
0 steht. Das passiert auch irgendwann (nach einigen ms, während denen
der AD7794 nur mit 0xFF FF antwortet). Zu dem Zeitpunkt, an dem das Bit
auf 0 springt, kommt aber leider 0x80 00 zurück. Also 0x80 während dem
Schreibzugriff auf das Communications-Register, und dann 0x00 als
Antwort. Das passt jedenfalls nicht mit dem Angaben aus dem Datenblatt
zusammen.
Im weiteren Verlauf würde ich wieder auf das mode-register schreiben, um
die internal full scale calibration zu starten, dann warten, bis diese
fertig ist, das Ganze für alle genutzen Kanäle wiederholen, und dann
Anfangen zu messen. Habe ich da einen Denkfehler? Kann bitte jemand, der
das Ding bereits am Laufen hat, mal seine Initialisierung posten?
Felix schrieb:> Arc Net schrieb:>> Nur Abfrage des Status-Flags, keine Abfrage des DOUT-Pins. Bei einem>> Projekt bspw. insgesamt 6x AD7794 auf zwei Platinen, längste Verbindung>> ca. 15 cm FFC, SPI-Takt 4 MHz, SPI-Mode 0.>> Edit: 27R jeweils auf Seiten der ADCs und des Controllers>> Vielleicht noch interessant: Das Setzen/Lesen von Registern läuft hier>> nach dem Muster:>> ADC CS -> low>> Ein Register (Byte, Wort oder 24-Bit) lesen/schreiben>> ADC CS -> high>> 10 us warten>> und dasselbe für das/die nächste/n Register>> Bin ich bescheuert, oder sieht das im AD7794-Datenblatt auf Seite 9 so> aus, als ob der ADC eigentlich gerne SPI-Mode 3 hätte?
Ja, zumindest sagt mir auch mein Quelltext das es SPI-Mode 3 ist...
> Momentan betreibe ich den AD7794 im SPI-Mode 3 (SPCR |=> (1<<CPOL)|(1<<CPHA)), Mode 0 brachte leider auch keine Abhilfe. (Das> Verhalten wird anders, aber ich vbekomme immer noch 0x00 als Inhalt des> Status-Registers)
...
> Vielleicht ist auch meine Initialisierung zu kompliziert. Ich schicke> momentan folgende Befehle (pro zeile ein Datenframe, nach jeder Zeile> wird _CS wieder auf high gesetzt):>> 0xFF FF FF FF //spi-reset> 2ms warten> 0x10 10 00 //write config register, unipolar mode, channel 1> 0x08 80 03 //write mode register, internal zero scale calibration,> 123Hz Update rate> 2ms warten> 0x40 00 //read status register
Externe Referenz oder interne Referenz? Bzw. im Config Reg REF_DET
einschalten und beim Auslesen des Statusregisters NOXREF überprüfen.
> Im weiteren Verlauf würde ich wieder auf das mode-register schreiben, um> die internal full scale calibration zu starten, dann warten, bis diese> fertig ist, das Ganze für alle genutzen Kanäle wiederholen, und dann> Anfangen zu messen. Habe ich da einen Denkfehler?
Sieht so weit in Ordnung aus.
> Kann bitte jemand, der> das Ding bereits am Laufen hat, mal seine Initialisierung posten?
Kann nach dem Aufstehen mal die Quelltexte passend zusammenstellen...
Das wäre mir glaube ich eine große Hilfe! Vielen Dank schon mal für die
bisherige Antwort!
Im Moment verwende ich externe Referenz an Refin1 (5V mittels Tiefpass
geglättet, soll dann auch das Messobjekt (Kraftmessdose) versorgen).
Ref_detect habe ich nicht aktiviert, NOXREF auch nicht überprüft. Sollte
ich das? Ändert das irgendwas am Verhalten?
Ich versteh auch nicht so ganz, ob es Sinn macht, nach dem Start einer
Kalibrierung direkt ununterbrochen das Statusregister zu pollen, bzw ob
ich das Ergebnis der Kalibrierung im Statusregister sehe (_RDY low?
stimmen dann auch die drei untersten Bits für den aktuell gewählten
Kanal? da kommt nämlich alles mögliche raus bei mir..)
Ich werde nachher mal die Strippen kontrollieren, momentan sind es ca
10cm Kabel für die SPI, der uC hat 220 Ohm Schutzwiderstände in allen
Datenleitungen, Signale sahen am Oszi aber 1A aus. Vielleicht hat sich
irgendwo ein Wackler eingeschlichen. Was wiederum dagegen sprechen
würde, ist die Tatsache, dass das Verhalten im Logikanalyzer absolut
reproduzierbar zu beobachten ist.. SPI-Frequenz hab ich auch schon rauf-
und runtergeschraubt, anfangs 1MHz, jetzt 125kHz, macht keinen
Unterschied...
Hier mal die angepassten und zusammenkopierten Routinen für den AD7794
Edit: wo noch += 2 steht müsste ++ stehen (ursprünglich waren die
Routinen für zwei Bänke von AD7794, die an unterschiedlichen SPI-Modulen
hingen und deren /CS an div. Ports hingen und z.T. gleichzeitig
gestartet wurden)
vielen Dank für die Hilfe!
Ich habe die billigen China-Strippen mal durch angelötete Kabel ersetzt,
und das Ganze läuft schon besser. Habe außerdem in meinem Code die
Pausen zwischen den _CS verlängert auf über 10us. Leider steigt die
Kommunikation immer wieder aus, auch Baudratenunabhängig. Kann es sein,
dass 220 Ohm in der Datenleitung schon zu viel ist?
Momentan überprüfe ich das Statusregister auf die festen Bits
0bXXX01XXX. Wenn andere Daten vom AD7794 kommen, initialisiere ich ihn
neu. Genauso auch, wenn ich bereits mehrfach einen bestimmten Kanal
angefordert habe, dieser aber nicht im Statusregister als aktiver Kanal
erscheint.
Ausserdem habe ich einen Timeout eingebaut, für den Fall, dass der
AD7794 die Kommunikation eingestellt hat und mal wieder nur noch 0xFF
von sich gibt.
Mit diesen drei Maßnahmen läuft die ganze Sache recht robust.
Jetzt kanns ans Feintuning gehen..
Eventuell wird es notwendig sein, den AD7794 ein Stück (40cm) entfernt
vom Atmega zu betreiben. Wie sollte ich meine SPI-Schnittstelle denn
optimalerweise beschalten (Serien- und Abschlusswiderstände), um
möglichst Robust gegen EMV zu sein? Die Kabel wären selbstverständlich
geschirmt.