Forum: Mikrocontroller und Digitale Elektronik Soft SPI 24 Bit


von Steffen (Gast)


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?
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);

von Jim M. (turboj)


Lesenswert?

Darüber solltest Du nochmal nachdenken:
1
if (data&0x7FFFFF)

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

von Trumpelstielzchen (Gast)


Lesenswert?

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

von Dr. Sommer (Gast)


Lesenswert?

Steffen schrieb:
> if (data&0x7FFFFF)

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

von Dr. Sommer (Gast)


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...

von Steffen (Gast)


Lesenswert?

Dr. Sommer schrieb:
> 0x800000

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

von eProfi (Gast)


Lesenswert?

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?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.