Forum: Mikrocontroller und Digitale Elektronik Abfrage via SPI


von Thomas H. (Gast)


Lesenswert?

Hallo,

wenn ich den MAX6674 auslesen moechte (siehe Protokoll im Anhang) muss
ich CS low setzen und dann sendet der IC die Daten an den uC mit dem
vorgegebenen Takt.

Dann muesste ich ja in schneller Folge zwei Byte auslesen. Geht das mit
dem Hardware SPI bzw. wie gehe ich da ran?

Z. B. uC als Master und setze CS auf low. Wie bekomme ich nun die
gesendeten zwei Byte gleich hintereinander, ohne, dass dazwischen ein
Bit durch den Auslesezeitraum o. ae. verloren geht? Mache ich das ueber
den Interrupt (auch beim uC als Master)? Oder kann ich den Takt
anhalten nach 8 Bits, damit ich das erste Byte auslesen kann und
anschliessend weiterlaufen lasse um die letzten auszulesen - waehrend
ich CS auf low halte?

Ich setze den ATmega162 ein. Vielen Dank,

Thomas

von Thomas H. (Gast)


Angehängte Dateien:

Lesenswert?

nhang vergessen!

von Stefan Kleinwort (Gast)


Lesenswert?

Den Takt machst Du doch selber.

Also:
* CS auf low setzen (AVR)
* der ATmega startet erste SPI-Übertragung -> der Max setzt seine
  Datenbits entsprechend dem SPI-Takt des AVR
* AVR liest SPI-Daten aus Register
* der ATmega startet zweite SPI-Übertragung -> der Max setzt seine
  Datenbits von Byte entsprechend dem SPI-Takt des AVR
* AVR liest SPI-Daten des 2.Bytes aus Register
* CS auf high setzen (AVR)

Wenn der AVR zwischenrein eine Pause macht, dann stört das garnicht,
weil er ja selber den Takt vorgibt.

Was anderes ist es, wenn der AVR der Slave ist, dann muss man wirklich
schauen, dass der AVR "hinterherkommt". In diesem Fall muss die
SPI-Rate entsprechend niedrig angesetzt werden.

Stefan

von Thomas H. (Gast)


Lesenswert?

Hallo Stefan,

so dachte ich mir das auch, nur funktioniert das bis jetzt nicht.

Frage: waehrend ich das Register auslese, ruht solange der Takt? Denn
sonst uebertraegt der MAX6674 weiterhin Daten, obwohl ich das Register
vom AVR noch nicht ausgelesen habe und damit das 2. Byte nicht in das
Register kann und somit verloren geht??

Viele Gruesse,

Thomas H.

von Stefan Kleinwort (Gast)


Lesenswert?

Wenn de AVR Master ist, kommen nur 8 Clock-Takte für jedes gesendete
SPI-Byte. Zwischen den Bytes kommt nix.

Wenn der AVR Slave ist und ein Überlauf stattfindet, würde übrigens das
erste Byte vom zweiten überschrieben werden.

Was bekommst Du denn bis jetzt als Ergebnis?

Stefan

von Thomas H. (Gast)


Lesenswert?

Hallo,

ich habe jetzt zur Sicherheit und zum Test einmal das Auslesen manuel
mit dem Setzen der Ausgaenge gemacht. Damit habe ich jetzt folgenden
Code (noch umstaendlich, aber vom Prinzip her o. k.):

{
SPCR=0x00;  // deaktiviere SPI

unsigned char buffer1, buffer2, a;
int i;

for (;;)
{
SPCR=0x00;

buffer1=0;
buffer2=0;

sbi(DDRB, 7);      // SCK Ausg.
sbi(DDRA, 1);      // CS Ausg.
cbi(DDRB, 6);      // MISO Eing.

sbi(PORTA, 1);    // CS high
    cbi(PORTB, 7);                          // SCK low

    cbi(PORTA, 1);                          // CS low
    _delay_loop_2(1000);

    for(i=1; i<=8; i++)
    {
      sbi(PORTB, 7);                        // SCK high
      _delay_loop_2(200);

      if(bit_is_set(PINB, 6))
      {
        a=1;
      }
      else
      {
        a=0;
      }

      cbi(PORTB, 7);                        // SCK low
      _delay_loop_2(200);

      buffer1=(buffer1*2)+a;
    }

    for(i=1; i<=8; i++)
    {
      sbi(PORTB, 7);                        // SCK high
      _delay_loop_2(200);

      if(bit_is_set(PINB, 6))
      {
        a=1;
      }
      else
      {
        a=0;
      }

      cbi(PORTB, 7);                        // SCK low
      _delay_loop_2(200);

      buffer2=(buffer2*2)+a;
    }

    sbi(PORTA, 1);                          // CS high
    _delay_loop_2(200);

    init_lcd();
    printhex(buffer1);
    printhex(buffer2);
  }
}

von Thomas H. (Gast)


Lesenswert?

Ich erhalte jedoch immer die Ausgabe 0x1787. Das kann nicht stimmen.
Selbst wenn ich das Thermoelement abkopple ist es die selbe Ausgabe.

Idee?

Danke und tschau,

Thomas

von Stefan Kleinwort (Gast)


Lesenswert?

Der Code sieht eigendlich korrekt aus.

Kannst Du die Pins mal mit dem Oszi nachmessen?

Überschreib doch mal die Werte von bufferx vor der LCD-Ausgabe, um zu
testen, ob ev. da der Fehler steckt:

    buffer1 = 1;
    buffer2 = 2;
    init_lcd();
    printhex(buffer1);
    printhex(buffer2);
  }

Stefan

von Thomas H. (Gast)


Lesenswert?

Hallo Stefan,

Ausgabe ist korrekt. Nach mehrmaligem an-/ausschalten (reseten) erhalte
ich jetzt immer die Ausgabe 0x0007. Mit dem Osszi wollte ich auch
demnaechst messen, wenn ich wieder ins Labor komme.

Thomas H.

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.