Soft SPI 24 Bit

Gast #5022926
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?
1
uint32_t spi_tx(uint32_t data)
2
{  unsigned char i;
3

4
  cbi(spi_PORT, CS);
5
  for (i=0; i<24; i++)
6
  {
7
    if (data&0x7FFFFF)
8
    sbi(spi_PORT, SDI);
9
    else
10
    cbi(spi_PORT, SDI);
11
    data<<=1;
12
    sbi(spi_PORT, SCK);
13
    asm("nop");
14
    asm("nop");
15
    cbi(spi_PORT, SCK);
16
  }
17
  sbi(spi_PORT, CS);
18
  return data;
19
}

Aufrufen tu ich das ganze mit:
1
spi_tx(0x30FE00);
Gast #5022934
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...
Gast #5023057
1
void spi_tx(uint32_t data){
2
  uint32_t mask=0x800000;
3
  cbi(spi_PORT, CS);
4
  do{
5
    if(data&mask)sbi(spi_PORT, SDI);
6
    else         cbi(spi_PORT, SDI);
7
    sbi(spi_PORT, SCK);
8
    asm("nop");asm("nop");
9
    cbi(spi_PORT, SCK);
10
  }while((mask>>=1)!=0);
11
  sbi(spi_PORT, CS);
12
}
13

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

17
union{
18
  uint32_t d32;
19
  uint8_t  d08[4];
20
} u;
21

22
void spi_tx(uint32_t data){
23
  uint8_t mask=0x80; u.d32=data;
24
  cbi(spi_PORT, CS);
25
  do{
26
    if(u.d08[2]&mask)sbi(spi_PORT, SDI);
27
    else             cbi(spi_PORT, SDI);
28
    sbi(spi_PORT, SCK);
29
    asm("nop");asm("nop");
30
    cbi(spi_PORT, SCK);
31
  }while((mask>>=1)!=0);
32

33
  mask=0x80; do{
34
    if(u.d08[1]&mask)sbi(spi_PORT, SDI);
35
    else             cbi(spi_PORT, SDI);
36
    sbi(spi_PORT, SCK);
37
    asm("nop");asm("nop");
38
    cbi(spi_PORT, SCK);
39
  }while((mask>>=1)!=0);
40

41
  mask=0x80; do{
42
    if(u.d08[0]&mask)sbi(spi_PORT, SDI);
43
    else             cbi(spi_PORT, SDI);
44
    sbi(spi_PORT, SCK);
45
    asm("nop");asm("nop");
46
    cbi(spi_PORT, SCK);
47
  }while((mask>>=1)!=0);
48
  sbi(spi_PORT, CS);
49
}

Warum gibst Du data wieder mit return zurück?

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 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.