SPI - uC "empfängt" nur ein bestimmtes Byte

Gast #646030
Lesenswert?
• ▲
▼
Es sind zwei uCs miteinander verbunden (MOSI - MOSI, MISO - MISO).

Der Mega16 läuft als Master. Der Mega8 als Slave. Ein Programmchen soll 
zum Testen ein Byte '0b00110011' an den Slave schicken. Das Problem ist, 
dass ich immer nur '0bxx110101' im SPDR habe. Was an den zwei Bits xx 
steht, weiß ich nicht, da ich nur an den Pins PC0 bis PC5 den Pegel 
messen kann.

Selbst wenn der Master gar nichts gesendet hat (also direkt nach dem 
Reset) und ich den SPDR auslese, bekomme ich dieses komische Byte. Wenn 
der Master etwas sendet, ändert sich auch nichts.

Hier der Quellcode beider Programme. Die SPI-Routinen habe ich aus dem 
Datenblatt übernommen.

SLAVE
1
// SLAVE-PROGRAMM
2
#include <avr/io.h>
3

4
#define  led_1    PD6
5
#define button_1  PIND3
6

7
int main(void) {
8

9
  DDRD |= (1<<led_1);
10
  DDRC |= 0b00111111;
11
  SPI_SlaveInit();
12
    
13
  while(1) {
14

15
    if(but() == 1) {      //Sobald Taster (PD3) gedrückt,
16
      PORTD |= (1<<led_1);  //Kontroll-LED einschalten und
17
      PORTC = SPDR;      //SPDR nach PORTC schreiben.
18

19
    } else {
20
      PORTD &= ~(1<<led_1);  //Kontroll-LED aus
21
    }  
22
  }
23

24
  return 0;
25
}
26

27
int but(void) {      //Liefert '1', wenn PD3 == true
28
  
29
  int tmp;
30

31
  if(PIND & (1 <<button_1)) {
32
    tmp = 1;
33
  } else {
34
    tmp = 0;
35
  }
36

37
  return tmp;
38
}
39

40
void SPI_SlaveInit(void)
41
{
42
  /* Set MISO output, all others input */
43
  DDRB = (1<<PB4);
44

45
  /* Enable SPI */
46
  SPCR = (1<<SPE);
47
}
48

49
char SPI_SlaveReceive(void)
50
{
51
  /* Wait for reception complete */
52
  while(!(SPSR & (1<<SPIF)));
53

54
  /* Return data register */
55
  return SPDR;
56
}

MASTER
1
//MASTER-PROGRAMM
2
#include <avr/io.h>
3

4
#define  led_1    PD5
5
#define button_1  PIND2
6

7
int main(void) {
8

9
  DDRD |= (1<<led_1);
10
  DDRB |= (1<<PB4);    //SS Leitung
11
  SPI_MasterInit();
12
    
13
  while(1) {
14

15
    if(but() == 1) {          //Wenn Taster (PD2) gedrückt,
16
      PORTD |= (1<<led_1);      //Kontroll-LED einschalten.
17
      PORTB |= (1<<PB4);        //SS-Leitung auf 'high',
18
      SPI_MasterTransmit(0b00110011);  //Test-Byte senden und
19
      PORTB &= ~(1<<PB4);        //SS-Leitung wieder auf 'low'.
20

21
    } else {
22
      PORTD &= ~(1<<led_1);    //Kontroll-LED aus.
23
    }  
24
  }
25

26
  return 0;
27
}
28

29
int but(void) {      //Liefert '1', falls PD2 == true
30
  
31
  int tmp;
32

33
  if(PIND & (1 <<button_1)) {
34
    tmp = 1;
35
  } else {
36
    tmp = 0;
37
  }
38

39
  return tmp;
40
}
41

42
void SPI_MasterInit(void)
43
{
44
  /* Set MOSI and SCK output, all others input */
45
  DDRB |= (1<<PB5)|(1<<PB7);
46

47
  /* Enable SPI, Master, set clock rate fck/16 */
48
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
49
}
50

51
void SPI_MasterTransmit(char cData)
52
{
53
  /* Start transmission */
54
  SPDR = cData;
55

56
  /* Wait for transmission complete */
57
  while(!(SPSR & (1<<SPIF)));
58
}
Gast #646051
Lesenswert?
• ▲
▼
>Selbst wenn der Master gar nichts gesendet hat (also direkt nach dem
>Reset) und ich den SPDR auslese, bekomme ich dieses komische Byte.

Das liegt wohl daran das du nichts empfangen hast ;)

SLAVE
Wo benutzt du SPI_SlaveReceive(void) ?

MASTER
Vieleicht doch besser so:

      PORTB &= ~(1<<PB4);        //SS-Leitung wieder auf 'low'.
      SPI_MasterTransmit(0b00110011);  //Test-Byte senden und
      PORTB |= (1<<PB4);        //SS-Leitung auf 'high',
Gast #646082
Lesenswert?
• ▲
▼
>SLAVE
>Wo benutzt du SPI_SlaveReceive(void) ?
>
>MASTER
>Vieleicht doch besser so:
>
>      PORTB &= ~(1<<PB4);        //SS-Leitung wieder auf 'low'.
>      SPI_MasterTransmit(0b00110011);  //Test-Byte senden und
>      PORTB |= (1<<PB4);        //SS-Leitung auf 'high',

Aha, danke! Jetzt geht es.
Gast #678833
Lesenswert?
• ▲
▼
eine verständnisfrage zu diesem spi-slave-beispiel , wie kommt der 
anwender zu dieser routine : char SPI_SlaveReceive(void) , ich sehe kein 
aufruf?

// SLAVE-PROGRAMM
#include <avr/io.h>

#define  led_1    PD6
#define button_1  PIND3

int main(void) {

  DDRD |= (1<<led_1);
  DDRC |= 0b00111111;
  SPI_SlaveInit();

  while(1) {

    if(but() == 1) {      //Sobald Taster (PD3) gedrückt,
      PORTD |= (1<<led_1);  //Kontroll-LED einschalten und
      PORTC = SPDR;      //SPDR nach PORTC schreiben.

    } else {
      PORTD &= ~(1<<led_1);  //Kontroll-LED aus
    }
  }

  return 0;
}

int but(void) {      //Liefert '1', wenn PD3 == true

  int tmp;

  if(PIND & (1 <<button_1)) {
    tmp = 1;
  } else {
    tmp = 0;
  }

  return tmp;
}

void SPI_SlaveInit(void)
{
  /* Set MISO output, all others input */
  DDRB = (1<<PB4);

  /* Enable SPI */
  SPCR = (1<<SPE);
}

char SPI_SlaveReceive(void)
{
  /* Wait for reception complete */
  while(!(SPSR & (1<<SPIF)));

  /* Return data register */
  return SPDR;
}

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