mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Soft SPI


Autor: Sven Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich will einen DAC ansteuern (MAX528) dieser verfügt über ein SPI
Interface.

Ich habe ihn noch nicht hier, möchte aber schon etwas Software
vorbereiten.

Als uC kommt ein Mega 16 (später 8) zum Einsatz.

den eingebauten SPI will ich nicht nutzen, da ich ihn beliebig an einen
Port anschließen will.
Darum habe ich mir gedacht eine Funktion zu schreiben.

klappt das so? oder soll ich doch den eingebauten benutzen? Nutzt der
eingebaute das SS Signal als CS?

Danke schonmal, hier der Code:

void softspi(unsigned int data)

{

unsigned int i=0;

            PORTD.1=0; //CS=low übertragung anfang



            for (i=16;i<0;i--)

                        {

                        PORTD.2=0; //clock low

                        PORTD.3 = data & (1<<i);

                        PORTD.2 = 1; //Clock bit rising edge

                        }

            PORTD.1=1; //CS high, übertragung beendet

return;



}

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Sven,
so sieht man sich wieder ;-))

Zwei Punkte würde ich ändern:
Die Portnamen per #define in den Header schreiben. Dann musst Du nicht
jedesmal das ganze Programm ändern, wenn Du die Portpins wirklich
tauschen willst.

PORTD.3 = data & (1<<i);
Hier musst Du bei jedem Bit bis zu 16* schieben. Fixer geht es so:

if (data & 1){
  PIN_SPI_DATA = 1;
else{
  PIN_SPI_DATA = 0;
}
data = data >> 1;

Sieht zwar länger aus, ist aber im Programmcode kürzer und schneller.
Wenn es ganz optimal sein soll, dann kannst Du i auch noch als 8 Bit
definieren.

Den eingebauten musst Du nur benutzen, wenn Du die Geschwindigkeit
wirklich brauchst.

Viele Grüße, Stefan

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P.S.:
Ich habe es frei runtergeschrieben, ohne zu testen. Also betrachte es
kritisch ;-)

Stefan

Autor: Sven Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

Dann war meine Idee doch nicht so falsch..

Aber dein Programm verstehe ich nicht ganz..
Du prüfst ja erst ob das lsb von data =1 ist shiftest dann rechts dann
bist du doch beim MSB??
Ich meine doch das MSB muss zuerst rein...
Data besteht bei mir aus adresse + wert

vielleicht erklärst du mir deine optimierung noch etwas. Danke.

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry. War von LSB first ausgegangen. Ich ahbe aber auch kein Datenblatt
angeschaut :-(

Mit MSB first muss es so aussehen:

if (data & 0x8000){      /* Wenn MSB-Bit gesetzt     */
  PIN_SPI_DATA = 1;      /* Data-Pin auf 1 schalten, */
else{
  PIN_SPI_DATA = 0;      /* ansonsten auf 0          */
}
data = data << 1;        /* das Ganze nach Links schieben, dann    */
                         /* ist das MSB-1 beim nächstenmal das MSB */
                         /* Das geht solange (16*), bis das LSB    */
                         /* nach links als MSB aufgerückt ist      */

Insgesamt wird 16* geshiftet. Bei Dir sinds pro 16Bit-Ausgabe 128*
Ist aber im Prinzip auch kein Problem.

Viel wichtiger finde ich die symbolische Darstellung der Portpins.
PIN_SPI_DATA (oder ähnlich) ist auch ohne Kommentar klar, bei PORTD.3
weisst Du in 14 Tagen nicht mehr, was es soll, ohne im Schaltplan zu
schauen.

Stefan

Autor: Sven Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
JA, mit dem benennen hast du recht. habe es auch schon geändert..

Also packe ich deinen Code in die for schleife. schalte vorher und
nachher die clock um..muss man warten? oder kann ich das so laufen
lassen?

Ich verstehe das Datenblatt zumindest so das zuerst das MSB kommt.. ist
etwas knapp gehalten..

Danke schonmal. Sven

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Also packe ich deinen Code in die for schleife. schalte vorher und
>nachher die clock um..muss man warten? oder kann ich das so laufen
>lassen?

Im Datenblatt steht je 80ns für Low- und High-Clock. Die wirst Du nicht
unterschreiten, denke ich. Dazu müssten die Assembler-Befehle zum
setzen und löschen von clk direkt hintereinander kommen.

>Ich verstehe das Datenblatt zumindest so das zuerst das MSB kommt..
ist
>etwas knapp gehalten..

Hast Du völlig Recht. Ich habe einfach nicht geschaut.
Es gibt aber schlimmere Datenblätter ... vor allem bei Chips aus Japan.
Die scheinen ganz anders zu denken ;-)

Stefan

Autor: Sven Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut, dank dir. Dann geh ich jetzt beruhigt schlafen..

Sven

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ob optimal, weiss ich nicht, jedenfalls funktionierts prima mit einem
2313/MAX528 und MAX192 an einem Software-SPI.

void write_spi (unsigned char data_out){       //msb first
unsigned char loop, mask;
for (loop=0,mask=0x80;loop<8;loop++, mask=mask>>1)
    {sclk=0;
    if (data_out & mask) mosi=1;
     else mosi=0;
     sclk=1;
    }
sclk=0;
}

void write_max528 (unsigned char adress, unsigned char data){
dac_cs=0;
write_spi(adress);
write_spi(data);
dac_cs=1;
watchdog=0;
}

Autor: Sven Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, das Beispiel von crazy scheint mir der optimale, praktische Weg zu
sein. danke dir!

Sven

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Ccrazy horse:
Sieht hübsch aus, und weil es nur mit 8-Bit-Werten rechnet, ist es
sicher sehr nah am Optimum.

for (loop=0,mask=0x80;loop<8;loop++, mask=mask>>1)

Erstmal war ich in dieser Zeile etwas irritiert: das Komma in der
for-Schleife hat mich stutzig gemacht, also habe ich mal bei K&R
nachgeschaut: Es gibt einen Komma-Operator!

Wieder was gelernt, danke.

Stefan

Autor: Sven Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, mit dem Komma das kannte ich auch noch nicht..

werds mal ausprobieren wenn die samples da sind..

Sven

Autor: Roman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
crazy horse, danke! :) ich blicke bei der for schleife nicht ganz durch 
aber es funzt!

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.