Atmega8 und ISP Kommunikation

#1049471
Lesenswert?

Hallo Leute!

Bin neu hier und auch in sachen Mikroprozessoren.

Nachdem ich jetzt ein paar Tage mit dem uC rumexperimentiert habe, habe 
ich mir eine (vermeindlich !!) einfache Aufgabe gestellt.

Da ich viele Bauteile die ich in Zukunft verwenden will ISP unterstüzen 
wollte ich zum EInstieg 2 uP miteinander "kommunizieren" lassen, soll 
heißen:
Master schickt ein Byte an Slave, fertig!

Gesagt, getan schaltung sieht wie folgt aus:

2 Atmega8 mit 4,5 V Spannung (3x1,5V Batterie) und 8Mhz Quartz (also 2 
mal) dran.

am Master PD2 auf 4,5V (Master / Slace select, siehe unten)

SCK <--> SCK
MISO <--> MOSI
MOSI <--> MISO

und am Slave
SS <--> GND

Da ich nicht immer 2 Programme flashen will, habe ich master und slave 
betrieb über einen Input pin (PD2) gewählt.


an PD0 und PD1 hängen bei beiden uC jeweils eine LED zum debuggen.

Hier mein Programm:
(in gdi_test.h ist nur F_CPU definiert (8000000))
1
#include <avr/io.h>
2
#include "gdi_test.h"
3
#include <util/delay.h>
4

5

6

7
int Master(void){
8
  PORTD |= (1 << PD0); //PD0 -> Einschalten
9

10

11
  /* Set MOSI and SCK output, all others input */
12
  DDRB = (1<<PB3)|(1<<PB5);
13
  /* Enable SPI, Master, set clock rate fck/16 */
14
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
15

16
    int x;
17
  x =0;
18
  while (1){
19
    /* Start transmission */
20
    SPDR = 1;
21
    /* Wait for transmission complete */
22
    while(!(SPSR & (1<<SPIF)))
23
    ;
24

25

26
    if (x == 1){
27
      x = 0;
28
      PORTD |= (1 << PD1); //PD0 -> Einschalten
29
    }
30
    else{
31
      x = 1;
32
      PORTD &= ~(1 << PD1); //PD0 -> Ausschalten
33
    }
34

35
    _delay_ms(1000);
36

37
  }
38

39
  return 0;
40
}
41

42

43
int Slave(void){
44
  PORTD &= ~(1 << PD0); //PD0 -> Ausschalten
45

46
  /* Set MISO output, all others input */
47
  DDRB = (1 << PB4);
48

49
  /* Enable SPI */
50
  SPCR = (1<<SPE);
51

52

53
  int x;
54
  x = 1;
55
  while (1){
56

57
    if (x == 1){
58
      x = 0;
59
      PORTD |= (1 << PD0); //PD0 -> Einschalten
60
    }
61
    else{
62
      x = 1;
63
      PORTD &= ~(1 << PD0); //PD0 -> Ausschalten
64
    }
65

66

67

68
    while(!(SPSR & (1<<SPIF)))
69
    ;
70

71
    int test;
72
    test = SPDR;
73

74
    if ( test == 1){
75
      PORTD |= (1 << PD1); //PD1 -> Einschalten
76
    }
77
    else
78
    {
79
      PORTD &= ~(1 << PD1); //PD1 -> Ausschalten
80
    }
81

82

83

84

85

86
  }
87
  
88

89

90

91

92

93
  return 0;
94
}
95

96

97

98

99

100
int main (void){
101

102
  DDRD |= (1 << PD0); // -> Ausgang
103
  DDRD |= (1 << PD1); // -> Ausgang
104
  DDRD &= ~(1 << PD2); // -> Eingang
105

106
  
107
  PORTD &= ~(1 << PD0); // -> Ausschalten
108
  PORTD &= ~(1 << PD1); // -> Ausschalten
109

110
  
111
  if (PIND & (1 << PD2)){
112
    //port PD2 ist geschaltet -> master
113
    Master();
114
  }
115
  else
116
  {
117
    Slave();
118
  }
119

120
}



So und jetzt mein Problem:
Problem 1:
Der Master "hängt" nach dem 3 Zyklus der übertragung. (PD0 Alias LED1) 
hört auf zu blinken.

Problem 2:
Der Client empfängt nur manchmal (sehr sporadisch) irgendwelche Daten 
und wenn er etwas empfängt, dann nicht das richtige. (in diesem Fall 
keine "1", habs aber auch schon mit anderen zahlen probiert)

Leider habe ich (noch) kein Oszi. hier, kann also nicht sagen was jetzt 
tatsächlich beim Master an MISO rauskommt.


Vermutlich ist es ein Anfängerfehler. Habe schon das Forum durchsucht 
nur leider scheint keiner ein ähnliches problem zu haben...

Was mach ich falsch.

Liebe Grüße
und danke schonmal!

Lukas B.
Gast #1049486
Lesenswert?

>Pin PB2 muß als Ausgang gesetzt werden beim MAster Betrieb.

Das ist sicherlich \SS.

>SS mußt du mein ich doch per "Hand" ansteuren da du damit dem Slave
>bekannt gibts das das byte "fertig" ist...


Am besten beide \SS verbinden. Beim Master ein LOW ausgeben während der 
übertragung.


>SCK <--> SCK
>MISO <--> MOSI
>MOSI <--> MISO

Das ist falsch.
MISO = MasterIn  SlaveOut
MOSI = MasterOut SlaveIn

Somit muss folgendes verschaltet werden:
Master                     Slave
MASTER_IN_slave_out         master_in_SLAVE_OUT
MASTER_OUT_slave_in         master_out_SLAVE_IN

Also: MISO an MISO und MOSI an MOSI.

Sonst gibts Murks.


PS: Alles im Datenblatt beschrieben!
#1049516
Lesenswert?

hey dankeschön!


RTFM ist wohl manchmal echt angebracht. ;-)

aber ich habe die ganze zeit alles überprüft und immer wieder 
nachgelesen. habe nur nie in frage gestellt das MISO an MOSI gehört -> 
ist wohl als anfängerfehler abzutun.

tut jetzt wunderbar!

danke nochmal!
#1049520
Lesenswert?

ach eine frage noch am rande:

(vermutlich steht es zwischen den zeilen auch in der manual, aber 
vielleicht kanns mir ja einer kurz und knapp beantworten)

da steht "full duplex" drin. aber wie kann die SPI übertragung full 
duplex sein, wenn ich zum lesen und schreiben jeweils das gleich byte 
benutze?
Gast #1049527
Lesenswert?

# Halbduplex (HX), auch Semiduplex genannt bedeutet wechselseitiger 
Betrieb. Hierbei können Informationen in beide Richtungen fließen, 
allerdings nicht gleichzeitig, z. B. Amateurfunk.
# Vollduplex (DX, manchmal auch FDX) ist der gleichzeitige Betrieb. Es 
lässt die Übertragung der Informationen in beide Richtungen zu gleicher 
Zeit zu, z. B. Telefonie.

Siehe: http://de.wikipedia.org/wiki/Duplex_(Nachrichtentechnik)
#1049530
Lesenswert?

Lukas Baumann wrote:

> da steht "full duplex" drin. aber wie kann die SPI übertragung full
> duplex sein, wenn ich zum lesen und schreiben jeweils das gleich byte
> benutze?

Du meinst vermutlich mit "Byte" eher "Register". Es werden zwei 
verschiedene Register sein, die über die selbe Adresse angesprochen 
werden. Beim Lesen von der Adresse halt das eine Register, und beim 
Schreiben auf die Adresse das andere.

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