mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Soft SPI 24 Bit


Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich bin eben am verzewifeln 24bit am Stück per SPI zu übertragen. Dazu 
habe habe ich folgenden SoftSPI genutzt. Es geht bis 16bit ohne 
Probleme, dann eher nicht mehr. Ich nutze zum Senden einen Tiny85. Der 
Empfänger der Daten ist ein DAC, der aber nur einen DI, SCK und CS 
Eingang hat. d.h. DO oder MISO gibt es nicht.

Wo liegt mein Fehler?
uint32_t spi_tx(uint32_t data)
{  unsigned char i;

  cbi(spi_PORT, CS);
  for (i=0; i<24; i++)
  {
    if (data&0x7FFFFF)
    sbi(spi_PORT, SDI);
    else
    cbi(spi_PORT, SDI);
    data<<=1;
    sbi(spi_PORT, SCK);
    asm("nop");
    asm("nop");
    cbi(spi_PORT, SCK);
  }
  sbi(spi_PORT, CS);
  return data;
}

Aufrufen tu ich das ganze mit:
spi_tx(0x30FE00);

Autor: Jim M. (turboj)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Darüber solltest Du nochmal nachdenken:
if (data&0x7FFFFF)

Hint: In C ist true alles was ungleich 0 (Null) ist.

Autor: Trumpelstielzchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Steffen schrieb:
> if (data&0x7FFFFF)
soll vermutlich heißen
if (data&0x800000)

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Steffen schrieb:
> if (data&0x7FFFFF)

Was soll das denn und wie soll das mit 16 Bit funktionieren?? Mit 
0x800000 sollte es besser gehen...

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Steffen schrieb:
> data<<=1;

PS: Eventuell kann der Compiler das besser optimieren wenn du 
stattdessen
data = (data << 1) & 0xFFFFFF;
und am Anfang der Funktion einmal:
data = data & 0xFFFFFF;
schreibst. Probier das mal aus, ob da die unnötige Berechnung des 4. 
Registers verschwindet...

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dr. Sommer schrieb:
> 0x800000

jo das war es... vielen Dank :-)

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void spi_tx(uint32_t data){
  uint32_t mask=0x800000;
  cbi(spi_PORT, CS);
  do{
    if(data&mask)sbi(spi_PORT, SDI);
    else         cbi(spi_PORT, SDI);
    sbi(spi_PORT, SCK);
    asm("nop");asm("nop");
    cbi(spi_PORT, SCK);
  }while((mask>>=1)!=0);
  sbi(spi_PORT, CS);
}

Oder noch besser jedes Byte einzeln rausschieben,
dann muss man nicht jedes mal jedes Mal 4 Bytes schieben.

union{
  uint32_t d32;
  uint8_t  d08[4];
} u;

void spi_tx(uint32_t data){
  uint8_t mask=0x80; u.d32=data;
  cbi(spi_PORT, CS);
  do{
    if(u.d08[2]&mask)sbi(spi_PORT, SDI);
    else             cbi(spi_PORT, SDI);
    sbi(spi_PORT, SCK);
    asm("nop");asm("nop");
    cbi(spi_PORT, SCK);
  }while((mask>>=1)!=0);

  mask=0x80; do{
    if(u.d08[1]&mask)sbi(spi_PORT, SDI);
    else             cbi(spi_PORT, SDI);
    sbi(spi_PORT, SCK);
    asm("nop");asm("nop");
    cbi(spi_PORT, SCK);
  }while((mask>>=1)!=0);

  mask=0x80; do{
    if(u.d08[0]&mask)sbi(spi_PORT, SDI);
    else             cbi(spi_PORT, SDI);
    sbi(spi_PORT, SCK);
    asm("nop");asm("nop");
    cbi(spi_PORT, SCK);
  }while((mask>>=1)!=0);
  sbi(spi_PORT, CS);
}

Warum gibst Du data wieder mit return zurück?

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.