Ich versuche seit ein paar Tagen ein Problem mit der SPI Kommunikation zwischen einem ESP8266 und einem ADS1217 zu loesen und komme da Leider nicht recht weiter. Also dachte ich ihr loest mal eben mein Problem. :-) Der ADS1217 ist mit POL=1 verdrahtet. Damit sollte er im SPI-MODE3 laufen, das erste Bild zeigt einen ausschnitt aus dem Datenblatt wie sich TI das vorgestellt hat. Das Bild Oszi1.gif zeigt die Uebertragung sowohl des Logiganalyser wie auch nochmal das SCK-Signal auf dem analogen Eingang. Das sieht nach meiner Meinung so aus wie es laut Datenblatt aussehen sollte. Widerspruch? Der ADS1217 ist ein AD-DA Wandler der zusaetzlich noch einen 8Bit Datenport enthaelt. Um die Sache einfach zu halten beschreibe und lese ich erstmal diesen Datenport. Ich habe an den oberen drei Bits dieses Ports eine RGB-Led angeschlossen, D2 liegt auf high und alles andere auf low. Das Kommando 0x56 0x00 0x80 beschreibt als Beispiel den Port mit 0x80 und schaltet so z.B meine gruene LED ein. Ich gebe so einmal pro Sekunde immer abwechselnd 0x20 0x40 und 0x80 aus. Das sollte also dazu fuehren das die LED munter blinkt. Das tut sie aber in der Regel nicht. Sie blinkt manchmal garnicht, manchmal nur in einer Farbe und manchmal auch genau wie sie soll. Ignoriere ich einfach mal die Vorgaben laut Datenblatt und probiere alle Modi durch so kann ich in Mode0, was auf dem Oszi dann total falsch aussieht die LED korrekt und zuverlaessig ans blinken bringen. Lese ich dann aber testweise den Port ein so liefert der erste Versuch immer Unsinn und danach bekomme ich dann den richtigen Wert. Lese ich zwischendurch etwas anderes werden die reinkommenden Daten immer ander verwuerfelt. So kann es z.B sein das ich einen ADC-Wert lesen will, aber den den Inhalt des Portregisters bekomme wenn ich das zuvor versucht habe. Mit anderen Worten es sieht so aus als wenn keiner der vier moeglichen Modis funktioniert. Ich sollte vielleicht noch erwaehnen das ich am selben Anschluss, aber nicht gleichzeitig, vollkommen problemlos diverse Grafik-LCDs ans laufen bringen konnte. Schalte ich POL=0 bekomme ich genau dasselbe Ergebnis aber dann in anderen SPI_Modes. In keiner der acht denkbaren Kombinationen kann ich immer zuverlaessig lesen UND schreiben. Ich hab daher den Eindruck als wenn sich der ADS1217 nicht ganz an sein Datenblatt haelt. Hat schon mal jemand mit diesem IC (oder ADS1216, ADS1241, ADS1241) aehnliche Erfahrungen gemacht? Olaf
Noch was..wer das Datenblatt dieser AD-Wandler liesst wird erkennen das man beim lesen eines Wertes vor der letzten lesenden SPI-Uebertragung eine kleine Pause einlegen muss. Daran halte ich mich! SPI.transfer(SendData); //Schreibkommando für das gewünschte Register SPI.transfer(0x00); //0x00 bedeutet das wir ein Register lesen wollen //Wartezeit laut Datenblatt seite 20 //fuer ReadReg ist das 50xOscilatorperioden = 50x 1/4Mhz = 12.5us delayMicroseconds(30); ReadData = SPI.transfer(0x00); Ich hab zu Testzwecken auch schon sehr viel laenger gewartet ohne das dies einen Unterschied machte.
Hallo, mit den SPI-Modi 2 und 3 gab es mehrere Probleme, speziell aus der Arduino-IDE. Auch im SDK gab es wohl Unklarheuten bei der Beschreibung der Registerbits. Ich weiß nicht, ob das behoben wurde, ich habe hier nichts zur Hand, was nicht mit Mode 0 oder 1 läuft. Gruß aus Berlin Michael
> mit den SPI-Modi 2 und 3 gab es mehrere Probleme, speziell aus der > Arduino-IDE. Mode2 und Mode3 sind vertauscht. Ist aber nur eine Zeile im source das richtig zu biegen. Ist auch irrelevant weil ich ja das als Referenz ansehe was mein Oszi anzeigt und das scheint mir richtig zu sein. Ich hab mal mein Testprogramm geaendert: 1. Digital-PORT auf 0 setzen. 2. Digital-PORT auf 0x40 setzen 3. Digital-PORT auf 0 setzen 4. 200ms Pause dann wieder von vorne. Der gelbe Kanal zeigt den Portausgang D6 an. Man wuerde also erwarten das der Port nach (2) auf high geht und nach (3) wieder auf low. Die drei Bilder zeigen nun drei beliebige Triggerevents. Jedesmal anders und nie wie man es erwartet. An dieser Stelle wuerde ich jetzt darauf wetten das etwas mit dem SCK nicht stimmt. Das sieht aber (Analogkanal, Tastkopf mit Massefeder) absolut perfekt aus. Keine Ueberschwinger nichts. Entweder ich bin zu doof das Datenblatt zu lesen oder das IC hat eine Macke. Ich hab das IC allerdings auch schonmal gewechselt.... Olaf
Ich habs jetzt zuverlässig und gut laufen. :-) Mein Problem war das ich zwei Bugs hatte. Der eine war eigene Bloedheit, ich hatte einen der Pinne (!DSYNC) fuer einen Ausgang gehalten und nirgendwo angeschlossen. ARGH! Nachdem ich den angeschlossen habe lief es erstmal, bis auf eine sehr faszinierende Kleinigkeit. Bei jeder Uebertragung kamen immer alle Bits korrekt im ADS1217 an, aber beim auslesen war Bit0 des jeweils letzten uebertragenen Bytes im ESP8266 immer 0. Egal was ich gelesen habe! Dabei sah auf meinem Oszi alles korrekt aus und wurde auch vom Oszi korrekt dekodiert. Die Loesung sah dann so aus: SPI.beginTransaction(SPISettings(SPI_SPEED, MSBFIRST, SPI_MODUS)); digitalWrite(CS, LOW); SendData = RREG | (RegisterNumber & 0x0f); SPI.transfer(SendData); //Schreibkommando für das gewünschte Register SPI.transfer(0x00); //0x00 bedeutet das wir ein Register lesen wollen delayMicroseconds(20); ReadData = SPI.transfer(0x00); delayMicroseconds(5); //DAS IST WICHTIG digitalWrite(CS, HIGH); SPI.endTransaction(); Aus Gruenden die mir ein echtes Raetzel sind braucht der ESP8266 zumindest mit dem ADS1217 eine kleine Wartezeit bevor er CS wieder hochsetzt. Dafuer kann ich mir keinen logischen Grund vorstellen weil das einlesen mit der Rueckkehr aus der transfer Methode bereits abgeschlossen sein sollte. Falls also jemand aehnliche Probleme hat empfehle ich ihn das mal auszuprobieren. Olaf
Olaf schrieb: > Aus Gruenden die mir ein echtes Raetzel sind braucht der ESP8266 > zumindest mit dem ADS1217 eine kleine Wartezeit bevor er CS wieder > hochsetzt. Dafuer kann ich mir keinen logischen Grund vorstellen weil > das einlesen mit der Rueckkehr aus der transfer Methode bereits > abgeschlossen sein sollte. > > Falls also jemand aehnliche Probleme hat empfehle ich ihn das mal > auszuprobieren. die Probleme hatte ich auch. Die Transfer Methode wird verlassen auch wenn der Transfer noch nicht abgeschlossen ist. ich habe das mit einer Funktion gelöst: void HSPI::wait(uint16_t timeout) const { while (timeout > 0) { if (spi_busy(E_HSPI)) { os_delay_us(1); timeout--; } else { timeout = 0; } } } spi_busy ist definiert: //Expansion Macros #define spi_busy(spi_no) READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR das ist jetzt ein Ausschnitt aus meiner HSPI HAL. Allerdings nicht mit Arduino. Grüße, Werner
> die Probleme hatte ich auch. Die Transfer Methode wird verlassen auch > wenn der Transfer noch nicht abgeschlossen ist. Das ist aber dann ein schwerer Bug. Wo befindet sich denn der Rueckgabewert wenn die Methode bereits verlassen ist? Ich hab schon ueberlegt ob ich zeitweise in einem Universum bin wo Ursache und Wirkung vertauscht sind. :) Olaf
das kann ich Dir jetzt so direkt nicht beantworten. Wir hatten immer das Problem dass wenn wir nach dem Transfer CS auf High gesetzt haben der Slave Probleme machte. Wir stellten dann fest, dass wenn wir nach dem Transfer CS auf High setzen , die Übertragung aber noch nicht abgeschlossen war. Nach langem Suchen im Internet fanden wir dann die Lösung. Ist aber jetzt schon 2 Jahre her.
Ich hab gerade noch etwas experementiert. Das Problem haengt nicht an einer Wartezeit bevor man CS wieder setzt, es ist von der SCLK-Frequenz abhaengig. Bei 100khz liesst der ESP8266 das letzte bit immer als 0 ein, bei 110khz flackert es lustig rum, bei 130khz ist es meistens, aber nicht immer korrekt und ab 140khz liesst er immer korrekt ein. Das finde ich sehr bemerkenswert weil die Uebertragung ja von der Hardware erfolgt und man sieht auf den Oszibildern deutlich das CS erst lange nach der Uebertragung hoch geht und der AD1217 das Bit noch sehr lange stehen laesst. Im Extremfalle, bei einem Takt von 1Mhz laesst er das Bit sogar noch kurz stehen waehrend CS schon wieder high ist. Das ist IMHO von Analog auch nicht ganz sauber implementiert. Auf jedenfall hat das Bit bei der fallenden Flanke, ich nutze SPIMODE=0 (POL =GND) immer den korrekten Pegel. Deshalb dekodiert es der Oszi auch richtig. Auch wenn ich auf SPIMODE=3 und POL=high umstelle aendert sich am Fehlverhalten nichts. Andererseits sind die anderen Bits im Register immer korrekt. Sowohl Pegel wie auch Position. Ich gehe jetzt davon aus das die SPI-Hardware im ESP8266 einen Bug hat. Der Code der Transfer funktion sieht im uebrigen so aus: uint8_t SPIClass::transfer(uint8_t data) { while(SPI1CMD & SPIBUSY) {} // reset to 8Bit mode setDataBits(8); SPI1W0 = data; SPI1CMD |= SPIBUSY; while(SPI1CMD & SPIBUSY) {} return (uint8_t) (SPI1W0 & 0xff); } Da wird also auch explizit gewartet bevor das Register gelesen wird. Allerdings ist es etwas befremdlich das man das Busybit von Hand setzen muss. Jetzt waer eigentlich der Moment wo man ein gutes Datenblatt braeuchte und den Assemblercode von Hand durchgehen muesste um auszuschliessen das der Compiler da etwas erzeugt das man so nicht erwartet. Seufz. Olaf
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.