SPI - A/D Wandler AD7124 Kommunikation

Vielleicht ist die spi-initialisierung im mode 3 fuer den adc doch etwas spezieller als es die implementierung fuer den atmega hergibt?

Ich hatte auch schon mal vorgeschlagen, beide Datenblätter zu vergleichen.

Ich vermute das CPHA bit muss ebenfalls gesetzt sein.

Mode 0..3 oder Mode 1..4.
Je nach Definition. Ich gehe vom ersten aus. Janiiix Code vom zweiten Fall, er hat also tatsächlich Mode 1 eingestellt.
 
Habe alle Modes ausprobiert.
 
Das kann doch nicht so schwer sein... Was gibt es denn für Möglichkeiten das Problem zu finden?

Ich habe schon mal mit einem anderen Chip (auch von ad, fast gleiches Protokoll) sprechen können...

Das hat dort ohne Probleme geklappt. Wieso sollte das hier mit dem nicht so klappen...
 
Was gibt es denn für Möglichkeiten das Problem zu finden?

Ich würde zunächte einmal schauen, dass der richtige SPI Mode eingestellt ist und nicht alle durchprobieren und einfach einen wählen, wenn es nicht funktioniert. Dann ist nämlich die weitere Fehlersuche problematisch. Schau dir beide Datenblätter an, und vergleiche die Diagramme. Ich denke es müsste CPOL und CPHA gesetzt sein, das ist SPI Mode 3 (fallende Flange = setup, steigende Flanke = sample). Im Moment ist bei dir anscheinend nur CPOL gesetzt, das entspricht SPI Mode 2 (fallende Flanke = sample, steigende Flanke = setup).

Es könnte sein, dass dein MISO-Signal belastet ist (es sieht nach deinem Oszillogramm so aus). Eventuell ist das Signal durch den ISP Programmer belastet. Kannst du das MISO Signal "abhängen" und am AD-Wandler messen, geht es dann auf high?

Mehr fällt mir nicht ein. Das Datenblatt habe ich nur kurz überflogen, ich habe da aber nichts besonderes gesehen, was zu beachten wäre. (Das MISO Signal hat anscheinend noch eine weitere Funktion, wenn CS\ auf high ist)
 
Womit sollte das Signal belastet sein? Ich habe den ISP MK2 auch abgezogen gehabt und es war genau das gleiche...

www.analog.com/media/.../EVAL-AD7124-8SDZ_UG-856.pdf
Das ist das Board was ich nutze... Also vom Layout her. sollte es wohl keine Probleme geben.
 
Womit sollte das Signal belastet sein? Ich habe den ISP MK2 auch abgezogen gehabt und es war genau das gleiche...
Gut, dann wissen wir nun, dass der Programmer das Signal nicht belastet.

Dein Link funktioniert nicht. Hier der korrigierte Link.
 
Ohje...
Habe einen hoffentlich nicht so schweren Denkfehler gehabt / gemacht...



CodeBox C
#define MISO_DDR DDRB


#define MISO_PIN PINB


#define MISO_PORT PORTB


#define MISO_BIT 3


Damit setze ich natürich nicht PB3 sondern 1 & 2...
Kann es sein, dass ich damit den Ausgang getoastet hab?
 
Damit setze ich natürich nicht PB3 sondern 1 & 2...
?

MISO_DDR &= ~(1<<MISO_BIT);

Damit definierst du den Pin PB3 (MISO) als Input, das ist der Zustand nach Reset. Es ist ein hochohmiger Eingang. Sonst nutzt du wahrscheinlich MISO_BIT in deinem Code nicht weiter.
 
Also mit dem Layout sollte es keine Probleme geben, da das ein Board von AnalogDevice ist.
Die Pins habe ich alle mit dem Oszilloskope nachgemessen.
Bis auf "MISO" dort kommt nichts, keine Antwort.
??
Der AD wird sicher Slave sein, insofern bedient der nur MISO (SDO), und eigentlich auch nur dann, wenn der Chip via /CS selektiert wurde.
Üblicherweise kann über SDO dann auch ausgelesen werden, ob der Chip "bereit" ist (/RDY)
MOSI (DIN), SCK (SCLK) und CS werden vom AD nur gelesen, hochohmig...

Dein AVR ist also Master.
Damit definierst du den Pin PB3 (MISO) als Input, das ist der Zustand nach Reset. Es ist ein hochohmiger Eingang.
Abgesehen davon übernimmt das SPI die Kontrolle über einige DDR und PORT-Bits, sobald SPE (SPI enable) gesetzt wird. Override
Wenn das Master-Bit gesetzt ist
  • ist MISO immer Eingang (DDR-Bit=0), man hat aber Zugriff auf das PORT-Bit (kann also den Pullup zuschalten)
  • wird der PORT-Value ("Pegel") des SCK-Pin vom Clock-Output und des MOSI-Pin vom SPI-Output (quasi das SPI-Schieberegister) überschrieben, man hat aber Kontrolle über die DDR-Bits (Kann also zwischen Ein- und Ausgang wählen (bei Ausgang zappeln die Pins dann zwischen Hi und Lo, bei Eingang zwischen Tristate und "Hi-via-Pullup"
Wenn das Master-Bit nicht gesetzt ist
  • sind MOSI, SCK und CS immer Eingang (man hat aber weiterhin Zugriff auf das PORT-Bit)
  • wird der PORT-Value des MISO vom SPI-Output festgelegt (man hat aber weiterhin Zugriff auf das DDR-Bit)
  • solange /CS high ist, ist MISO tristate
Insofern erübrigen sich bei der Konfiguration ein paar Schritte...
Eine Besonderheit gilt für den /CS am AVR: Wenn der AVR Master ist, und der /CS-Pin Eingang, zwingt ein Low-Pegel den AVR in den Slave-Mode (löscht das Master-Bit). Verwendest Du den AVR als Master mußt Du also sicherstellen, daß der /CS entweder immer Hi ist, oder Ausgang.
 
??

Insofern erübrigen sich bei der Konfiguration ein paar Schritte...
Eine Besonderheit gilt für den /CS am AVR: Wenn der AVR Master ist, und der /CS-Pin Eingang, zwingt ein Low-Pegel den AVR in den Slave-Mode (löscht das Master-Bit). Verwendest Du den AVR als Master mußt Du also sicherstellen, daß der /CS entweder immer Hi ist, oder Ausgang.

hi LotadaC,

habe ich gemacht! Konnte ja schon mit einem ähnlichen Chip kommunizieren. Der hatte mehr oder weniger das gleiche Protokoll.
 
Ich habe schon mal schnell reingeschaut (ich kann mir das am WE noch einmal näher ansehen).

Ich bin der Meinung, clock_option muss hier 3 sein, nicht 2.
Bei SPI Mode 3 ist CPOL und CPHA gesetzt. Am Ende der Zeilen das mode1 bis mode4 kenne ich so nicht, ich kenne mode0 ... mode3.


CodeBox C
switch(clock_option)
     {
       case 0 : {SPCR &= ~((1<<CPOL) | (1<<CPHA)); }break; // mode 1
       case 1 : {SPCR |=  (1<<CPHA);         }break; // mode 2
       case 2 : {SPCR |=  (1<<CPOL);         }break; // mode 3
       case 3 : {SPCR |=  ((1<<CPOL) | (1<<CPHA));   }break; // mode 4
       default: {return 0;               }; // error
     }


In der verwendeten Lib spi.c wird für MasterSPI auch der SS Pin (PB0) konfiguriert, sowie ein freier SS Pin (PB6).
Auf PB0 liegt auch eine LED, das ist soweit nicht schlimm, weil PB0 für die LED auch ein Ausgang ist.
PB6 wird auch als Ausgang geschaltet, das ist der Software SS Pin.

Achtung nun kommt der eigentliche Fehler:

In deiner Funktion AD7124_read_uint8(...) verwendest du


CodeBox C
void chip_enable_high(void)
{
   SS_PORT &= ~(1<<SS_BIT);
}

void chip_disable_low(void)
{
   SS_PORT |= (1<<SS_BIT);
}

(Das _high und _low finde ich hier irritierend, da die tatsächlichen logischen Pegel dazu invertiert sind)

Hier wird SS_BIT und SS_PORT genutzt, definert in spi.h. Im Moment ist das PB6.
Du müsstest CS\ also an PB6 angeschlossen haben.
Das ist wahrscheinlich nicht der Fall, da du in main.c einen SYNC pin definiert hast, der liegt aber auf PB5!


CodeBox C
#define SYNC_DDR   DDRB
#define SYNC_PORT   PORTB
#define SYNC     (1<<5)
#define SYNC_HIGH   SYNC_PORT |=  SYNC
#define SYNC_LOW   SYNC_PORT &= ~SYNC


... und dieser wird in deiner Software nicht genutzt.

Entferne dein SYNC. Definiere in spi.h
#define SS_BIT 5
wenn dein CS\ auf PB5 liegt.

Den richtigen SPI Mode nicht vergessen.
 
@Dirk
Das mit den Mode habe ich geändert.

Was hat der Sync Pin mit dem DOUT/RDY Pin zu tun? Das sind zwei unterschiedliche Pins...
Den Sync Pin verwende ich aktuell nicht, dass stimmt. Habe ihn jedoch definiert, da man ihn evtl. später mal gebrauchen könnte.

Außerdem habe ich mir die Signale alle mit dem Oszi angeschaut. MOSI, SCK, CS waren vorhanden und sahen gegenüber MISO gut aus, die Pegel haben auch gestimmt.
 
Zuletzt bearbeitet:
Außerdem habe ich mir die Signale alle mit dem Oszi angeschaut. MOSI, SCK, CS waren vorhanden und sahen gegenüber MISO gut aus, die Pegel haben auch gestimmt
Hmmm, dann weiß ich im Moment auch nicht weiter. Ich schaue mir das am Wochenende noch mal näher an. Die Pegelhöhe stimmt, alles 3,3V?
 
Ja, dass ist es ja. Bis auf MISO passt Physikalisch alles :(
 
Mir ist gerade aufgefallen, dass du 0x05 in das Kommandoregister überträgst.
Hier ist das R/W\ Bit nicht gesetzt (Bit 6), du müsstest also eigentlich 0x45 übertragen, wenn ich mich nicht täusche, erst dann kommt beim nächten Byte der Inhalt des ID Registers zurück.

Ich bin mir nicht sicher, ob du das nicht schon mal so hattest, aber eventuell in Verbindung mit einem falschen SPI Mode hat es dann gerade nicht funktioniert.



CodeBox C
while (1)
  {
     AD7124_read_uint8(0x45);   
   }
 
Hallo @Dirk
Da hast du meinen Quellcode wohl nicht richtig gelesen...
Hier baue ich das Kommando zusammen.
Müsste so wie ich es laut Datenblatt verstanden habe... eine 0x45 sein.



CodeBox C
buffer[0] = (AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD | AD7124_COMM_REG_RA(reg));
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)