mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Hardware SPI Fragen


Autor: Paul F. (zwanzischmark)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
ich habe versucht möglichst viele der 16 Seiten mit SPI Themen zu lesen 
und habe dort auch einige Seiten gefunden wo SPI allgemein gut erklärt 
ist, aber mir fehlt noch immer ein gut erklärtes C-Programmbeispiel.

Aus dem Datenblatt habe ich den folgenden code:
(nur die Zeile "DDRB = (1<<PB5)|(1<<PB7);" angepasst)

ATMEGA 644P
void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDRB = (1<<PB5)|(1<<PB7);
/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

void SPI_MasterTransmit(char cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)));
}

also rufe ich einmal
SPI_MasterInit();
 zum initialisieren des Hardware SPI auf und kann dann mit z.B.
SPI_MasterTransmit(0xFF);
 ein byte senden.
Ist das korrekt soweit?

der Slave richtet sich nach dem Takt den der Master vorgibt?

der Master gibt die Daten auch aus wenn nichts angeschlossen ist?

Autor: Paul F. (zwanzischmark)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so, ich füge jetzt mal den code von master und slave an, vielleicht 
schaut mal einer drüber:

Master:
#include <avr/io.h>
#include <util/delay.h>

void SPI_MasterInit(void) {
  /* Set MOSI and SCK output, all others input */
  DDRB = (1<<PB5)|(1<<PB7);
  /* Enable SPI, Master, set clock rate fck/16 */
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

void SPI_MasterTransmit(char cData) {
  /* Start transmission */
  SPDR = cData;
  /* Wait for transmission complete */
  while(!(SPSR & (1<<SPIF)));
}

int main (void) {

  SPI_MasterInit();
  while(1) {
    SPI_MasterTransmit(0xFF);
    _delay_ms(200);
    SPI_MasterTransmit(0x00);
    _delay_ms(200);
  }

  return 0;
}


Slave:
#include <avr/io.h>
#include <util/delay.h>

void SPI_SlaveInit(void) {
  /* Set MISO output, all others input */
  DDRB = (1<<PB6);
  /* Enable SPI */
  SPCR = (1<<SPE);
}


char SPI_SlaveReceive(void) {
  /* Wait for reception complete */
  while(!(SPSR & (1<<SPIF)));
  /* Return Data Register */
  return SPDR;
}


int main (void) {

  DDRD = 0xFF;
  SPI_SlaveInit();
  while(1) {
    PORTD = SPI_SlaveReceive();
  }
  return 0;
}

Autor: JÜrgen Grieshofer (Firma: 4CKnowLedge) (psicom) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du das Kapitel über /SS gelesen?

Autor: Paul F. (zwanzischmark)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, sorry... hatte ich nicht erwähnt, /SS hab ich am Slave einfach an 
GND gelegt, oder ist /SS zwingend erforderlich zur syncronisation?

Es soll ja einfach PortD am Slave im 200ms Abstand getoggelt werden. 
Dazu hab ich natürlich simplerweise eine LED dran. Die LED geht auch an, 
allerdings nicht mehr aus!

Sind denn die Programme so richtig?

Autor: Udo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wenn du in der Senderoutine 2 Byte sendest, solltest du auch 2x die 
Bytes auslesen:
int main (void) {

  DDRD = 0xFF;
  SPI_SlaveInit();
  while(1) {
    PORTD = SPI_SlaveReceive();
    _delay_ms(200);
    PORTD = SPI_SlaveReceive();
  }
  return 0;
}


Gruß
Udo

Autor: Paul F. (zwanzischmark)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm? ist doch in ner Schleife, also wird ständig ausgelesen...

ist ja nur ein testprogramm...

komischerweise geht es jetzt, obwohl ich nichts geändert hab :/

Autor: Udo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups, sorry, hab die Schleife überlesen.....

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.