Hallo, ich möchte einen DAC (12 bit DAC7611 von Texas) an meinen ATmega323 anschliessen. Verkabelt habe ich eigentlich schon alles, nur komme ich nun nicht damit klar, wie ich das Teil ansteuern soll. Ich benutze Codevision, dort gibt es so einen Wizard, wo man schon gleich SPI auswählen kann. Nur bin ich mir mittlerweile garnicht mehr sicher, ob der DAC tatsächlich SPI benötigt. In der Doku steht zwar "3-wire interface", und ich hatte mir ihn auch bei Texas also SPI kompatiblen ausgewählt, jedoch steht im Datenblatt meines uC´s, daß für SPI 4 Leitungen vorgesehen sind: MISO, MOSI, SCK und SS. Im Datenblatt des DAC´s steht, daß nur 3 Leitungen mit dem uC verbunden werden müssen: Serial Clock, Serial Data und Load Strobe. Meint ihr daß das so kompatibel ist? Ein weiteres Problem ist, daß über Serial Data (SDI) ein 12 bit Wort übertragen werden muß. Nun weiß ich auch nicht ob das überhaupt mit meinem uC bzw. mit Codevision kompatibel ist, da die glaube ich immer von Byte-langen Wörtern (also 8 oder 16 bit) ausgehen. Wie man wahrscheinlich merkt, ist es das erste mal, daß ich was mit SPI mache, dementsprechend verwirrt bin ich... Vielleicht hat trotzdem jemand einen Tipp. Gruß, Stefan
Hallo Stefan, nach meinem naiven Verständnis der Datenblätter (bin kein SPI-Experte) verbindest Du SCK mit CLK, MOSI mit SDI und SS mit CS. Den LD-Impuls mußt Du Dir mit einem separaten PIN am AVR generieren. Die MISO-Leitung entfällt, weil vom DAC keine Daten zurückkommen. Von Codevision habe ich keine Ahnung. Aber wie gesagt, habe selbst noch nichts mit SPI gemacht. Warte besser noch auf fundierte Meinungen. Oder benutze die Forum-Suchfunktion, SPI dürfte schon häufiger Thema gewesen sein. Gruß, Frank
Hallo Frank, danke erstmal für Deine Antwort. Ich habe immer noch meine Probleme mit dem Verständnis von SPI. Wie funktioniert das genau. Hat da vielleicht irgend jemand einen brauchbaren Link? Ansonsten probiere ich mich nochmal anhand der Datenblätter schlau zu machen, das hatte jedoch bisher nicht soo viel gebracht. Bis dann, Stefan
Ist eigentlich nicht so schwer. Du benötigst lediglich MoSi (MasterOutSlaveIn), welches du mit SDI (oder Serial Data oder wie auch immer) des DAC's verbindest. Dann hängst du noch den SCK an den Clock-Eingang des DAC's. (So, wie es Frank schon gesagt hat.) Den SS brauchst du nicht, stattdessen nimmst du irgend nen anderen Pin des Controllers. Somit ist dein Interface fertig. Für die anderen beiden Pins des DAC (/LD und /CLR) nimmst du wieder 2 andere Pins oder legst sie auf nen definierten Pegel. /CLR auf Low und dein DAC gibt ne Spannung von 0V aus. /CLR auf High gibt die Spannung, die digital im Latch steht, aus. /LD auf Low gibt alle Spannungsdaten sofort an die DAC-Switches. /LD auf High speichert die Daten zwischen, bis /LD auf Low geht. D.h. im prinzip kannst du /CLR immer auf High lassen, und /LD immer auf Low. (Wobei ich letzteres nicht empfehlen würde, da sonst deine Spannung am Ausgang erst mal in der Gegend rumhüpft, bis die kompletten Daten geschrieben worden sind.) Steht aber alles im Datenblatt drin, auch wie die Daten auszusehen haben, die der DAC erwartet. Sollten meine Überlegungen irgend welche Fehler beinhalten, bitte ich diese zu entschuldigen. Hab das nur mal schnell hingeschrieben. Gruß, ERDI - Soft.
Hallo ERDI, was SPI angeht hast du mir auf jedem Fall schonmal sehr gut weitergeholfen. Ist eigentlich ziemlich klar. Das einzige Problem was ich nun noch habe, ist folgendes: im Datenblatt http://focus.ti.com/lit/ds/symlink/dac7611.pdf steht, daß das input Format "straight binary und MSB first" ist. Der DAC erwartet offenbar ein 12 bit langes Wort, von dem ich nicht weiß wie ich es "generieren" soll. Wenn ich alles richtig verstanden habe, werden die Daten die per SPI verschickt werden sollen ins SPI Data Register meines uC geschrieben. Dies ist jedoch nur 8 bit lang, und somit habe ich da ein Problem wo und wann die restlichen 4 bit´s geschrieben werden. Hat jemand von Euch eine Ahnung? Gruß, Stefan ps: Und was genau ist ein "Latch"?
Ist doch eigentlich relativ einfach. Du hast 3 Nibbles (4bit), die der DAC erwartet, kannst aber mit Hardware-SPI immer nur 8bit verschicken, wobei man, soweit ich weiß, das Startbit angeben kann. (Also MSB oder LSB zuerst). Du nimmst also dein zweites Byte und schickst es mit dem MSB (most signigicant bit) zuerst an den DAC, dann das erste Byte auf die gleiche Art. Dabei gehen die 4 höchstwertigen bits von Byte zwei (das, welches zuerst geschrieben wurde) verloren, werden ins Nirvana geschoben. [ Byte 2 ] [ Byte 1 ] [D8 D7 D6 D5 D4 D3 D2 D1 D0] [D8 D7 D6 D5 D4 D3 D2 D1 D0] ++ ++ ++ ++ Byte zwei zuerst mit D8 in den DAC schieben, sobald Byte 1 reingeschoben wird, sind die mit den ++ gestorben. Wenn du jetzt nen Pegelwechsel an /LD iniziierst (von High auf Low), werden die Daten vom Latch (Zwischenspeicher) an die DAC-Switches transferiert und dein eingestellter Wert erscheint am Ausgang. Alles klar?
Hallo Stefan, da das Teil bis 20 MHz Daten einlesen kann werden kann würde auch eine Softwareroutine sehr schnell abgearbeitet. Das ist ein reines 12 bit Schieberegister. Unsigned Word laden, /LD Pin low. Schleife (12*) Wenn Word and h'0800' > 0: Portpin setzen sonst löschen. Word links schieben, clock setzen, clock löschen, ende Schleife. /LD Pin high - fertig . Wenn du während die Daten reingeschoben werden, lieber 0V am Ausgang haben willst, statt Zufallswerte musst du /CLR mitverwenden. Gruß Bernhard
@BernhardT: Ne, erst /LD high, sonst werden die Daten im DAC gleich als Spannung umgesetzt. Erst wenn alle 12bit geschrieben sind, /LD kurz auf Low, um die Daten vom Latch in den DAC-Switch zu übernehmen, dann wieder auf High. Bei deiner Methode springt der Ausgang unkontrolliert zwischen 0 und 4.096 Volt rum. Den /CLR braucht man eigentlich nur, wenn man mal ganz schnell auf 0V muß. Es sei denn, du hast /LD und /CS verwechselt. Dann paßts. :-)
Hallo ERDI und BernhardT, vielen Dank für Eure Tipps, ich werde gleich mal probieren sie in die Tat umzusetzen. Bis später, Stefan
Hallo, ich habe nun meinen DAC komplett an den uC angeschlossen. Das sollte eigentlich alles stimmen. Nur tut sich am Ausgang des DAC´s irgendwie noch nichts. Ich habe mir folgende Routine gebastelt: void send_dac(char high, char low) { char sende; sende = spi(high); sende = spi(low); delay_us(10); PORTB.3=0; // Load Strobe Pin delay_us(100); PORTB.3=1; } Wenn ich dann z.B. send_dac(0x0F,0xFF) sage, so müßte der DAC eigentlich 4 Volt (also volle Spannung) ausgeben. Ich habe jedoch permanent 0 Volt am Ausgang. Hat jemand noch eine Idee, wo hier der Wurm drin sein könnte? Gruß, Stefan ps: Die Funktion spi() wurde mir von Codevision vorgefertigt und macht folgendes: unsigned char spi(unsigned char data) this function sends the byte data, simultaneously receiving a byte. Daß kein Byte empfangen wird (vom DAC wird nichts zurückgeschickt, da ich nur den MOSI Pin benutze) sollte doch eigentlich nicht weiter stören.
Solltest vielleicht vor dem Senden der Daten den /CS Pin noch auf Low legen. könnte evtl. helfen. :-)
Aber ich dachte, wenn ich nur ein Bauteil am SPI Bus hängen habe, dann muss der /CS Pin nicht unbedingt auf Low gezogen werden. Oder sollte man das bei nur einem Bauteil ebenfalls machen, damit man da nicht irgendwelche undefinierten Zustände hat? Stefan
Ach ja, noch was: kann ich wenn ich den Pin benutze ihn permanent auf Ground legen? Oder sollte ich das jedesmal vor der Datenübertragung mit dem uC auf Low ziehen? Stefan
Du mußt den Pin AUF JEDEN FALL beschalten. Des DAC weiß ja sonst nicht, dass er gemeint ist. Man könnte den Pin theoretisch dauerhaft auf Low legen, würde ich aber nicht unbedingt empfehlen, da sonst u.U. auch irgendwelche Störsignale den DAC-Wert verändern könnten.
Ich setze den /CS Pin nun ganz zu Beginn meines Programms auf low. Aber es funzt immer noch nicht: Ich habe permanent volle Spannung am Ausgang meines DAC´s. Irgendwas ist da noch faul. Meinst Du denn daß diese kleine Routine in meinem Programm so funktioniert wie sie soll? Stefan
Mooooooment, weiter oben stand: Ich habe jedoch permanent 0 Volt am Ausgang. Jetzt Ich habe permanent volle Spannung am Ausgang. Bin ich verwirrt oder Du? :-) Das Zweite Ergebnis wäre ja zu erwarten bei gesendetem 0x0FFF. Dann bin ich mir auch nicht ganz sicher, was in deinem SPDR steht. Da der Datenpuffer ja beim Senden mit dem "pinzustand" von MISO geladen wird. Wenn das MISO-Pin high ist , dann stehen nach senden des ersten Bytes evntl. 0xFF im SPDR. Vielleicht ist da ja was falsch gelaufen. Würde mich interessieren , welche Funktion von Codevision sowas fertig generiert. Uwe (auch nur ein Anfänger auf dem Gebiet)
Hallo Uwe, daß ich gestern immer 0 Volt und heute 4 am Ausgang habe ist natürlich verdächtig. Aber mit den 4 Volt hat es schon seine Richtigkeit. Was genau in der spi Funktion passiert probiere ich gerade rauszufinden. Ich habe bisher erst folgendes gefunden, was mir nicht viel weiterhilft: #ifndef SPI_INCLUDED #define SPI_INCLUDED unsigned char spi(unsigned char data); #endif Ich glaube statt MISO meinst du MOSI (also Master Out, Slave In), oder? Da müßte ich erstmal überprüfen ob die Sachen die im MOSI drinstehen mit meinen vorgegebenen Daten übereinstimmen. Stefan
Hi, also ich habe das so in Erinnerung: Wenn du ein Datenbyte ins SPDR schreibst wird ein Takt erzeugt und das Byte seriell an MOSI ausgegeben (rechts_shift oder links.. je nachdem ob MSBfirst oder LSBfirst), gleichzeitig wird bei jedem Takt ein Bit von MISO in SPDR eingeschoben. Am Ende ist dein Byte raus und dafür das , was an MISO stand während der Takte drin im SPDR. Wenn also deine MISO nicht belegt ist und "1" führt, dann steht nach dem ersten gesendeten Byte 0xFF im SPDR. Jetzt muss nur noch das einschreiben des zweiten Bytes falsch laufen...warum auch immer, und schon steht im SPDR immer 0xFF und wird gesendet.--> Volldampf am Ausgang des DAC. Aber das ist nur so eine Idee. Vielleicht ist auch das Data_IN_Pin vom DAC immer high(schaltungstechnischer Fehler ? ) dann kommt das auf das gleiche raus. Bin mal gespannt woran das gelegen hat, wenn du es gefunden hast. Ciao Uwe (immernoch Anfänger)
Hallo Uwe, an dem MOSI Pin meines uC´s liegen tatsächlich permanent 5 Volt. Das kann ja irgendwie schonmal nicht stimmen. Nun weiß ich jedoch nicht warum der permanent auf high ist, da ich nicht genau weiß was diese verdammte von Codevision erzeugte spi() funktion genau macht. Vielleicht sollte ich probieren die gesamt Kommunikation "manuell" zu realisieren, und nicht mir von Codevision irgendwas vorfertigen lassen. Stefan
Verdammte Axt!!!!!!! Hier kommt die Lösung meines Problems: Das Data Direction Register war falsch gesetzt, die Pins für Chip Select (CS) und Load Strobe (LD) waren nicht als Ausgang gesetzt. Ansonsten stimmte alles. Immer wieder erstaunlich, wieviel Zeit man verwenden kann um dann irgendwo triviale Fehler zu finden.... Nochmals danke für Eure Hilfe, Stefan
HEHE, "verdammte Axt" rutscht mir auch ab und zu mal raus. Gut , dass du es gefunden hast.... Ciao Uwe
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.