www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI selbst generieren


Autor: Jason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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);
}

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;

Autor: Jason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

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.