Forum: Mikrocontroller und Digitale Elektronik DAC Schieberegister


von Alexander S. (alex130)


Lesenswert?

Hallo versuche einen DAC (TLC5620) anzusprechen mir fehlen aber noch 
einige Grundlagen (oder viele) habe mir bis jetzt diesen Code erst 
einmal einfallen lassen will eigentlich nur wissen ob ich damit erstmal 
richtig liege in der Art den DAC anzusprechen oder ob ich einen 
Denkfehler habe. Ich weiss das ich mit der bit verschiebung im Code noch 
nicht richtig liege.

#include <avr/io.h>
#include <util/delay.h>

#define DAC_PORT PORTC
#define DAC_LOAD 1
#define DAC_CLOCK 0

void dac_data(unsigned char temp1);
void dac_enable(void);

void dac_data(unsigned char temp1)
{
   unsigned char temp2 = temp1;

   DAC_PORT |= (1<<DAC_LOAD);        // RS auf 1 setzen


   //a1
   temp1 = 0xE0 >> 5;
   temp1 = temp1 & 0x04;
   DAC_PORT &= 0x04;
   DAC_PORT |= temp1;
   dac_enable();

   //a0
   temp1 = 0xE0>> 5;
   temp1 = temp1 & 0x04;
   DAC_PORT &= 0x04;
   DAC_PORT |= temp1;
   dac_enable();



   //rng
   temp1 = 0xE0 >> 5;
   temp1 = temp1 & 0x04;
   DAC_PORT &= 0x04;
   DAC_PORT |= temp1;
   dac_enable();


   //d7
   temp1 = 0xE0 >> 5;
   temp1 = temp1 & 0x04;
   DAC_PORT &= 0x04;
   DAC_PORT |= temp1;
   dac_enable();

//d6
temp1 = 0xE0 >> 5;
   temp1 = temp1 & 0x04;
   DAC_PORT &= 0x04;
   DAC_PORT |= temp1;
   dac_enable();
//d5
temp1 = 0xE0 >> 5;
   temp1 = temp1 & 0x04;
   DAC_PORT &= 0x04;
   DAC_PORT |= temp1;
   dac_enable();

//d4
temp1 = 0xE0 >> 5;
   temp1 = temp1 & 0x04;
   DAC_PORT &= 0x04;
   DAC_PORT |= temp1;
   dac_enable();

//d3
temp1 = 0xE0 >> 5;
   temp1 = temp1 & 0x04;
   DAC_PORT &= 0x04;
   DAC_PORT |= temp1;
   dac_enable();


//d2
temp1 = 0xE0 >> 5;
   temp1 = temp1 & 0x04;
   DAC_PORT &= 0x04;
   DAC_PORT |= temp1;
   dac_enable();

//d1
temp1 = 0xE0 >> 5;
   temp1 = temp1 & 0x04;
   DAC_PORT &= 0x04;
   DAC_PORT |= temp1;
   dac_enable();




 //d0
temp1 = 0xE0 >> 5;
   temp1 = temp1 & 0x04;
   DAC_PORT &= 0x04;
   DAC_PORT |= temp1;
   dac_enable();

   _delay_us(42);
}


void dac_enable(void)
{
   DAC_PORT |= (1<<DAC_CLOCK);
    _delay_us(100);  // nicht zu knapp warten, sonst drohen 
Kompatbilitätsprobleme!
   DAC_PORT &= ~(1<<DAC_CLOCK);
}


int
main(void)
{
DDRC=0x07;
dac_data(255);
DDRC=0;

while (1)
{

}

  return 0;
}

Danke im voraus für Hilfe.

von Zacc (Gast)


Lesenswert?

Ich hab leider grad das Datenblatt nicht zur Hand. Normalerweise macht 
man das so :

int v;

int main(void)
{
DDRC=0x07;
v:=0;
while (1) {
 dac_data(v);
 v++;
}
}

Die einzelnen Bits (a0,a1,rng,d7,d6,....) sehen mir etwas zu identisch 
aus. Da stimmt noch etwas nicht denk ich.

von Rahul D. (rahul)


Lesenswert?

>temp1 = 0xE0 >> 5;

Sollte eine Konstante sein...
0xE0 >> 5 = 7

von Alexander S. (alex130)


Angehängte Dateien:

Lesenswert?

Habe jetzt nochmal den Code mit Bit Verschiebung angepasst datenblatt 
des DAC ist im Anhang:

#include <avr/io.h>
#include <util/delay.h>

#define DAC_PORT PORTC
#define DAC_LOAD 1
#define DAC_CLOCK 0
#define schiebeum 5

void dac_data(unsigned char temp1);
void dac_enable(void);

void dac_data(unsigned char temp1)
{

   unsigned char a1dac=0x00;
   a1dac = a1dac & 0x04;
   unsigned char a0dac=0x00;
   a0dac = a0dac & 0x04;
   unsigned char rngdac=0x00;
   rngdac = rngdac & 0x04;

   unsigned char d7dac=temp1<<2;
   d7dac = d7dac & 0x04;
   unsigned char d6dac=temp1<<1;
   d6dac = d6dac & 0x04;
   unsigned char d5dac=temp1;
   d5dac = d5dac & 0x04;
   unsigned char d4dac=temp1>>1;
   d4dac = d4dac & 0x04;
   unsigned char d3dac=temp1>>2;
   d3dac = d3dac & 0x04;
   unsigned char d2dac=temp1>>3;
   d2dac = d2dac & 0x04;
   unsigned char d1dac=temp1>>4;
   d1dac = d1dac & 0x04;
   unsigned char d0dac=temp1>>5;
   d0dac = d0dac & 0x04;

DAC_PORT |= (1<<DAC_LOAD);


//a1
   DAC_PORT &= 0x04;
   DAC_PORT |= a1dac;
   dac_enable();

//a0
   DAC_PORT &= 0x04;
   DAC_PORT |= a0dac;
   dac_enable();

//rng
   DAC_PORT &= 0x04;
   DAC_PORT |= rngdac;
   dac_enable();


//d7
   DAC_PORT &= 0x04;
   DAC_PORT |= d7dac;
   dac_enable();

//d6
   DAC_PORT &= 0x04;
   DAC_PORT |= d6dac;
   dac_enable();

//d5
   DAC_PORT &= 0x04;
   DAC_PORT |= d5dac;
   dac_enable();

//d4
   DAC_PORT &= 0x04;
   DAC_PORT |= d4dac;
   dac_enable();

//d3
   DAC_PORT &= 0x04;
   DAC_PORT |= d3dac;
   dac_enable();


//d2
   DAC_PORT &= 0x04;
   DAC_PORT |= d2dac;
   dac_enable();

//d1
   DAC_PORT &= 0x04;
   DAC_PORT |= d1dac;
   dac_enable();

//d0
   DAC_PORT &= 0x04;
   DAC_PORT |= d0dac;
   dac_enable();

//DAC_PORT &= (1<<DAC_LOAD);

}


void dac_enable(void)
{
   DAC_PORT |= 0x01;
    _delay_us(150);  // nicht zu knapp warten, sonst drohen 
Kompatbilitätsprobleme!
   DAC_PORT &= ~0x01;
}




int main(void)
{

DDRC=0x07;
PORTC=0x00;
dac_data(1);


while (1)
{


}

  return 0;
}
Habe die Antworten gelesen zu Zacc verstehe nicht genau wiso in schleife 
dadurch würde sich doch der DAC immer wieder erhöhen.

Ich gebe zu der Code ist sehr einfach geschrieben aber das hilft auch 
das ganze besser zu verstehen.

Danke für jede Antwort.

von SMDli (Gast)


Lesenswert?

Am besten du verwendest die SPI Scnittstelle, die ist für sowas 
gemacht...

Gruss

von Alexander S. (alex130)


Lesenswert?

Na gut wenn dies auch würde ich das auch nehmen gibt da vielleicht 
tutorial für avr gcc habe nämlich kein richtig gefunden oder kann mir 
jemand vielleicht ein richtung vorgeben wie man die bei dem DAC machen 
muss nicht kompletten Code sondern nur ungefähr?
Vielen dank für hilfe

von SMDli (Gast)


Lesenswert?

Also bitte, im Datenblatt zu deinem Controller sind unter SPI sogar 
Codebeispiele drin!

von Alexander S. (alex130)


Lesenswert?

Hast ja recht aber aller anfang ist schwer und meine englishe kenntnisse 
sind auch nicht so gut aber nea.

Habe mir das alles ziemlich lange mal angekuckt habe aber noch ein paar 
fragen:

1.
Beim DAC gibt es 3 Pins dafür LOAD CLK DATA die klemme ich dann in 
folgender Reihenfolgende an den ATMEGA8
LOAD an RCK
CLK an SCK
DATA an MISO oder Mosi ???

wäre das so in etwa richtig

2.
Ich sende ja insgesamt 16 Bits aber muss nur 11 insgesamt senden fängt 
der DAC dann mit der Parametrierung von vorne an oder wartet er bis load 
ausgeschaltet ist?

3.
Ich muss den Atmega als Master einstellen oder ??

danke für jede hilfe.

von Alexander S. (alex130)


Lesenswert?

Bitte nicht schimpfen brauche eben etwas länger.
Müsste ja dann das Beispiel nehmen aus dem Datenblatt oder  aber wie 
mach ich das mit den DD_MOSI &DD_SCK was trage ich dort ein und was ist 
das Load signal vom DAC.

void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_MasterTransmit(char cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
;
}

Danke für Hilfe

von Alexander S. (alex130)


Lesenswert?

Habe mir jetzt nochmal alles genauer angekuckt und einiges verändert 
aber es funktioniert trotzdem nicht.
Load habe ich ans SS Pin
MOSI an DATA
SCK an CLK

#include <avr/io.h>
#include <stdint.h>
#define DD_MOSI PB3
#define DD_SCK  PB5
#define DD_LOAD PB0

void SPI_MasterInit(void)
{

/* Set MOSI and SCK output, all others input */
DDRB = (1<<DD_MOSI)|(1<<DD_SCK);
/* Enable SPI, Master, set clock rate fck/64 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1);
}



void SPI_MasterTransmit(char cData)
{

/* Start transmission */
SPDR = 15;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
;

/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
;



}

int main(void)
{
SPI_MasterInit();
SPI_MasterTransmit(200);
   for(;;)
        ;
   return 0;
}

bitte helft mir.

von Alexander S. (alex130)


Lesenswert?

hat den keiner eine idee hier?

von SMDli (Gast)


Lesenswert?

Wie im Datenblatt beschrieben, musst du den Pegel vom SS Pin selbst 
einstellen (das ist bei deinem Beispiel noch nicht implementiert). Der 
ist meist wie folgt: vor der Übertragung auf 0 ziehen und nach der 
Übertragung wieder auf 1. Dann nimmt der DAC den Wert welcher er im 
Schieberegister hat und gibt die Spannung aus.
Wieviel Bit hat dein DAC?

von Spess53 (Gast)


Lesenswert?

Hi

Du musst DD_load (SS ?) auch als Ausgang setzen. Nach erfolgter 
Übertragung erwartet der TLC (Habe das Datenlatt nicht gelesen) mit 
Sicherheit einen Impuls an Load um den übertragenen Wert vom 
Schieberegister in das Ausgaberegiter zu übernehmen.
Noch ein Hinweis: selbst wenn du das SS-Pin nicht, benutzt sollte es als 
Ausgang geschaltet sein. Ansonsten geht die SPI nach der Übertragung in 
den Slave-Modus

MfG Spess

von Spess53 (Gast)


Lesenswert?

Hi

Habe mal spassenshalber in das Datenblatt des TLC geschaut. Wie ich 
vermutet hatte wird der DAC-Wert mit einem Low-Impuls übernommen. Aber 
nur wenn LADC Low ist. Ist dir eigentlich aufgefallen,daß du 11 Bit 
übertragen musst? Da bekommst du mit der SPI Probleme. An deiner Stelle 
würde ich eine Software-SPI einsetzen. Allerdings solltest di dich 
erstmal etwas intensiver mit den Datenblättern auseindersetzen. Hier 
bestehen meinesachtens die grössten Mankos.

MfG Spess

von Alexander S. (alex130)


Lesenswert?

okay da sollte ich woll lieber sagen ich lass den TLC5620 erst einmal 
sein und versuche mal etwas einfacheres was wo man die Grundlagen besser 
versteht. kennt ihr da sowas habe schon von Portexpandern gelesen mit 
SPI gibts da ein einfaches modell oder ein DAC mit 8 bit oder 16 bit?

Könnt ihr mir die frage wenigstens noch beantworten könnt mich zwar in 
den Arsch beissen das ich das nicht geschafft habe mit eurer hilfe? Aber 
habe auch etwas mehr über bit verschiebung und SPI da zu gelernt.

mfg Alex

von Alexander S. (alex130)


Lesenswert?

SMDli wrote:
> Wie im Datenblatt beschrieben, musst du den Pegel vom SS Pin selbst
> einstellen (das ist bei deinem Beispiel noch nicht implementiert). Der
> ist meist wie folgt: vor der Übertragung auf 0 ziehen und nach der
> Übertragung wieder auf 1. Dann nimmt der DAC den Wert welcher er im
> Schieberegister hat und gibt die Spannung aus.
> Wieviel Bit hat dein DAC?

noch mal zu der Frage er hat 8 bit man muss aber wegen einiger 
einstellungen noch 3 bit am anfang übertragen also insgesamt 11 bit

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.