Forum: Mikrocontroller und Digitale Elektronik DAC8552 SPI Programm


von Martin R. (Gast)


Lesenswert?

Hallo zusammen.
Ich bin Anfänger in Programmieren und hab auch schon Paar Dinge mit I2C 
gemeistert. Jezt bin ich mit SPI dran. Ich habe einen DAC8552 der mit 
SPI angesteuert wird von einem ATmega2560. Dazwischen ist ein LSF0204 
Pegelwandler. Ich versuche momentan lediglich auf einem der zwei kanäle 
ein Analog Signal heraus zu geben. Dafür habe ich mal den Standart SPI 
Code für dieses Projekt gewählt. Jetzt bin ich im Datenblatt die genaue 
Ansteuerung zu ermittteln. Irgendwie fällt mir das unheimlich schwer. 
Als ich mal was mit I2C gemacht habe war dies ein wenig organisiert mit 
Adressen und Kommandos. Hier blicke ich leider nicht ganz durch was ich 
falsch mache. Sieht jemand ev. was ich falsch mache oder ich da einen 
kompletten falschen Ansatz habe im Programm.
Danke im Voraus!
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#pragma GCC optimize 2    //Optimierung
4
5
#define F_CPU 16000000UL
6
7
8
#define DD_MISO    PB3
9
#define DD_MOSI    PB2
10
#define DD_SCK     PB1
11
#define DD_SS      PB0
12
#define DDR_SPI    DDRB
13
14
void SPI_MasterInit(void)
15
{
16
  // Set MOSI and SCK output, all others input
17
  DDR_SPI |= (1<<DD_MOSI)|(1<<DD_SCK) |(1<<DD_SS);
18
  // Enable SPI, Master, set clock rate fck/16
19
  SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0);
20
}
21
uint8_t SPI_MasterTransmit(char Data)
22
{
23
  SPDR = Data;
24
  while(!(SPSR & (1<<SPIF)));
25
  return(SPDR);
26
}
27
//****************************************************************************
28
//Hauptprogramm
29
//****************************************************************************
30
int main(void)
31
{
32
    InitDriverColor();            //Einstellungen initialisieren
33
  SPI_MasterInit();            //SPI 
34
    wait_5ms(350);              //Warten bis start Programm LCD Profil
35
  clear_lcd_f();
36
  
37
    while(1)
38
    {
39
      write_text(0,3,"AO-Output Test");
40
      SPI_MasterTransmit(0x00);    //Standard Modus
41
      SPI_MasterTransmit(0x10);    //Kanal 1
42
      SPI_MasterTransmit(0x33);    //MSB
43
      SPI_MasterTransmit(0x00);    //LSB
44
      _delay_ms(100);
45
  }    
46
}

von Tany (Gast)


Lesenswert?

Vor dem Transfer /Read muss du Device selektierten. In deinem Fall wäre 
DD_SS Leitung, je nachdem mit H oder L Pegel. Danach wieder 
deselektieren.

von Tany (Gast)


Lesenswert?

Tany schrieb:
> DD_SS Leitung, je nachdem mit H oder L Pegel
Bei DAC8552 wäre L Pegel...

von Martin R. (Gast)


Lesenswert?

Tany schrieb:
> Tany schrieb:
>> DD_SS Leitung, je nachdem mit H oder L Pegel
> Bei DAC8552 wäre L Pegel...

Wen ich versuche das DD_SS auf H zu setzen motzt der Kompiler das dies 
nicht gehe. Wie würdest du dies setzen damit dieser Pin auf H  ist.

Und versteh ich soweit richtig solange ich die Befehle sende muss DD_SS 
L sein?

von Tany (Gast)


Lesenswert?

Martin R. schrieb:
> Wie würdest du dies setzen damit dieser Pin auf H  ist

PORTB &=~(1<<DD_SS): Set DD_SS auf L
PORTB |=(1<<DD_SS):  Set DD_SS auf H

> Und versteh ich soweit richtig solange ich die Befehle sende muss DD_SS
> L sein

Ja.

von Martin R. (Gast)


Lesenswert?

Tany schrieb:
> Martin R. schrieb:
>> Wie würdest du dies setzen damit dieser Pin auf H  ist
>
> PORTB &=~(1<<DD_SS): Set DD_SS auf L
> PORTB |=(1<<DD_SS):  Set DD_SS auf H
>
>> Und versteh ich soweit richtig solange ich die Befehle sende muss DD_SS
>> L sein
>
> Ja.

Oke soweit so gut dies sehe ich jezt auch mit dem Analizer. Im 
Datenblatt sind mehrere Kommandos angegeben 0x00 Standard modus 0x10 
Kanal1  dan noch LSB und MSB. So sende ich das ja auch aber was mir hir 
fehlt ich hab keine bestätigung über das Kommando wie bie I2C. Den am 
Ausgang tut sich trotzdem nichts. Ausser ich verstehe das Datenblatt mit 
den Kommandos und der Reihenfolge komplett falsch.

von Tany (Gast)


Lesenswert?

So ungefähr...

     PORTB &=~(1<<DD_SS);
      SPI_MasterTransmit(0x10);    //Kanal 1
      SPI_MasterTransmit(0x33);    //MSB
      SPI_MasterTransmit(0x00);    //LSB
      PORTB |=(1<<DD_SS);

von Martin R. (Gast)


Lesenswert?

Tany schrieb:
> So ungefähr...
>
>      PORTB &=~(1<<DD_SS);
>       SPI_MasterTransmit(0x10);    //Kanal 1
>       SPI_MasterTransmit(0x33);    //MSB
>       SPI_MasterTransmit(0x00);    //LSB
>       PORTB |=(1<<DD_SS);

Das habe ich schon einmal ausprobiert. Leider klappt es so auch nicht. 
Irgendwo müsste doch noch die Konfiguration sein 0x00 für Standard 
Betrieb nicht. Aber selbst dan versteht der Chip die Kommandos nicht.

von Tany (Gast)


Lesenswert?

Martin R. schrieb:
> Irgendwo müsste doch noch die Konfiguration sein 0x00 für Standard

Nein.
Schaue mal auf Seite 16. Dort sind alle beschrieben.

von Martin R. (Gast)


Lesenswert?

Tany schrieb:
> Martin R. schrieb:
>> Irgendwo müsste doch noch die Konfiguration sein 0x00 für Standard
>
> Nein.
> Schaue mal auf Seite 16. Dort sind alle beschrieben.

Ja das habe ich auch soweit herausgelesen auber irgendwie kommt es nicht 
auf den Punkt. Soweit habe ich die übertragung herausgelese trotzdem 
funktioniert es nicht und jetzt ist die Frage ob jemand den Fehler der 
kommuniktion mit den Kommandos sieht. Den wen ich noch einmal durch gehe 
seh ich trotzdem keinen Unterscheid.

von Tany (Gast)


Lesenswert?

Na probiere mal aus:

      PORTB &=~(1<<DD_SS);
      SPI_MasterTransmit(0x10);
      SPI_MasterTransmit(0x33);
      SPI_MasterTransmit(0x00);
      PORTB |=(1<<DD_SS);
      wait...

      PORTB &=~(1<<DD_SS);
      SPI_MasterTransmit(0x34);
      SPI_MasterTransmit(0x33);
      SPI_MasterTransmit(0x00);
      PORTB |=(1<<DD_SS);

von Martin R. (Gast)


Lesenswert?

Tany schrieb:
> Na probiere mal aus:
>
>       PORTB &=~(1<<DD_SS);
>       SPI_MasterTransmit(0x10);
>       SPI_MasterTransmit(0x33);
>       SPI_MasterTransmit(0x00);
>       PORTB |=(1<<DD_SS);
>       wait...
>
>       PORTB &=~(1<<DD_SS);
>       SPI_MasterTransmit(0x34);
>       SPI_MasterTransmit(0x33);
>       SPI_MasterTransmit(0x00);
>       PORTB |=(1<<DD_SS);

Wen ich diesen Code ausprobiere da erscheint tatsächlich für ms eine 
Spannung verschwindet aber sofort wieder und kommt dan nie mehr obwohl 
in While(1).
Somit nicht mal so falsch aber korrekt ist es dennoch leider nicht...

von Martin R. (Gast)


Lesenswert?

Ich hab noch rausgefunden das wen ich den ersten der Beiden Teile ins 
main und nicht While(1) setze zeigt es mir eine Spannung an aber startet 
mit 1,25V statt 0V mit 0x00MSB und 0x00LSB. Und wieso funktioniert 
dieser code nur ein mal auch im While(1)?

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.