Problem Schieberegister 595er ud 597er

#3385721
Lesenswert?

Hallo,

ich wurschtel hier herum und irgendwie funktioniert es nicht. Ich möchte 
über SPI ein 595er und 597 benutzen. Angehangen der Schaltplan, wobei 
noch fehlt, dass alle Eingänge des 597er über 1k Ohm auf Masse liegen 
als pulldown.

Es funktioniert einwandfrei, bei der Schaltung den 595er zu steuern, da 
hängen getreiberte LEDs dran.

Wenn ich aber den Code ausführe, der vom 597er lesen soll, und das Datum 
an den 595er weitergibt, dann geht nix mehr. Die Idee ist simpel: Auf 
die Inputs des 597er Spannung legen, dann erwarte ich, dass dies 
weitergegeben wird an den 595 als Output.

Der Schaltplan sollte passen, ich benutze ein Pollin-Board, deshalb habe 
ich extra die Pinbelegungen des Atmega32 hinzugefügt.

Ich bin nicht erfahren im Debugging über Studio und Dragon, aber so wie 
es ausschaut, hängt sich der Debugger beim Input über den 597er fest...

Habt ihr nen Tipp?







Viele Grüße,

Jens
#3385997
Lesenswert?

Du hast keinen Takt zum Lesen. Entweder du schreibst sinnvolle Daten und 
liest gleichzeitig oder du gibst ein Dummybyte aus. Sonst kannst du bis 
in alle Ewigkeit warten.
1
uint8_t SPI_SlaveReceive(void)
2
{
3
  SPDR = 255;   // Dummybyte
4
  /* Wait for reception complete */
5
  while(!(SPSR & (1<<SPIF)))
6
  ;
7
  /* Return data register */
8
  return SPDR;
9
}


mfg.
#3386009
Lesenswert?

Thomas Eckmann schrieb:
> Du hast keinen Takt zum Lesen. Entweder du schreibst sinnvolle Daten und
> liest gleichzeitig


Das scheint überhaupt eines der größten Missverständnisse beim SPI zu 
sein.

SPI unterscheidet nur zwischen Master und Slave. Aber eigentlich sind 
Senden und Empfangen dasselbe. Denn SPI ist in Wirklichkeit ein 
Austausch von Bytes. Der Master übergibt 1 Byte auf der MOSI Leitung an 
den Slave und zur selben Zeit übergibt der Slave auf der MISO Leitung 1 
Byte an den Master.

Da der Master zu jedem Zeitpunkt die volle Kontrolle über die 
Taktleitung hat, kann ein Slave nur dann an den Master übertragen, wenn 
der Master den Vorgang anleiert und zu diesem Zwecke 1 Byte an den Slave 
übergibt. Der Slave kann von sich aus da überhaupt nichts tun.

D.h. die Funktionen

> uint8_t SPI_SlaveReceive(void)
und
> void SPI_MasterTransmitOut (uint8_t data) {

sind eigentlich dasselbe und können zu einer einzigen Funktion 
zusammengefasst werden, die 1 Byte austauscht.
1
uint8_t SPI_Exchange( uint8_t data )
2
{
3
  SPDR = data;
4

5
  while(!(SPSR & (1<<SPIF)))
6
  ;
7

8
  return SPDR;

Ja nachdem, woran man interessiert ist, benutzt man dann einfach den 
Returnwert nicht bzw. übergibt einfach irgendeinen Wert als 
data-Argument, weil man am Returnwert interessiert ist.
#3386344
Lesenswert?

Karl Heinz schrieb:
> Thomas Eckmann schrieb:
>> Du hast keinen Takt zum Lesen. Entweder du schreibst sinnvolle Daten und
>> liest gleichzeitig
>
>
> Das scheint überhaupt eines der größten Missverständnisse beim SPI zu
> sein.
>
>
Hallo Karl Heinz und Thomas,

vielen Dank! Ich möchte mich echt bedanken für dieses hervorragende 
Forum, macht Spaß!

Ja, das war mir absolut nicht bewusst!

Leider stehe ich immer noch auf dem Schlauch, angehangen der neue Code 
und ein Bild von meinem Oszi. Ich kann beliebige Werte an SPI_Exchange 
schreiben, genau diese werden auf den Leds angezeigt, also im 
Code-Beispiel die 233.
Der Austausch der Daten mit dem 597er funktioniert aber nicht. Mit 
meinem kleinen Oszi habe ich ein Bild vom Pin 14 des 597er aufgenommen, 
also der DS der auf MISO liegt. Die Spannung passt wohl kaum, um dem 
Atmega ein Signal zu geben!
Irgendwo muss die Spannung doch bleiben... habt ihr eine Idee?


Liebe Grüße,
Jens
Angehängte Dateien:
#3386496
Lesenswert?

J. W. schrieb:

> Leider stehe ich immer noch auf dem Schlauch, angehangen der neue Code
> und ein Bild von meinem Oszi. Ich kann beliebige Werte an SPI_Exchange
> schreiben, genau diese werden auf den Leds angezeigt, also im
> Code-Beispiel die 233.
1
    PORTC &= ~(1<<DD_SS_i); 
2
    PORTC |= (1<<DD_SS_i);
3
    PORTC &= ~(1<<DD_SS_i);
4
    PORTC |= (1<<DD_p597);
5
    PORTC &= ~(1<<DD_p597);
6
    PORTC |= (1<<DD_p597);

Ich steig durch deine Bezeichnungen zwar nicht durch, aber das sieht 
irgendwie falsch aus. Denn der Load muß bei PL = 0 und das Auslesen bei 
PL = 1 erfolgen.

PL(13) = 0
STCP(12) = 1   Lo..
STCP(12) = 0       ..ad
PL(13) = 1

SPDR = Daten oder Dummy
while(!(SPSR & (1 << SPIF)));
input = SPDR;

mfg.
#3386967
Lesenswert?

Das hier
1
    //output verarbeiten
2
    PORTB &= ~(1<<DD_SS_o);
3
    PORTB |= (1<<DD_SS_o);
4
    PORTB &= ~(1<<DD_SS_o);
5
    dummy = SPI_Exchange(zahl); //return wert nicht wichtig
kann so nicht stimmen.

Denn um am 595 auszugeben musst du erst das Byte eintakten und erst dann 
einmal mit dem RCK des 595 wackeln, damit er es auf den Ausgang 
durchschaltet.

PS: wenn dich ein Returnwert nicht interessiert, dann brauchst du ihn 
auch nicht in einer Variablen auffangen
1
    //output verarbeiten
2
    SPI_Exchange(zahl);           // 595 laden
3
    PORTB &= ~(1<<DD_SS_o);       // und mittels RCK auf die Ausgänge durchschalten
4
    PORTB |= (1<<DD_SS_o);
5
    PORTB &= ~(1<<DD_SS_o);

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