mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega8 und ISP Kommunikation


Autor: Lukas Baumann (lukasb)
Datum:

Bewertung
0 lesenswert
nicht 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))
#include <avr/io.h>
#include "gdi_test.h"
#include <util/delay.h>



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


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

    int x;
  x =0;
  while (1){
    /* Start transmission */
    SPDR = 1;
    /* Wait for transmission complete */
    while(!(SPSR & (1<<SPIF)))
    ;


    if (x == 1){
      x = 0;
      PORTD |= (1 << PD1); //PD0 -> Einschalten
    }
    else{
      x = 1;
      PORTD &= ~(1 << PD1); //PD0 -> Ausschalten
    }

    _delay_ms(1000);

  }

  return 0;
}


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

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

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


  int x;
  x = 1;
  while (1){

    if (x == 1){
      x = 0;
      PORTD |= (1 << PD0); //PD0 -> Einschalten
    }
    else{
      x = 1;
      PORTD &= ~(1 << PD0); //PD0 -> Ausschalten
    }



    while(!(SPSR & (1<<SPIF)))
    ;

    int test;
    test = SPDR;

    if ( test == 1){
      PORTD |= (1 << PD1); //PD1 -> Einschalten
    }
    else
    {
      PORTD &= ~(1 << PD1); //PD1 -> Ausschalten
    }





  }
  





  return 0;
}





int main (void){

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

  
  PORTD &= ~(1 << PD0); // -> Ausschalten
  PORTD &= ~(1 << PD1); // -> Ausschalten

  
  if (PIND & (1 << PD2)){
    //port PD2 ist geschaltet -> master
    Master();
  }
  else
  {
    Slave();
  }

}




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.

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
habe dein Programm zwar nur überflogen, aber Pin PB2 muß als Ausgang 
gesetzt werden beim MAster Betrieb. Davon einmal abgesehen würde ich 
alle deine "int" durch "unsigned char" ersetzen.

Gruß

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

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

Autor: Christian L. (lorio)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Musst du nicht

MOSI <-> MOSI
MISO <-> MISO

verbinden?
Schließlich heit das doch Master Out, Slave In.

Gruß
Christian

Autor: Matthias Lipinsky (lippy)
Datum:

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

Autor: Lukas Baumann (lukasb)
Datum:

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

Autor: Lukas Baumann (lukasb)
Datum:

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

Autor: Gast (Gast)
Datum:

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

Autor: Stefan Ernst (sternst)
Datum:

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

Autor: lukas b. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
alles klar, danke

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Lukas,

kannst du bitte deine "gdi_test.h" posten??

Gruß
Martin

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.