Guten Abend,
ich versuche jetzt schon seit heute früh mit dem AD Wandler (ADS1255
)auf meiner Platine zu kommunizieren. Ich dachte ich beginne erstmal
damit das Status Register des Chips erfolgreich auszulesen. Leider
bekomme ich das bereits nicht hin. Ich habe diverse SPI-Modi ausprobiert
aber ohne Erfolg.
Habe jetzt bereits an mehreren Stellen im Internet gelesen, dass die
t6-Zeitspanne im SPI-Timing auf jedenfall eingehalten werden muss,
deshalb habe ich erstmal 50 µs beim Übertragen eingefügt. Das sollte ja
genügen. Das ist das erste mal, dass ich einen externen AD ansteuern
möchte deshalb verzeiht mir bitte falls ich sehr grobe Fehler begehe :)
Ich habe meinen Code im Anhang weitesgehend kommentiert. Viel ist es ja
noch nicht, aber eventuell endeckt ja jemand bereits einen Fehler. Hier
auch das Datenblatt des Chips.
Die Beschaltung ist grundlegend wie im Datenblatt auf Seite 28. Auf
Seite 6 ist das besagte SPI-Timing Diagramm, das ich probiert habe
einzuhalten. Als Antwort, die ich per UART ausgebe, bekomme ich immer
nur "0xFFFFFFFF". Das kann ja nicht stimmen. Denn auch wenn ich
beispielsweise das DRATE-Register für die Abtastrate anstatt des
Statusregisters auslese bekomme ich denselben Wert.
Die Beschreibung des Registersatzes beginnt auf Seite 30 und die des
Befehlssatzes auf Seite 34.
Vielleicht mag ja jemand mal über den Code schauen und entdeckt einen
Fehler. Eventuell kennt ja auch jemand den Chip und kann mir ein paar
Tips geben. Ich bin für alles offen.
Schönen Abend allen.
Noch als weiteren Hinweis. Die Kommunikation per SPI wird von einem
Atmega168 gesteuert. Der rennt mit einem externen 7,3728 MHz Quarz. Mit
Prescaler 16 läuft die SPI also mit ca. 460 kHz.
Hallo Dirk.
Vielen Dank für deine Antwort. Ich hatte deinen Code, den du netterweise
zur Verfügung stellst, bereits in einem anderen Thread entdeckt.
Beitrag "ADS1255 / ADS1256 Beispielcode"
Ich habe noch nie mit PICs gearbeitet aber ich hatte trotzdem probiert
einige Informationen herauszuziehen und in meinen Code einzubauen.
Leider ohne Erfolg. Ich bekomme wie ich bereits geschrieben habe immer
nur "0xFFFFFFFF" als Rückgabewert.
Grundsätzlich passiert in meinem Code ja auch noch nicht so viel. Ich
initialisiere den SPI als Master und setze die Pins von SCK, MOSI und
!CS auf Ausgang. Momentan sind CPOL UND CPHA auf "0". Ich habe aber auch
anderen Modi bereits ausprobiert.
Der UART wird initialsiert und der funktioniert auch einwandfrei.
Der Rest sind denk ich ganz normale SPI-Funktionen wie man sie sowohl im
Datenblatt als auch überall im Netz findet. Mit der Ausnahme, dass ich
in der Transceive-Funktion nach dem Warten auf eine erfolgreiche
Übertragung 50 µs warte um die Distanz von t6 einzuhalten.
Nachdem !CS auf Low gezogen wurde wird 0x10 kombiniert mit dem Wert 0x00
übertragen. Das entspricht dem Befehl für Registerauslesen. Und in dem
Fall das Statusregister. Der nächste Wert, der übertragen wird sagt dem
Chip, dass nur ein Register gelesen werden soll. Dann ein Dummybyte
wodurch der Chip eigentlich den Registerwert zurückgeben sollte. Leider
tut er das noch nicht.... Abschließend wird !CS wieder auf High gezogen.
Das wars eigentlich. Klingt simple funktioniert nur noch nicht.
Tobi schrieb:> Ich dachte ich beginne erstmal> damit das Status Register des Chips erfolgreich auszulesen. Leider> bekomme ich das bereits nicht hin. Ich habe diverse SPI-Modi ausprobiert> aber ohne Erfolg.
Bei dem großen Bruder (ADS1298) hatte ich genau das Problem wenn die
analoge Spannung nicht OK war. Miss die mal mit 'nem Multimeter nach.
Ansonsten: Digitales Oszi an die SPI Pins und Kurven anschauen.
Hey,
beim ADS1299 gehe ich im Init() wie folgt vor:
- Reset vom ADS1299
- Disable Read Continous (sonst nimmt er keine Befehle an)
- Stop Befehl
- Config Reg. schreiben
- Config Reg. lesen und ID prüfen
Ich würde mir sonst anschauen ob die Kommunikation ansich überhaupt
stimmt.
Tobi schrieb:> Momentan sind CPOL UND CPHA auf "0"
Beim ADS1255 hab ich jetzt auf anhieb nichts gefunden, beim ADS1299 ist
es so:
NOTE: SPI settings are CPOL = 0 and CPHA = 1.
Ich habe auch eine ganze Weile gebraucht um den ADS1256 anzusteuern, am
Raspberry mit Python. Hier ein Teil des Programms. Die Reihenfolgen und
Verzögerungszeiten sind vermutlich wichtig. Wieweit der 1255 kompatibel
ist weiß ich nicht. Man findet jedenfalls noch weitere Leidensgenossen
im Web.
"pi.spi_open(0, 200000, 0x00000061)"
http://abyz.me.uk/rpi/pigpio/python.html#spi_open
Mode POL PHA
0 0 0
1 0 1
2 1 0
3 1 1
die beiden letzten Bits von 0x..61 bestimmen den SPI-Modus, nämlich
"01", also so wie es mein Vorredner schon schrieb.
Die drei ADS1255-1257 unterscheiden sich anscheinend nur in der Anzahl
der Analogeingänge.
Jim M. schrieb:> Bei dem großen Bruder (ADS1298) hatte ich genau das Problem wenn die> analoge Spannung nicht OK war. Miss die mal mit 'nem Multimeter nach.
Spannungen an den Pins sind alle okay. AVDD = 5,01 V stabil und DVDD =
3,30 V stabil.
Adam P. schrieb:> beim ADS1299 gehe ich im Init() wie folgt vor:>> - Reset vom ADS1299> - Disable Read Continous (sonst nimmt er keine Befehle an)> - Stop Befehl> - Config Reg. schreiben> - Config Reg. lesen und ID prüfen
Bei TI im Forum wurde mir auch geraten den SDATAC befehl einzufügen. Was
ich jetzt auch getan habe. Reset kann ich vorher noch ausprobieren. Stop
Befehl gibts bei dem Chip nicht. Ansonsten will ich erstmal das Lesen
hinbekommen um die grundsätzliche Verbindung herzustellen.
Christoph K. schrieb:> Ich habe auch eine ganze Weile gebraucht um den ADS1256 anzusteuern, am> Raspberry mit Python. Hier ein Teil des Programms. Die Reihenfolgen und> Verzögerungszeiten sind vermutlich wichtig. Wieweit der 1255 kompatibel> ist weiß ich nicht. Man findet jedenfalls noch weitere Leidensgenossen> im Web.
Danke für den Code. Ich kenn leider weder den Umgang mit Raspberry PI
noch Python. Aber ich denke den groben Ablauf konnte ich trotzdem
erkennen.
- Soft-Reset
- Status-Register schreiben
- Config-Register schreiben
- Data-Rate Register schreiben
- ADC kalibrieren
- ...
Ich habe die SPI Pins mal durchgemessen. So weit ich das beurteilen kann
sehen die Signale okay aus. Siehe Anhang. Channel 1 (gelb) ist jeweils
das !CS Signal. Wie man sieht tut sich an der DOUT leitung gar nix außer
ein bisschen "Geraschel". Der ADC antwortet also gar nicht...
- Bild 1: Channel 2 zeigt DIN am ADC
- Bild 2: Channel 2 zeigt SCLK am ADC
- Bild 3: Channel 2 zeigt DOUT am ADC
Die Bilder zeigen jeweils eine Befehl Sequenz. Zwischen den Befehlen
wird !CS jeweils wieder auf High gezogen. Nachdem !CS auf LOW gezogen
wurden und bevor es wieder auf High gezogen wird sind jeweils 20 µs
Verzögerung.
- 1. Befehl : Stop Read Data Continuously (0xF)
- 2. Befehl : Wakeup (0x00)
- 3. Befehl : Read Register (0x10)
Das einzige, das mir auffällt ist, dass SCLK nicht auf Masse liegt,
sondern einen Offset hat. Weiß nicht ob dsa normal ist bzw. woran das
liegt und ob das das Problem sein könnte?! Laut Datenblatt erkennt der
ADC maximal 0.2*DVDD als "LOW" an den digitalen Inputs an. Ich denke
aber da liegt das Signal noch knapp drunter. Irgendwer eine Idee wie ich
den ADC dazu bringen kann mit mir zu sprechen? :)
Code ist auch im Anhang. Danke für eure Hilfe.
Das ist auch praktisch mein erstes Python-Programm und mein erstes auf
dem Raspberry.
Vor dem ADS1256 kam schon der DDS, der im Programm auch erwähnt ist. Der
hat auch erst mal keine Reaktion gezeigt, ich stand praktisch an allen
Fronten am Anfang - waren es Hardwarefehler, Softwarefehler oder hatte
ich das Datenblatt nicht verstanden. Durch Vergleich mit Hard- und
Software anderer im Web konnte ich schließlich eine erste Reaktion an
einem Pin des DDS feststellen, damit war der Durchbruch geschafft. Mit
dem ADS1256 ging dasselbe nochmal los.
Wenigstens kann ich jetzt etwas Python, kommt mir vor wie ein würdiger
Nachfolger von BASIC, speziell für schnelle Erfolge für Einsteiger wie
einst in den Achtzigern. Das ganze objektorientierte Geschwurbel muss
man nur einfach ignorieren, man kann damit genausogut funktionierende
Software alten Stils schreiben.
Zum ADS noch: den ersten Messwert lasse ich unter den Tisch fallen, da
erst die erste Abfrage eine AD-Wandlung auslöst - wenn ich noch recht
weiß, ist schon über ein Jahr her.
Ich bin mir mittlerweile eigentlich relativ sicher, dass ich so
zumindest irgendeine Reaktion von dem Chip bekommen sollte...Leider
kommt immer noch "0x00" zurück. An der DOUT-Leitung tut sich also immer
noch nichts. Zum verzweifeln.
Was ist den mit dem _DRDY Pin ?
Messe den mal mit dem Oszi.
Er sollte nach dem Anlegen der Spannung zyklisch auf Low gehen, immer
dann wenn eine Wandlung fertig ist.
Wenn er das nich macht, ist der Chip wohl im Eimer...
LG Dirk
Dirk F schrieb:> Was ist den mit dem _DRDY Pin ?> Messe den mal mit dem Oszi.> Er sollte nach dem Anlegen der Spannung zyklisch auf Low gehen, immer> dann wenn eine Wandlung fertig ist.> Wenn er das nich macht, ist der Chip wohl im Eimer...
Du meinst zyklisch auf High oder? (Datenblatt S. 27). Das macht er auch.
Siehe Anhang. Frequenz passt auch. Habe einen 7.3728 MHz Quarz.
(7.3728 / 7.68)* 30 kHz = 28.8 kHz
Tobi schrieb:> Bild 3: Channel 2 zeigt DOUT am ADC> (...)> Irgendwer eine Idee wie ich> den ADC dazu bringen kann mit mir zu sprechen? :)
Ja. Wie wäre es, wenn du aufhörst ihm das Maul zuzuhalten?
Wenn du dir Bild3 nochmal genau anschaust, siehst du dass das Signal
DOUT vom ADC um mehrere hundert Millivolt im Takt hoch und
runter-springt. Das deutet darauf hin, dass das DOUT Signal vom ADC
gegen ein anderes Ausgangs-Signal welches bei low hängt getrieben wird.
- DOUT vom ADC korrekt mit MISO am uC verbunden?
- Niederohmige Verbindung von DOUT nach GND? / zu einem anderen Signal?
- Ist das MISO signal am uC wirklich auf Input eingestellt?
- Treibt jemand andes auch noch MISO? (z.b. der Debugger)
P.S.: Die delay_us(10) gehören übrigens genau überall NICHT hin wo du
die geschrieben hast. Die Zeit t6 (50us) ist genau nur vor dem Lesen
(also in der Zeile vor "//send Dummy-Byte and save return value" in
deinem Code) notwendig. Und da fehlt sie.
Ah, und noch ein Grund warum das DOUT des ADC garnicht am MISO deines uC
anliegen wird:
> ADS1255_transceive(0b10|0x00); (..)
> Bild 1: Channel 2 zeigt DIN am ADC
Das Bild 1 zeigt schön beim ersten gesendeten Byte 0x10,
dass DIN am ADC low-low-low-high low-low-low-low geht.
Das passt zum Byte 0x10.
(Man beachte 0 = low, 1 = high Level.)
> - Bild 3: Channel 2 zeigt DOUT am ADC (...)
> Als Antwort, bekomme ich immer nur "0xFFFFFFFF"
Bild 3 zeigt DOUT am ADC ist immer low.
Dein uC liest aber 0xFF, also immer high.
Das passt doch nicht zusammen!