mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Abfrage via SPI


Autor: Thomas H. (Gast)
Datum:

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

Autor: Thomas H. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
nhang vergessen!

Autor: Stefan Kleinwort (Gast)
Datum:

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

Autor: Thomas H. (Gast)
Datum:

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

Autor: Stefan Kleinwort (Gast)
Datum:

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

Autor: Thomas H. (Gast)
Datum:

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

Autor: Thomas H. (Gast)
Datum:

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

Autor: Stefan Kleinwort (Gast)
Datum:

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

Autor: Thomas H. (Gast)
Datum:

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

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.