mikrocontroller.net

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


Autor: Florian M. (skywalker79)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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



Autor: Florian M. (skywalker79)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Florian M. (skywalker79)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Florian M. (skywalker79)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, das war das Problem.
Jetzt Funktioniert alles so wie es soll.

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.