Sign in Join
Wiki copytemporary

AVR Embedded Tutorial - SPI Shiftregister/de

Deutsch · English

Schieberegister 74HC595 über SPI

Vorwort

Es können auch andere Schieberegister angesteuert werden.
Die SPI Version hat einen grossen Vorteil gegenüber einem normalen Schieberegister, das sie etwa den Faktor 10 schneller ist (ATmega328). Dies macht sich bei einem grösseren Multiplex bemerkbar.

Die folgenden Funktionen, sind in folgenden Tutorials beschrieben:

Beispiel Atmega328 / Arduino Uno/Nano

Konstanten

Pins welche an PORTB für SPI benötigt werden.

pascal
const
  SPI_SlaveSelect = 2;
  SPI_MOSI        = 3;
  SPI_Clock       = 5;

Schreiben eines Pins

Beschreiben eines Pins von PORTB, wird für SlaveSelect und für die Softwareversion gebraucht.

pascal
  procedure WritePortB(Pin: byte; Value: boolean);
  begin
    if Value then begin
      PORTB := PORTB or (1 shl Pin);
    end else begin
      PORTB := PORTB and not (1 shl Pin);
    end;
  end;

Ein Funktion welche eine Zeichenkette an den SPI-Port sendet.

Schreiben der Zeichenkette

pascal
  procedure WriteDataHardSPI(p: PByte; len: byte);
  var
    i: byte;
  begin
    WritePortB(SPI_SlaveSelect, False);
    for i := len - 1 downto 0 do begin
      SPDR := p[i];
      while (SPSR and (1 shl SPIF)) = 0 do begin
      end;
    end;
    WritePortB(SPI_SlaveSelect, True);
  end;

Hauptprogramm

Die Register von SPI wird auf die höchst mögliche Geschwindigkeit gestellt.

pascal
var
  z: uint16;
begin
  // Alle Pins auf Output.
  DDRB := (1 shl SPI_MOSI) or (1 shl SPI_Clock) or (1 shl SPI_SlaveSelect);

  // SPI-Register einstellen.
  SPCR := (1 shl SPE) or (1 shl MSTR) or (%00 shl SPR);
  SPSR := (1 shl SPI2X);  

  repeat
    // Zähler hochzählen, bei Überlauf wieder auf 0.
    Inc(z);

    // SPI-Port beschrieben.
    WriteDataHardSPI(@z, 2); // 2 Byte schreiben.
  until 1 = 2;
end.

Beispiel ATTiny2313

Der ATTiny2313 besitzt keine direkte SPI-Schnittstelle, dafür gibt es die universelle USI-Schnittstelle, welche hier für SPI verwendet wird. Dies ist beim Beschreiben ein wenig komplizierter als bei der direkte SPI-Schnittstelle des Atmega.

Hinweis: Der ATTiny2313 hat auch MOSI und MISO-Anschlüsse, diese habe aber nur für den Programmer Verwendung. Dafür sind DO und DI vorhanden, welche aber genau in der umgekehrten Reihenfolge arbeiten.

Deklarationen

Pins welche an PORTB für SPI benötigt werden.

Dafür wir ein bitpacked record verwendet, somit kann man direkt auf die Pins zugreifen.

pascal
type
  TSPIGPIO = bitpacked record
    p0, p1, p2, p3, SlaveSelect, DataInt, DataOut, Clock: boolean;
  end;

var
  SPI_PORT: TSPIGPIO absolute PORTB;
  SPI_DDR:  TSPIGPIO absolute DDRB;

Ein Funktion welche eine Zeichenkette an den SPI-Port sendet.

Schreiben der Zeichenkette

pascal
  procedure SPIWriteData(p: PByte; len: byte);
  var
    i: byte;
  begin
    SPI_PORT.SlaveSelect := False;
    for i := len - 1 downto 0 do begin
      USIDR := p[i];
      USISR := 1 shl USIOIF;

      repeat
        USICR := (%01 shl USIWM) or (%10 shl USICS) or (1 shl USICLK) or (1 shl USITC);
      until (USISR and (1 shl USIOIF)) <> 0;

    end;
    SPI_PORT.SlaveSelect := True;
  end;

Hauptprogramm

Diese Beispiel zeigt da Beschreiben von 2 kaskadierten Schieberegister.

Es wird einfach einen Integer Wert ausgegeben.

Man sieht auch das keine Konfiguration von USI am Anfang notwendig ist, ausser das man die Ports auf Ausgabe stellen muss.

pascal
var
  z: uint16 = 0;
begin
  SPI_DDR.DataOut     := True;
  SPI_DDR.Clock       := True;
  SPI_DDR.SlaveSelect := True;

  repeat
    Inc(z);
    SPIWriteData(@z, 2); // Integer ausgeben.
  until 1 = 2;
end.

Software Version

Das man SPI sehr gut auch Softwareemuliert machen kann, zeige ich es hier auch.

Dies ist aber um etwa den Faktor 10 langsamer als die Hardwareversion des Atmega328, dafür kann man beliebige Ports nehmen.

Die Software-Version hat den Vorteil, sie läuft auf jedem AVR und kann auch benutzt werden, wen man mehrere SPI-Schnittstellen braucht.

pascal
  procedure WriteDataSoftSPI(p: PByte; len: byte);
  var
    i, j: byte;
  begin
    WritePortB(SPI_SlaveSelect, False);
    for j := 0 to len - 1 do begin

      for i := 7 downto 0 do begin
        if (p[j] and (1 shl i)) <> 0 then begin
          WritePortB(SPI_MOSI, True);
        end else begin
          WritePortB(SPI_MOSI, False);
        end;
        WritePortB(SPI_Clock, True);
        WritePortB(SPI_Clock, False);
      end;
      WritePortB(SPI_SlaveSelect, True);

    end;
  end;

Siehe auch

Autor: Mathias


From the Free Pascal wiki, page "AVR Embedded Tutorial - SPI Shiftregister/de", as it stood on 2020-02-27 after a change by Mathias, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Revision 1, last changed by WikiArchive .

Edited on wiki.freepascal.org by 2 people, 2018–2020

From the official wiki's backup of 26 May 2024: who edited this page there, and when. Edits made there after that date were not recorded, and the earlier versions are not shown here; the main page says why.

WhenWhoWhat changed
MathiasCreated page
MathiasFunktionen (minor)
MathiasVorwort
MathiasSiehe auch
MathiasFunktionen für EEPROM (24LC256) Ansteuerung.
MathiasSchieberegister 74HC595 über SPI
MathiasSchieberegister 74HC595 über SPI
MathiasSiehe auch
MathiasVorwort
MathiasFunktionen für die Beschreibung von 74HC595 Schieberegister
MathiasFunktionen für die Ansteuerung von 74HC595 Schieberegister
MathiasBeispiel Atmega328 / Arduino Uno/Nano
MathiasBeispiel ATTiny2313
MathiasBeispiel ATTiny2313
MathiasFunktionen für die Ansteuerung der 74HC595 Schieberegister
MathiasFunktionen für die Ansteuerung der 74HC595 Schieberegister
MathiasVorwort
MathiasSchieberegister 74HC595 über SPI
MathiasVorwort
Mathias
MathiasBeispiel Atmega328 / Arduino Uno/Nano
MathiasSoftware Version
Mathias
MathiasFunktionen
MathiasSoftware Version
MathiasBeispiel ATTiny2313
MathiasBeispiel ATTiny2313
MathiasKonstanten
MathiasHauptprogramm
MathiasHauptprogramm
MathiasHauptprogramm
MathiasSoftware Version
MathiasHauptprogramm
MathiasHauptprogramm
TrevFixed template loop; syntax highlighting; modded categories to German; added language category (minor)
MathiasBeispiel ATTiny2313

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.