Forum: Mikrocontroller und Digitale Elektronik Atmega 16, SPI, DA-Wandler funktionunsfähig


von Rob E. (dancer)


Lesenswert?

Hallo liebes Forum,

ich bin neu im Forum und habe folgendes Problem:

Mein Ziel ist es mit einem Atmega 16 einen Seriellen DA-Wandler über SPI 
anzusteuern.
Der DA Wandler ist der AD5304.

Die Funktionen hab ich analog zu beiden Datenblätter erstellt.
Jedoch bekomme ich am Ausgang vom uC keine Signale (gemessen mit Oszi)

Hier der Code:
1
void spi_init(void)   //SPI Schnittstelle aktivieren für DA-Wandlung
2
{                  
3
  DDRB=(1<<PB4) | (1<<PB5) | (1<<PB7);  //DD_MOSI, DD_SCK als Ausgänge setzten PB4 für CS als Ausgang setzten
4
  SPCR= 0x5B;  //SPI Enable; Master; Prescaler 128  
5
  PORTB |=(1<<PB4);     //PB4 auf 1 Setzten - DA Wandler Low Aktiv
6
}
7
8
void geschw(char Data1, char Data2)//Daten zu DA-Wandler schicken
9
{  
10
PORTB &= ~(1 << PB4);  //PIN PB4 auf 0 (DA-Wandler emfangsbereit) 
11
SPDR=Data1;    //ersten 8 Bit schicken
12
while (!(SPSR & (1<<SPIF))) {};  //warten bis Daten versendet
13
SPDR=Data2;                  //2. Byte schicken
14
while (!(SPSR & (1<<SPIF))) {};  //warten bis Daten versendet
15
PORTB |=(1<<PB4);  //DA Wandler Empfang ausschalten
16
}

Simuliert habe ich das ganze im AVR Studio auch schon, dort liegen die 
passenden Signale am PINB Register an und nicht am PORTB Register.

Habe ich jetzt irgendwo einen Denkfehler ?!

Danke im voraus
Grüße
Rob

von Harald (Gast)


Lesenswert?

Zeig mal Deine Hauptschleife.

von Rob E. (dancer)


Lesenswert?

1
int main(void)
2
{
3
  DDRD=0x01;    //Spannungsversorgung (für Testzwecke)
4
  PORTD=0x01;
5
    
6
  uint8_t e=0b01111111;
7
  uint8_t f=0b11110000;
8
9
  spi_init();
10
  geschw(e,f);
11
  
12
  while(1)
13
  {  geschw(e,f);
14
    _delay_ms(1000);
15
        }

von Stefan B. (stefan) Benutzerseite


Lesenswert?

0x5B... Du hast möglicherweise Bit CPOL und CPHA verwechselt.
1
void spi_init(void)   //SPI Schnittstelle aktivieren für DA-Wandlung
2
{
3
  // DD_MOSI, DD_SCK als Ausgänge setzten 
4
  // PB4 für CS als Ausgang setzten                  
5
  DDRB=(1<<PB4) | (1<<PB5) | (1<<PB7);  
6
7
  // SPI Enable; Master; Prescaler 128
8
  // CPOL=0,CPHA=1: Mode 2 
9
  // vgl. AD5304/AD5314/AD5324 to 68HC11/68L11 Interface
10
  // in AD5304_5314_5324.pdf
11
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<SPR1)|(1<<SPR0);
12
13
  // SPI Interrupt Flag löschen
14
  {
15
    uint8_t dummy;
16
    dummy = SPSR; 
17
    dummy = SPDR;
18
  }
19
20
  PORTB |=(1<<PB4);     //PB4 auf 1 Setzten - DA Wandler Low Aktiv
21
}

> Jedoch bekomme ich am Ausgang vom uC keine Signale (gemessen mit Oszi)

Mindestens am PB4 müsstest du ein Signal bekommen. Wenn das nicht der 
Fall ist, wird weder spi_init() noch geschw() aufgerufen. Dann hängt der 
Atmega16 vielleicht im RESET. Das könnte dann ein Watchdog-Problem sein, 
aber nix grundsätzliches mit SPI.

von Rob E. (dancer)


Lesenswert?

Also ich bin jetzt schon einen Schritt weiter gekommen, die SPI 
funktioniert mittlerweile Tadellos. Hab einen neuen Atmega16 rein. Ka 
evtl hab ich den alten durchgebrannt.

Das mit CPOL und CPHA hab ich mir auch schon gedacht. Aber Laut 
Datenblatt liest der DA Wandler bei einer Fallenden Flanke, was wiederum 
laut Oszi passen sollte.

Ich bekomme am Ausgang des DA-Wandlers jedoch absolut keine Regung. Ich 
weiß nicht woran es sonst liegen könnte. Hab den DA zum 4ten mal neu 
eingelötet (bzw. neuen eingelötet) , auf Lötbrücken durch gepiept. 
Nichts, sonst passt an der Hardware auch alles. Es sind keine Lötbrücken 
drin und die Signale kommen Richtig am DA-Wandler an.

Ich bin ratlos...

EVTL sende ich einfach die Flaschen Daten an den DA. Wobei ich auch da 
schon sämtliche Optionen getestet hab.

Irgendwo überseh ich etwas....

Aber danke für deine Antwort.
Grüße
Rob

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Bei

  uint8_t e=0b01111111;
  uint8_t f=0b11110000;

Wäre lt. Datenblatt

A1 A0 => 01: DAC B
/PD   => 1: kein Powerdown
/LDAC => 1: Only addressed input register is updated. There is
no change in the content of the DAC registers.

Aufgrund des Double-Buffered Interface aus Input Shift Register und 
DAC Register, würde ich mich mit dem /LDAC näher befassen.

Im ersten Schritt würde ich die Doppelpufferung umgehen und mal dies 
senden:

  uint8_t e=0b01101111;
  //             ^
  uint8_t f=0b11110000;

ADD: Prima Sache das mit den Links Datenblättern im Forum. Lob an 
Andreas!

von Rob E. (dancer)


Lesenswert?

Ich hab die Polarität wie von dir vorgeschlagen abgeändert. Und Das LDAC 
auf 0 gezogen ändert jedoch beide male nichts...

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Dann bin ich auf dem gleichen Stand wie du: ratlos ;-(

REFIN am DAC hängt nicht unabsichtlich auf GND oder ist unabsichtlich 
unbeschaltet, sondern hängt korrekt an einer Spannungsquelle (zur Not an 
Vdd 5V)?

In welchem Zustand befindet sich der DAC, wieviel Strom zieht der DAC 
und ändert das sich in Abhängigkeit von Zeit (Power Up) und SPI 
Befehlen? Im Normalmodus sollte es im Ruhezustand ja 600 µA bei 5V sein 
und im Power down Modus 200 nA (bei 5V)

Hast du Tools (z.B. Logikanalysator) um dir die SPI Übertragung 
anzusehen? Hast du schon mit der Datenrate experimentiert?

von Rob E. (dancer)


Lesenswert?

Also Problem gelöst.

mein Code von Anfang war richtig ...
Das Problem war das mir der AD5304 (SMD Beinchen Abstand 0,5mm) kaputt 
ging, (Lötbrücke) und beim wieder neu verlöten, habe ich die 
Datenleitung mit der Clock Leitung vertauscht....

Er funktioniert nun wunderbar.

Danke für deine Antworten.

Grüße
Rob

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
Noch kein Account? Hier anmelden.