Forum: Compiler & IDEs 9 bit Nachricht bei SPI-Bus für AVR


von Florian M. (skywalker79)


Lesenswert?

Hallo,

Ich habe mal kurz zwei Fragen zum SPI-Bus bei ATMEL Controllern.

Als erstes hab ich das Problem, das meine SPI-Botschaft scheinbar nicht 
richtig abgeschlossen wird. Die MOSI-Datenleitung bleibt nach übertragen 
der Botschaft immer auf einem High-Pegel.
Wie bekomme ich es hin, das nach Ende der Botschaft, der Pegel wieder 
auf Low zurückgeht?

Das zweite Problem ist, das so standartmässig ja nur 8 bit pro Botschaft 
übertragen werden. Da ich ein digitales Poti ansprechen möchte, was 9 
bit pro Botschaft benötigt wollte ich fragen, ob es da eine einfache 
Lösung gibt, die Senderoutine umzustellen.

Hier mal mein Quellcode:

#include <avr/io.h>
#include "spi.h"

char spi_send_byte(unsigned char data)
{
  PORTB &= ~ (1<<PB0);          // CS auf Low setzen

  SPDR = poti_data;
  while (!(SPSR & (1<<SPIF)))
  ;
  poti_data_return = SPDR;

  PORTB |= (1<<PB0);           // CS auf High setzen
}



unsigned char spi_init(void)
{
  DDRB = (1<<DDB3) | (1<<DDB5) | (1<<DDB0);
  SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);
}


mit freundlichen Grüßen

Florian

von Falk (Gast)


Lesenswert?

@Florian M.

>Als erstes hab ich das Problem, das meine SPI-Botschaft scheinbar nicht
>richtig abgeschlossen wird. Die MOSI-Datenleitung bleibt nach übertragen
>der Botschaft immer auf einem High-Pegel.
>Wie bekomme ich es hin, das nach Ende der Botschaft, der Pegel wieder
>auf Low zurückgeht?

Wahrscheinlich nur, wenn das letzte Bit eine Null ist.

>Das zweite Problem ist, das so standartmässig ja nur 8 bit pro Botschaft
>übertragen werden. Da ich ein digitales Poti ansprechen möchte, was 9
>bit pro Botschaft benötigt wollte ich fragen, ob es da eine einfache
>Lösung gibt, die Senderoutine umzustellen.

Du musst die SPI in Software machen. Ist nicht weiter schwierig und 
immer noch ziemlich schnell.

MFG
Falk

von Wolfram (Gast)


Lesenswert?

>Das zweite Problem ist, das so standartmässig ja nur 8 bit pro Botschaft
>übertragen werden.
Wie wärs wenn du 2 mal 8 Bit sendest.

von Falk (Gast)


Lesenswert?

@Wolfram

>>Das zweite Problem ist, das so standartmässig ja nur 8 bit pro Botschaft
>>übertragen werden.

>Wie wärs wenn du 2 mal 8 Bit sendest.

Dann bekommt der digitale Poti auch 16 SCK Takte. Ob er das mag?

MFG
Falk



von Florian M. (skywalker79)


Lesenswert?

Hallo,

Danke für den Hinweis mit dem Software SPI. Das werde ich jetzt erstmal 
ausprobieren.
Mit dem versenden von 2 mal 8 bit wird, denk ich mal nicht so einfach 
gehen, da das Poti ja nur 9 bit und nicht insgesamt 16 bit erwartet.

Mfg Florian

von Wolfram (Gast)


Lesenswert?

>Mit dem versenden von 2 mal 8 bit wird, denk ich mal nicht so einfach
>gehen, da das Poti ja nur 9 bit und nicht insgesamt 16 bit erwartet.

Das Poti hat ein Schieberegister dessen Inhalt bei CS Disable übernommen 
wird.
Nicht denken, Datenblätter und SPI spec lesen.

von Florian M. (skywalker79)


Lesenswert?

Hallo,

Also danke erstmal an Wolfram, für den Hinweis. Ich spreche das Poti 
jetzt durch zwei Nachrichten hintereinander an und es lässt sich 
verstellen.
Jetzt habe ich nur leider noch das Problem, das ich nur einmal einen 
Aufruf  spi_send() starten kann. danach hängt sich der Controller 
irgendwie auf.
Die Senderoutine und die Initialisierung habe ich aus dem Datenblatt für 
den Controller. Kann mir einer von euch sagen, wo der Fehler sein kann?

#include <avr/io.h>
#include <stdlib.h>
#include "spi.h"

unsigned char spi_init(void)
{
  DDRB = (1<<DDB3) | (1<<DDB5) | (1<<DDB0);
  SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);
}

char spi_send(unsigned char poti_adress, unsigned char poti_data)
{
  PORTB &= ~ (1<<PB0);         // CS auf Low setzen
  SPDR = poti_adress;
    while (!(SPSR & (1<<SPIF)))
    {
    ;
  }
  SPDR = poti_data;
    while (!(SPSR & (1<<SPIF)))
    {
    ;
  }
    poti_data_return = SPDR;
  PORTB |= (1<<PB0);           // CS auf High setzen
}

mfg Florian

von Wolfram (Gast)


Lesenswert?

Schau nochmal ins Datenblatt,
am AVR hast du MISO,MOSI,SCK,SS (SS benutzt du nicht da nicht Slave 
richtig?)
wenn SS aber auf low geht schaltet der AVR automatisch von SPI-Master 
auf Slave, also SS auf Output setzen.

von Florian M. (skywalker79)


Lesenswert?

Danke, das war das Problem.
Jetzt Funktioniert alles so wie es soll.

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.