Forum: Mikrocontroller und Digitale Elektronik Programmiertfrage bez. SPI und Baustein


von Johnny K. (johnny_knoxville)


Lesenswert?

Hallo Leute
Ich habe folgendes Problem:
Beim Baustein LC320 von Microchip verlangt der Baustein beim Auslesen 
folgendes Timing (siehe Anhang).

Nun gut, da ich dieses Timing händisch hinprogrammiere stellt sich jetzt 
folgende Frage.
Wie kann ich mit dem Mikrocontroller am besten die Daten auf SO 
einlesen, währenddessen ich ja zeitgleich das Timing auf SCK am µC 
ausgebe, und nach der achten Flanke CS auf high ziehe.
Wie soll ich soetwas realisieren?
Das genaue Timing ist der Anhang "output_genau".
Denn das blöde ist ja, ich müsste erst einlesen, in der Mitte des Datums 
einen Takt generieren, dann wieder auf low ziehen, und dann kommt das 
nächste Datum.

Ich finde da irgendwie keine Lösung, und hoffe, dass ihr mir in 
irgendeiner Form helfen könnt.

Liebe Grüße
Johnny

: Wiederhergestellt durch Admin
von Johnny K. (johnny_knoxville)


Angehängte Dateien:

Lesenswert?

Anhang

: Wiederhergestellt durch Admin
von ... .. (docean) Benutzerseite


Lesenswert?

anhang fehlt

: Wiederhergestellt durch Admin
von Thomas B. (escamoteur)


Lesenswert?

Hi, wieso Zeitgleich? Die Signale dürfen doch ruhig ne weile anliegen. 
Die Daten werden eben erst mit der steigenden Flanke von SCLK 
übernommen.

Ich hatte neulich die gleichen sorgen bezüglich Timing und bekam den 
Hinweis, dass es ja gerade bei einer synchronen Übertragung bei der ein 
Taktsignal vorliegt auf das genaue Timing gar nicht ankommt.

Du musst lediglich die angegebenen Minimalzeiten einhalten, dann sollte 
es gehen.

Gruß
Tom

: Wiederhergestellt durch Admin
von Johnny K. (johnny_knoxville)


Lesenswert?

Thomas Burkhart schrieb:
> Hi, wieso Zeitgleich? Die Signale dürfen doch ruhig ne weile anliegen.
> Die Daten werden eben erst mit der steigenden Flanke von SCLK
> übernommen.
>
> Ich hatte neulich die gleichen sorgen bezüglich Timing und bekam den
> Hinweis, dass es ja gerade bei einer synchronen Übertragung bei der ein
> Taktsignal vorliegt auf das genaue Timing gar nicht ankommt.
>
> Du musst lediglich die angegebenen Minimalzeiten einhalten, dann sollte
> es gehen.
>
> Gruß
> Tom

Okay, ich habe verstanden was du meinst.
Aber wie soll ich das programmiertechnisch am besten realisieren?
Clock muss ich ja händisch programmieren, das heißt, in dieser Zeit kann 
ich nichts machen. Außer vorher und nachher. Und mit Interrupt kann ich 
das ja auch nicht so genau machen, oder etwa doch? Denn ich weiß ja 
nicht, wann das Datum genau anliegt, sodass ich darauf reagieren 
könnte...

Ich stehe gerade ein bisschen auf dem Schlauch. Vielleicht kannst du 
(respektive jemand) mir helfen.

Liebe Grüße

: Wiederhergestellt durch Admin
von Thomas B. (escamoteur)


Lesenswert?

Ich hab hier nur nen Ausschnitt fürs senden mit SPI, aber ich denke das 
sollte Dir helfen:

void writeCommand(uint16_t toSend)
{
  uint16_t mask  = 1 << 15;

  for(int i = 0; i<16; i++)
  {
    if (toSend & mask)
    {
      PORTB |= (1<<MOSI);
    }
    else
    {
      PORTB &= ~(1<<MOSI);
    }
    _delay_us(10);

    PORTB |= (1<<SCL);
    _delay_us(10);
    PORTB &= ~(1<<SCL);
    mask = mask >>1;
  }
  PORTB |= (1<<LOAD);
  _delay_us(10);
  PORTB &= ~(1<<LOAD);
  _delay_us(10);
}


D.h. Du ziehst SCL auf high, ließt in aller Ruhe Deinen Wert ein und und 
setzt SCLK wieder auf low und so weiter.

Gruß
Tom

: Wiederhergestellt durch Admin
von Johnny K. (johnny_knoxville)


Angehängte Dateien:

Lesenswert?

Thomas Burkhart schrieb:
> Ich hab hier nur nen Ausschnitt fürs senden mit SPI, aber ich denke das
> sollte Dir helfen:
>
> void writeCommand(uint16_t toSend)
> {
>   uint16_t mask  = 1 << 15;
>
>   for(int i = 0; i<16; i++)
>   {
>     if (toSend & mask)
>     {
>       PORTB |= (1<<MOSI);
>     }
>     else
>     {
>       PORTB &= ~(1<<MOSI);
>     }
>     _delay_us(10);
>
>     PORTB |= (1<<SCL);
>     _delay_us(10);
>     PORTB &= ~(1<<SCL);
>     mask = mask >>1;
>   }
>   PORTB |= (1<<LOAD);
>   _delay_us(10);
>   PORTB &= ~(1<<LOAD);
>   _delay_us(10);
> }
>
>
> D.h. Du ziehst SCL auf high, ließt in aller Ruhe Deinen Wert ein und und
> setzt SCLK wieder auf low und so weiter.
>
> Gruß
> Tom

Okay, so richtig schlau werde ich daraus nicht, ich glaub du hast ja 
jetzt nur das Timing herprogrammiert, oder wie?





Hier mal meine Methode!! (siehe Anhang) (welche nur das Timing 
ausgibt!), das Problem ist, wie gesagt, nur das einlesen...

PS: C-Code beinhaltet nur Methode, nicht das ganze Programm!

: Wiederhergestellt durch Admin
von Thomas B. (escamoteur)


Lesenswert?

If (bit_test (value, i))
  output_high(Data);      else                    output_low(Data);
      delay_us(2);
      output_high(Clock);
      delay_us(6);
      output_low(Clock);

output_low(Data);


Wieso ziehst Du Data am Ende wieder auf Low? Unnötig, reicht den neuen 
Wert für Data for dem nächsten hochziehen von SCLK zu setzen.

Vor allem musst Du aber hinter output-lo(Clock) noch ein Delay einfügen, 
damit Dein Slave auch ne Chance hat mitzubekommen, dass CLCK low ist.


Zum Programmierstil noch ein paar Hinweis:

Statt des CASE und der Forschleife außenrum, pack die for-Schleife die 
den Befehl ausgibt in eine Funktion und ruf die dann dreimal mit den 
richtigen Commandos auf, ich wußte erst gar nciht was Du da tust.

Kommentare: Du benennst Deine Variablen und Funktionen schon wunderbar 
sprechend. Schreib keine Kommentare die das gleiche aussagen wie Dein 
Code, ist überflüssig und oft passiert es dass man bei Änderungen des 
Codes vergisst die Kommentare anzupassen, so dass sie am schluss 
überhaupt nicht mehr passen. Kommentiere das Big Picture und versuche 
den Code so sprechend wie möglich zu machen.

Gruß
Tom

: Wiederhergestellt durch Admin
von Johnny K. (johnny_knoxville)


Lesenswert?

Thomas Burkhart schrieb:
> If (bit_test (value, i))
>   output_high(Data);      else                    output_low(Data);
>       delay_us(2);
>       output_high(Clock);
>       delay_us(6);
>       output_low(Clock);
>
> output_low(Data);
>
>
> Wieso ziehst Du Data am Ende wieder auf Low? Unnötig, reicht den neuen
> Wert für Data for dem nächsten hochziehen von SCLK zu setzen.
>
> Vor allem musst Du aber hinter output-lo(Clock) noch ein Delay einfügen,
> damit Dein Slave auch ne Chance hat mitzubekommen, dass CLCK low ist.
>
>
> Zum Programmierstil noch ein paar Hinweis:
>
> Statt des CASE und der Forschleife außenrum, pack die for-Schleife die
> den Befehl ausgibt in eine Funktion und ruf die dann dreimal mit den
> richtigen Commandos auf, ich wußte erst gar nciht was Du da tust.
>
> Kommentare: Du benennst Deine Variablen und Funktionen schon wunderbar
> sprechend. Schreib keine Kommentare die das gleiche aussagen wie Dein
> Code, ist überflüssig und oft passiert es dass man bei Änderungen des
> Codes vergisst die Kommentare anzupassen, so dass sie am schluss
> überhaupt nicht mehr passen. Kommentiere das Big Picture und versuche
> den Code so sprechend wie möglich zu machen.
>
> Gruß
> Tom

Okay, danke für die Belehrung.

Timing stimmt aber laut Logic Analyzer.

Nun gut, aber die Probleme wären trotzdem noch nicht geklärt :-)
Hinweis: Programmierung mag zwar nicht die vollkommendste sein, aber 
funktionieren tut es, zumindest das Timing ohne Einlesen...

: Wiederhergestellt durch Admin
von Thomas B. (escamoteur)


Lesenswert?

Sollte nicht Belehrend sein.

Mach trotzdem mal das output_low(Data); raus. Es könnte nämlich sein, 
dass Dein slave das als neues Bit wertet, auch wenn SCLK schon wieder 
auf LOW ist, aber danach nicht gewartet wurde. Die Pause in CLK kommt 
bei Dir nur durch den Delay am Anfang zu stande.

Im Zweifel auch ruhig mal die Pausen vergrößern, sind ja wher die 
Minimalweret die da angegeben sind oder? Und da Synchron sollte es fast 
egaö sein wie langsam Du die Werte rüberschiebst.

Gruß
Tom

: Wiederhergestellt durch Admin
von Johnny K. (johnny_knoxville)


Lesenswert?

Thomas Burkhart schrieb:
> Sollte nicht Belehrend sein.
>
> Mach trotzdem mal das output_low(Data); raus. Es könnte nämlich sein,
> dass Dein slave das als neues Bit wertet, auch wenn SCLK schon wieder
> auf LOW ist, aber danach nicht gewartet wurde. Die Pause in CLK kommt
> bei Dir nur durch den Delay am Anfang zu stande.
>
> Im Zweifel auch ruhig mal die Pausen vergrößern, sind ja wher die
> Minimalweret die da angegeben sind oder? Und da Synchron sollte es fast
> egaö sein wie langsam Du die Werte rüberschiebst.
>
> Gruß
> Tom

Okay...hab jetzt mal versucht, den Baustein nur zu beschreiben, und 
auszulesen, er gibt nichts aus...
Welche Tipps würdest du mir geben?
Soll ich mal die Timings posten?
Oder soll ich, was ich noch nicht gemacht habe, alle Pins auf einen 
definierten Pegel (5V oder Masse) bringen?

Falls ich es noch nicht erwähnt habe, der Baustein ist der 25LC320

Liebe Grüße

von Thomas B. (escamoteur)


Lesenswert?

Hast Du das letzte output_low(data) mal rausgenommen?

Timing posten wäre auf jeden Fall nicht schlecht.

Die Leitungen mit Pullpus versehen wäre sicher auch kein Fehler, 
zumindest SC-Karten reagieren allergisch wenn die nicht drin sind.

Hab grad mal nen Blick auf das Datenblatt geworfen. Kannst Du auch mal 
dan Schaltplan posten? Vielleicht haste Da auch einfach was übersehen.

Hast Du es mal mit nem anderen chip probiert? Nicht dass Deiner defekt 
ist.

Gruß
Tom

von Johnny K. (johnny_knoxville)


Angehängte Dateien:

Lesenswert?

Thomas Burkhart schrieb:
> Hast Du das letzte output_low(data) mal rausgenommen?
>
> Timing posten wäre auf jeden Fall nicht schlecht.
>
> Die Leitungen mit Pullpus versehen wäre sicher auch kein Fehler,
> zumindest SC-Karten reagieren allergisch wenn die nicht drin sind.
>
> Hab grad mal nen Blick auf das Datenblatt geworfen. Kannst Du auch mal
> dan Schaltplan posten? Vielleicht haste Da auch einfach was übersehen.
>
> Hast Du es mal mit nem anderen chip probiert? Nicht dass Deiner defekt
> ist.
>
> Gruß
> Tom

output_low(data) ist raus!

Timing ist im Anhang!
Hab drei Methoden inkludiert, siehe Timing.

Schaltplan kann ich dir sagen:

Beschaltung siehe Anhang (nicht beirren lassen vom Bauteil, GND ist beim 
25LC320 VSS)
SCLK vom µC auf SCK (& Logiganalysator)
SO vom µC auf SI (&Logikanalysator)
SS vom µC auf CS (&Logikanalysator)
SO vom Baustein auf Logikanalysator

Habs noch nicht mit einem anderen probiert, aber er dürfte, so glaube 
ich, nicht defekt sein!!!

von Thomas B. (escamoteur)


Lesenswert?

Hast Du Pullups eingefügt?

von Johnny K. (johnny_knoxville)


Lesenswert?

Thomas Burkhart schrieb:
> Hast Du Pullups eingefügt?

Meinst du auf den offenen Pins? Oder auf allen?

von Thomas B. (escamoteur)


Lesenswert?

Auf jeden Fall auf CS und und SCLK könnte ein Pulldown auch nicht 
schaden.

Gruß
Tom

von Johnny Knot (johnny_knoxville) (Gast)


Lesenswert?

Werd ich morgen mal probieren, hoffe, dass dabei was rauskommt.
Timing sollte doch passen, oder was sagst du?
Liebe Grüße

von Johnny K. (johnny_knoxville)


Lesenswert?

Johnny Knot (johnny_knoxville) schrieb:
> Werd ich morgen mal probieren, hoffe, dass dabei was rauskommt.
> Timing sollte doch passen, oder was sagst du?
> Liebe Grüße

Wie groß sollte ein Pulldown sein?
10k?

von Thomas B. (escamoteur)


Lesenswert?

Yep, 10k sollte passen CS aber ein Pull-Up
Gruß
Tom

von Johnny K. (johnny_knoxville)


Lesenswert?

Thomas Burkhart schrieb:
> Yep, 10k sollte passen CS aber ein Pull-Up
> Gruß
> Tom

Was sagste zum Timing, müsste doch passen oder etwa nicht?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.