Soft SPI Problem

OP #4414522
Hallo zusammen

Ich habe ein Soft SPI und möchte 9 Bit übertragen, stehe jedoch auf dem 
Schlauch bei dem Problem.

Hier der Code:
1
#define SPI_CLK                 PB5
2
#define SPI_DATA                PB3
3

4
#define HIGH                    1
5
#define LOW                     0
6

7

8
void softspi(unsigned int data)
9
{
10
    unsigned int i=0;
11

12
  SPI_CLK = LOW;            //CS=low übertragung anfang
13
  for (i=9;i<0;i--)
14

15
    {
16

17
    SPI_CLK = LOW; //clock low
18

19
    if (data  & 0x1FF){      /* Wenn MSB-Bit gesetzt     */
20
      SPI_DATA = HIGH;      /* Data-Pin auf 1 schalten, */
21
    }
22
    else{
23
      SPI_DATA = LOW;      /* ansonsten auf 0          */
24
    }
25
    data = data << 1;
26

27
    SPI_CLK = HIGH; //Clock bit rising edge
28

29
    }
30

31
  SPI_CLK = HIGH; //CS high, übertragung beendet
32
}

error: lvalue required as left operand of assignment

Dies kommt mir bei jeder Zuweisung von SPI_CLK oder SPI_DATA.

Kann mir jemand eine Lösung sagen?

MfG und danke
Konstanten kann man keine Werte zuweisen, schau Dir mal die Makros PB3 
und PB5 genauer an.

So gehts:
1
PORTB &= ~(1<<SPI_CLK); 
2

3
if (data  & 0x100){      /* Wenn MSB-Bit gesetzt     */
4
      PORTB |= (1<<SPI_DATA);      /* Data-Pin auf 1 schalten, */
5
  }
TM F. schrieb:
> Dies kommt mir bei jeder Zuweisung von SPI_CLK oder SPI_DATA.
>
> Kann mir jemand eine Lösung sagen?
Ist verständlich. Du versuchst dein #define zu überschreiben.
Mach es anders:
1
#define SPI_CLK_LOW()                 (PORTB &= ~(1<<PB5))
2
#define SPI_CLK_HIGH()                (PORTB |= (1<<PB5))
3

4
#define SPI_DATA_LOW()                 (PORTB &= ~(1<<PB3))
5
#define SPI_DATA_HIGH()                (PORTB |= (1<<PB3))

und nutze diese #defines
@ TM FW (p_richner)


>Ich habe ein Soft SPI und möchte 9 Bit übertragen, stehe jedoch auf dem
>Schlauch bei dem Problem.

Hmm

>error: lvalue required as left operand of assignment

Linkswert als linker operand einer Zuweisung benötigt.

>Dies kommt mir bei jeder Zuweisung von SPI_CLK oder SPI_DATA.

Logisch.

>Kann mir jemand eine Lösung sagen?

Eher so.

PORTB |= (1<<SPI_CLK);

Siehe Bitmanipulation.

>    if (data  & 0x1FF){      /* Wenn MSB-Bit gesetzt     */
>      SPI_DATA = HIGH;      /* Data-Pin auf 1 schalten, */
>    }

Darüber würde ich auch nochmal nachdenken.

>  SPI_CLK = HIGH; //CS high, übertragung beendet

NÖ. CS ist nich CLK, das ist ein extra Signal.
Hallo,

ich bin nicht der Spuer-C-Spezi, aber welche Lösung wäre Dir angenehm?
a) befasse Dich mit den Grundlagen von C, mit dem Präprozessor und was 
noch dazugehört.

b) #define SPI_CLK                 PB5
bearbeitet der Präprozessor, das ist also eine reine Textersetzung.
Überall, wo SPI_CLK im Code auftaucht, wird es durch PB5 ersetzt.
Also z.B. hier:
aus   SPI_CLK = LOW;            //CS=low übertragung anfang
wird  PB5 = 0
Das LOW wird ja auch ersetzt.
Dummerweise ist PB5 aber auch schon ein #define in den 
AVR-Standard-Includes,
es wird duchr die Bitnummer ersetzt, hier also 5.

Somit bekommr der Compiler also 5 = 0 vor die Füße geworfen und darüber 
beklagt er sich, er will zu Recht links eine Variable haben.

Was Du willst ist, daß in PortB das Bit 5 auf Low gesetzt wird.
Also PORTB = PORTB & ~(1<<SPI_CLOCK).
Meist verküzt geschreiben, also PORTB &= ~(1<<SPI_CLOCK).
Was passiert hier? Es wird der Inhalt von PortB eingelesen.
Es wird eine Byte-Maske erzeugt, die eine 1 um 5 Positionen nach links 
verschoben enthält, also 0b00100000.
Diese Maske wird invertiert, also zu 0b11011111.
Dann wird die Maske mit dem eingelesenen Byte von PortB AND verknüpft, 
also alles außer Bit 5 bleibt wie es ist, nur Bit 5 wird zu 0.
Das Ergebnis wird dann an PortB ausgegeben.

Warum diese Umstände? Es soll ja nur Bit5 in PortB geändert werden, 
alles andere muß erhalten bleiben.

Der Compiler wird beim Optimieren sehr wahrscheinlich ein cbi portb,5 
draus machen.

Das muß aber der Compiler entscheiden, nicht jeder µC kennt diesen 
Befehl und der C-Compiler kann ja je nach Angabe für etliche 
verschiedene Controller benutzt werden.

Gruß aus Berlin
Michael
Wenn du jetzt noch sagst, wann ein unsigned integer kleiner als 0 wird, 
weißt du auch, wann deine Schleife abgebrochen wird.

Das Problem ist, i wird, wenn es auf 0 steht und du das nächste mal eins 
abziehst nicht etwa -1 (da ja unsigned), sondern 65535 werden...

Antwort schreiben

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