www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI 16 bits zu 11bits


Autor: Alexander Schreiber (alex130)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hoffe ich bekomme keine krititk da ich extra dafür ein neues Thread 
eröffne aber ich komme da nicht weiter und denke mir es würde anderen 
auch helfen. Also ich versuche mein Problem oder meine Wissenlücke mal 
zu schildern:
ich versuche einen TLC7620 anzusprechen das ist ein 8 bit DAC aber man 
muss 11 bit übertragen (3 bit für Parameter) von einem ATMEGA 8 in C 
habe spi soweit verstanden aber komme da einfach nicht weiter? Vielen 
dank im voraus für konstruktive vorschläge.

Autor: Ziff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Schluesselwort heisst Soft SPI. Ist nicht weiter schwierig, man muss 
die Pin per Software anteuern. Gemaess Datenblatt.

Autor: Alexander Schreiber (alex130)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibts da vielleicht ein Beispiel in C will nicht copy und past machen 
aber zum verstehen würde es mir helfen? Weil auf die Idee bin ich auch 
schon gekommen aber nicht so richtig was gefunden und wenn war es nicht 
grade so nach vollziebar.

Autor: Alexander Schreiber (alex130)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe schon mal sowas versucht aber habe auch andere gefragt aber die 
sagten versuchs besser mit der SPI Schnittstelle von ATmega8 Hier der 
Code oder verstehe ich da was falsch?

#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;
}

danke für jede hilfe!

Autor: Ziff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CS=0;
for (i=0;i<11;i++){
 if ((Data && 0x01)==0x01) { DO=1; } else (DO=0;}
 SCLK=1;
 data >>= 1;
 {
CS=0;

So etwa. Kommt nun drauf an, of MSB first, oder LSB first.

Autor: Ziff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab was vergessen :

CS=0;
for (i=0;i<11;i++){
 if ((Data && 0x01)==0x01) { DO=1; } else (DO=0;}
 SCLK=1;
 data >>= 1;
 SCLK=0;
 {
CS=0;

Autor: Ziff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CS an Schluss wieder hoch : CS=1;

Autor: Alexander Schreiber (alex130)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Scheinst ja eine menge darüber zu wissen danke erst mal.
Die Pins wären da ja frei wähl paar so weit ich das verstehe CS wäre das 
Load bit data wäre für die Daten SCKL für die Clock. aber wie mache ich 
das mit dem Clock signal dies ist laut datenblatt bei 1 MHZ für den DAC 
tue ich da mit delay arbeiten da der Atmega8 an einen 3686000 MHZ quarz 
angeschlossen ist?

Aber nochmal kurz zum Hardware SPI ne andere Idee wenn ich nun 16 bit 
zum DAC schicke und nach 16 bits haufhöre schreibt der da die 5 bit am 
anfang wieder rein oder bei einem solchen fall da verhalten undefiniert?

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übrigens: Nur weil der Wandler 11Bits erwartet, heißt das nicht 
unbedingt, dass man exakt 11 Bits senden muss. Das ist ein Trugschluss!

Stell dir vor du hast ein 11-Bittiges Schieberegister und schiebst 
16Bits herein. Na, welche Bits liegen jetzt an den Ausgängen?

Meistens* läuft es so, dass die 11 letzten Bits, die du hineingeschoben 
hast bei einer fallenden/steigenden Flanke von CS die für das 
On-Chip-Processing relevanten Daten sind.
Sprich: Die Bits, die du zuerst hineingeschoben hast, sind schon wieder 
"herausgefallen".

*Ich weiß nicht, ob das bei deinem Baustein auch der Fall ist, aber ich 
könnte es mir sehr gut vorstellen.

PS: Sieh es erstmal andersherum: Wie sollte der Chip reagieren, wenn du 
mehr Bits vor dem CS hineinschiebst? In Rauch aufgehen? Wohl kaum.

Autor: Alexander Schreiber (alex130)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das habe ich ausprobiert aber die reaktion war nahe null wenn ich 16 
bits reingeschoben habe mit ensprechender +5 Bitverschiebung.
Siehe Code Master_Transmit

#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;
}

PS.: will hier keinen verärgern mit zuviel dummen fragen hoffe ihr nehmt 
mir das nich übel. Danke für jede hilfe

Autor: Ziff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn der DAC 1MBit als maximum vorsieht, kann das SPI auch langsamer 
sein. Der genannte Code wird 1MBit kaum ueberbieten, Im Loop 
wohlgemerkt.

Autor: Alexander Schreiber (alex130)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich nochmal vom Hardware SPI ausgehe und noch mal von vorne anfange 
habe mir auf seite 3 unten die Zeichnung genommen und das versucht 
nachzubauen.
Habe folgendes verbunden:

- 5 Volt spannungsquelle angeschlossen an vdd und gnd ist ein extra 
Spannungswandler mit verbindung mu mit gnd

- ref angeschlossen Spannungsquelle

- Data mit Mosi verbunden von mc

- CLK mit SCK verbunden von mc

- LOAD mit PIN2 verbunden von mc (ist im Quelltext nicht berücksichtigt 
habe aber dies auch mit bedacht in anderen Quelltext den ich jetzt nicht 
zur hand habe da auf Arbeit)

Liegt vielleicht dort der Fehler hier das Datenblatt dazu.

http://www.datasheetcatalog.com/datasheets_pdf/T/L...

danke für jede Hilfe

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich lese das Datasheet so, dass du da einfach zwei Bytes reinschieben 
kannst, MSB zuerst:
void dac_put_data(uint8_t channel, uint8_t data)
{
  spi_put_byte(channel<<1);
  spi_put_byte(data);
  CLR_LOAD();
  _delay_us(0.3); /* min. 250ns warten, 
    klappt so aber nur MIT aktivierter Optimierung */
  SET_LOAD();
}
Und LDAC einfach (erst mal) auf low lassen. Und das SPI auf "Mode 1" (s. 
AVR-Datenblatt) initialiseren.

hth. Jörg

Autor: Alexander Schreiber (alex130)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für deine Funktion sieht sehr interresant aus ich nehme die jetzt 
mal auseinander:

mit dac_channel meinst du einen der 4 Ausgänge des DAC
Frage 1.
Schiebe ich durch "spi_put_byte(channel<<1); " nur eine bestimmte anzahl 
von Bits aus der Channel Variablen raus also in dem vom DAC nur 3 Bits?

Frage 2.
"spi_put_byte(data);" ist der Parameterwert für den Ausgang des Kanals
oder?

Frage 3.
CLR_LOAD() setzte ich das Load bit auf 0 warte 0,3 us und setzte es dann 
wieder mit SET_LOAD(); aber im Datenblatt steht doch das während der 
übertragung der Load auf High sein soll und danach erst wieder auf Low?

Frage 4.
das ganze ist jetzt Hardware SPI oder?


Sorry meine Fragen aber versuche es zu verstehen und nicht einfach zu 
kopieren. Danke für deine Hilfe
mfg Alex

Autor: Jörg X. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
> spi_put_byte(channel<<1);
bedeutet dass die Nummer des DAC-Ausgange gesendet wird, aber nicht so:
> 0b 0 0 0 0 0 0 n n
sondern so
> 0b 0 0 0 0 0 n n 0
also einer (2er-)Stelle verschoben, weil das LSB ("Least Sigificant 
Byte") eine andere Bedeutung hat ("RNG"), damit man "Kanal 0" bis Kanal 
3 schreiben kann, z.B. für Arrays ;)

Ich häng dir mal an, was ich inzwischen zusammengetippt hab -> du musst 
aber auf jeden Fall die #defines in der .h-Datei überprüfen/ausfüllen

hth. Jörg

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander Schreiber wrote:
> Das habe ich ausprobiert aber die reaktion war nahe null wenn ich 16
> bits reingeschoben habe mit ensprechender +5 Bitverschiebung.

Ja, das würde mich nicht wundern:
 #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;
 }

Du musst im Master-Mode den /SS-Pin als Ausgang setzen. Außerdem hast du 
(vermute ich?) vergessen den LOAD-Ausgang als Ausgang zu setzen. Den 
Rest habe ich garnicht erst überprüft.
Btw, du steuerst den LOAD-Ausgang ja auch garnicht an!

Autor: Alexander Schreiber (alex130)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zu Simon Küppers:
will nicht fresch sein aber muss mal sagen richtig lesen aber trotzdem 
danke ich überlese auch manchmal sachen!

Autor: Alexander Schreiber (alex130)
Datum: 24.09.2007 13:50
- LOAD mit PIN2 verbunden von mc (ist im Quelltext nicht berücksichtigt
habe aber dies auch mit bedacht in anderen Quelltext den ich jetzt nicht
zur hand habe da auf Arbeit)

Mal eine zwichenfrage kommt von jemanden der mir geantwortet hat zu 
fällig jemand aus dresden?
PS danke  Jörg X. für deine mühe und deine Geduld bisher

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.