mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DAC 8534 an Atmega 8 funkt nicht, in C


Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich brauche Hilfe weil ich leider nicht weiß was ich falsch mache und 
was ich noch ändern kann bzw. muss damit es endlich funktioniert.
Ich verwende einen Atmega 8 mit 18432000 MHz.

Ich möchte einen 4 Kanal D/A Wandler von Texas Instruments betreiben.
Dazu schrieb ich mal dieses kleine Testprogramm in C.
Mit dem Timerinterupt simuliere ich einfach eine Abtastung die ich 
später brauche.
Sonst ist der DAC das einzige SPI Gerät (vorläufig).

Type: DAC 8534
Das Datenblatt findet man hier:
http://focus.ti.com/docs/prod/folders/print/dac8534.html

Anschluss:
PIN 3,4,12 auf 5 Volt
PIN 5,6,13,14,15,16 auf 0 V (GND) (16 - LDAC Software mäßig)

PIN 11 auf MOSI, Atmega
PIN 10 auf SCK, Atmega
PIN 9 auf PC0, Atmega (9 - Sync_nicht)

An den Ausgängen messe ich mit dem Voltmeter.


Es toggelt brav die LED aber sonst tut sich nicht das was sich tun soll.


Mein Programm:

#include <avr/io.h>    // Ein/Ausgangsbelegung, Definitionen
#include <math.h>      // Mathematikpaket
#include <stdint.h>    // AVR Integer
#include <avr/interrupt.h>  // Interrupt Routinen, Definitionen


#ifndef F_CPU
#define F_CPU 18432000
#endif


#define DAC_KANAL 1 // DAC Bitnr., Kanal auswählen, für Bitshift DAC8534


// Module definieren
void SPI_schreiben2(uint16_t DAC_Wert, uint8_t kanal);  // DAC 8534
ISR(TIMER1_COMPA_vect);        // Interruptroutine


int main (void) {

  // Ein-/Ausgänge initialisieren

  // Datenrichtung Ausgang
  DDRD |= (1 << DDD3);      // LED
  DDRC |= (1 << DDC0);      // Sync_nicht, DAC 8534
  PORTC |= (1 << PC0);      // Sync_nicht ein


  // Timer, 16 bit, Compare Match Modus, Vorteiler 1024

  TCCR1B |= (1 << WGM12) | (1 << CS10) | (1 << CS12);
  OCR1A = 18000;  // Vergleichsregister (1 s bei Vorteiler 1024)
  TIMSK |= (1 << OCIE1A); // enable OutputCompareA Interrupt


  // SPI, Atmega als Master
  // MOSI und SCK Ausgang, alle anderen als Eingänge

  DDRB |= (1 << DDB3) | (1 << DDB5); // SPI Ausgänge aktivieren
  DDRB |= (1 << DDB2);    //
  PORTB |= (1 << PB2);    //

  // Enable SPI, Master, Vorteiler 32

  SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1);
  SPSR = (1 << SPI2X);

  sei();    // Interrupts global aktivieren


  while(1) {
    ;
  }
  return 0;
}



ISR(TIMER1_COMPA_vect) {

                     // Wert, Kanal
  SPI_schreiben2(16000,0);
  SPI_schreiben2(32000,1);
  SPI_schreiben2(48000,2);
  SPI_schreiben2(64000,3);


  PORTD ^= (1 << PD3);   // LED toggeln
}



void SPI_schreiben2(uint16_t DAC_Wert, uint8_t kanal) { // DAC8534

  unsigned char Daten1, Daten2, Daten3;
  PORTC &= ~(1 << PC0);  // Sync_nicht aus


  // aufspalten in 8 Bit Zeichen
  Daten1 =  DAC_Wert;         //
  Daten2 = (DAC_Wert >> 8);    //

  Daten3 = (kanal << DAC_KANAL);    //
  Daten3 |= (1 << 4);  // LD0 auf 1 (DAC-Kanal aktualisieren)


        // Übertragung starten

  SPDR = Daten3;
  while(!(SPSR & (1 << SPIF))) {
    ;      // warten bis Daten übertragen
  }

  SPDR = Daten2;
  while(!(SPSR & (1 << SPIF))) {
    ;      // warten bis Daten übertragen
  }

  SPDR = Daten1;
  while(!(SPSR & (1 << SPIF))) {
    ;      // warten bis Daten übertragen
  }

  PORTC |= (1 << PC0);  // Sync_nicht ein
}





Dann würde ich noch gerne wissen wie PIN PB2 am Atmega mit der SPI 
Funktion zusammenhängt. Was hat dieser für eine Funktion wie muss man 
ihn wann setzen und warum?


Ich bitte um Hilfe, vielen Dank
Werner

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Es toggelt brav die LED aber sonst tut sich nicht das was sich tun soll.

Es wäre nett wenn Du uns mitteilen könntest, WAS(!) sich tun sollte.

Ich persönlich möchte mir nicht unbedingt den (fehlerbehafteten) Code 
von vorne bis hinten durchlesen müssen, nur um herauszubekommen, was 
DU(!) womöglich von dem Programm erwartest.

Nix für Ungut...
Magnetus

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alle Sekunden wird diese Routine aufgerufen:

ISR(TIMER1_COMPA_vect) {

                     // Wert, Kanal
  SPI_schreiben2(16000,0);
  SPI_schreiben2(32000,1);
  SPI_schreiben2(48000,2);
  SPI_schreiben2(64000,3);


  PORTD ^= (1 << PD3);   // LED toggeln
}
Das LED nehme ich immer damit ich weiß ob er im Programm stecken bleibt 
oder nicht.


Es sollte jeweils die entsprechende Spannung am DAC Ausgang anliegen.
Kanal 0 sollten ungefähr 1.25 Volt sein, Kanal 2 2.5, ....
Integerwert der in der Klammer steht sollt jeweils als Spg ausgegeben 
werden wobei das Maximum bei 16 Bit natürlich 65535 ist und bei mir 5 
Volt wäre.


bei einem anderen Texas Instruments DAC mit 13 Bit hat mein Programm 
funktioniert, wenn gleich natürlich weniger Bits über den SPI Bus 
übertragen werden und dort ein Chip Select nötig war also eine etwas 
andere Ansteuerung.

Muss aber wegen der Genauigkeit der Anwendung einen 16 Bit Wandler 
verwenden, weil damit später eine Präzisionsstromquelle gesteuert wird.

Ich hoffe das ist eine ausreichende Erklärung

Werner

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Dann würde ich noch gerne wissen wie PIN PB2 am Atmega mit der SPI
> Funktion zusammenhängt. Was hat dieser für eine Funktion wie muss man
> ihn wann setzen und warum?

PB2(/SS) benötigst du hier nicht. Die Frage kannst du dir selbst 
beantworten indem du ein bisschen mehr Zeit in das Lesen des 
Datenblattes (AVR) verbringst.

Ausserdem verwendest du den falschen SPI-Mode. Aktuell arbeitest du mit 
Mode 0, für den DAC benötigst du aber Mode 1 (CPOL = 1).

Gruß,
Magnetus

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen vielen Dank.
Mit dem CPOL funkt es jetzt.

Habs schon entdeckt was PB2 macht:
PB2 muss man auf high setzen damit der SPI Bus aktiviert wird, am ende 
der Routine kann man ihn wieder auf low setzen (oder immer auf high 
lassen). Andernfalls bleibt man in der Routine stecken.
Anscheinend ist es ein Enable befehl für den Atmega8.
Das steht so nicht drin im Datenblatt und trotzdem funkt es nur so !!!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.