Hardware SPI Fragen

OP #815259
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
1
void SPI_MasterInit(void)
2
{
3
/* Set MOSI and SCK output, all others input */
4
DDRB = (1<<PB5)|(1<<PB7);
5
/* Enable SPI, Master, set clock rate fck/16 */
6
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
7
}
8

9
void SPI_MasterTransmit(char cData)
10
{
11
/* Start transmission */
12
SPDR = cData;
13
/* Wait for transmission complete */
14
while(!(SPSR & (1<<SPIF)));
15
}

also rufe ich einmal
1
SPI_MasterInit();
 zum initialisieren des Hardware SPI auf und kann dann mit z.B.
1
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?
OP #815334
Lesenswert?

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

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

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

11
void SPI_MasterTransmit(char cData) {
12
  /* Start transmission */
13
  SPDR = cData;
14
  /* Wait for transmission complete */
15
  while(!(SPSR & (1<<SPIF)));
16
}
17

18
int main (void) {
19

20
  SPI_MasterInit();
21
  while(1) {
22
    SPI_MasterTransmit(0xFF);
23
    _delay_ms(200);
24
    SPI_MasterTransmit(0x00);
25
    _delay_ms(200);
26
  }
27

28
  return 0;
29
}


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

4
void SPI_SlaveInit(void) {
5
  /* Set MISO output, all others input */
6
  DDRB = (1<<PB6);
7
  /* Enable SPI */
8
  SPCR = (1<<SPE);
9
}
10

11

12
char SPI_SlaveReceive(void) {
13
  /* Wait for reception complete */
14
  while(!(SPSR & (1<<SPIF)));
15
  /* Return Data Register */
16
  return SPDR;
17
}
18

19

20
int main (void) {
21

22
  DDRD = 0xFF;
23
  SPI_SlaveInit();
24
  while(1) {
25
    PORTD = SPI_SlaveReceive();
26
  }
27
  return 0;
28
}
OP #815464
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?
Gast #815527
Lesenswert?

Hallo,

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

3
  DDRD = 0xFF;
4
  SPI_SlaveInit();
5
  while(1) {
6
    PORTD = SPI_SlaveReceive();
7
    _delay_ms(200);
8
    PORTD = SPI_SlaveReceive();
9
  }
10
  return 0;
11
}

Gruß
Udo

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren