SPI selbst generieren

Gast #158363
Hi

Folgendes ich arbeite mit dem ATMEGA128 und benutze das SPI.
Nun benötige ich aber zum programmieren eines DAC eine weitere SPI
Schnittstelle. Da ich hier immer nur 16 Bit an Daten an den DAC
schicken muss nehm ich also 3 I/Os - eine CLK, ein CS und ein DataOut.
Soweit so gut aber irgendwie krieg ich die 16 Bit nicht einzeln auf den
DataOut Pin, bzw. rausgeschiftet.
Arbeite zudem mit CVAVR also wenn dann in C bidde.
 dachte eigentlich es würde so funktionieren:

#define SDOUT PORTB.7

...

unsigned char control;

for(j=0;j<8;j++)
{
   ...
   SDOUT= (control>>(7-j));
   ...
}
...

Schonmal danke im vorraus.
Gast
Ein Codefragment. Vielleicht hilft's:

void softspi_W(uint8_t data)
{
  uint8_t i;
  i = 0x80;
  do {
    if (data & i) SPIPORT |= (1<<SPIMOSI);
    else SPIPORT &= ~(1<<SPIMOSI);
    pulse_sck();
    i>>=1;
  } while (i);
}
Gast
In Deiner Schleife shiftest Du einerseits nur ein Byte, andererseits
solltest Du -sicherheitshalber- noch eine verANDung mit 1 vornehmen:

   SDOUT= (control>>(7-j)) & 1;

Mit Takt könnte das dann so aussehen:

#define SDOUT PORTB.7
#define CLOCK PORTB.6
#define CHIPSEL PORTB.5
...

unsigned char control;

CHIPSEL = 0;  // active-Low-CS

for (j = 0; j < 8; j++)
{
   ...
   CLOCK = 0;
   SDOUT = (control >> (7 - j)) & 1;
   CLOCK = 1;
   ...
}

CHIPSEL = 1;
..

Du musst Dir noch Gedanken über die Polarität des Taktsignales machen
und wann in Relation zu den Daten das Taktsignal umschalten soll.
Außerdem musst Du überlegen, ob Du das LSB (wie in Deinem Quelltext)
oder das MSB als erstes übertragen willst; es gibt beide Varianten.

Wie hier vor einiger Zeit bereits diskutiert wurde, ist das Konstrukt
mit dem Shiftoperator ein relativ ineffizientes, da der AVR über keinen
sog. "Barrel Shifter" verfügt.

Besser wäre daher eine Variante wie


unsigned char control;
unsigned char temp;


temp = control;

CHIPSEL = 0;  // active-Low-CS

for (j = 0; j < 8; j++)
{
   ...
   CLOCK = 0;
   SDOUT = temp & 1;
   temp >>= 1;  // oder temp /= 2;
   CLOCK = 1;
   ...
}

CHIPSEL = 1;
Gast
Nachtrag:
Das ganze für 16-Bit-SPI:


unsigned short control;
unsigned short temp;


temp = control;

CHIPSEL = 0;  // active-Low-CS

for (j = 0; j < 16; j++)
{
   ...
   CLOCK = 0;
   SDOUT = temp & 1;
   temp >>= 1;  // oder temp /= 2;
   CLOCK = 1;
   ...
}

CHIPSEL = 1;
Gast
Das ich nur ein Byte shifte und somit nur 8 Bit und nicht 16 war mir
schon klar. Und ob bei steigender oder fallender Flanke übernomen
werden soll auch, deshalb ja die vielen ... "pünktchen" ;-)
Wollte nur nicht den ganzen Code posten.

Das einzige was mir theoretisach fehlte war die Ausmaskierung mit & 1
Und ein wenig umgestrickt damit ich das MSB zuerst sende und nicht das
LSB sieht das ganze jetzt so aus und funzt auch:

void WriteDAC(unsigned char control, unsigned char wert)
{
unsigned char j= 0;
unsigned char temp_control, temp_wert;

cs = 0;  // active-Low-CS

for (j=0;j<16;j++)
{
   sclk = 1;
   if(j<8)
   {
        temp_control = control;
        temp_control >>= (7-j);
        sdin = temp_control & 1;

   }
   else
   {
        temp_wert= wert;
        temp_wert >>= (15-j);
        sdin = temp_wert & 1;
   }
   sclk = 0;
}

cs = 1;
}


In diesem Sinne dankeschön für die Mühe

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.