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.
>Die GND der beiden Schaltungen sind verbunden ?
Wie sollte sonst die SPI-Übertragung funktionieren`?
Dann hast Du Störungen auf dem SPI-Clock, das schmeisst ihn durcheinander (hatten wir mit einem AD7719, auch SPI über Kabel).
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
:
Bearbeitet durch User
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.
Sehr interessantes Dokument! Das beantwortet es ja eigentlich nur zu gut! Danke nochmal
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
Diese ADC bedingen genauestes Lesen des Datenblattes. Teilweise ist jedes Wort wichtig. Zum Debuggen erst mal das Timing auf jede Flanke nachpruefen.
:
Bearbeitet durch User
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)
:
Bearbeitet durch User
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.