Difference between revisions of "AVR Embedded Tutorial - SPI Shiftregister/de"

From Lazarus wiki
Jump to navigationJump to search
Line 8: Line 8:
 
Die SPI Version hat einen grossen Vorteil gegenüber einem normalen [[AVR Embedded Tutorial - Shiftregister/de|Schieberegister]], das sie etwa den Faktor 10 schneller ist. Dies macht sich bei einem grösseren Multiplex bemerkbar.
 
Die SPI Version hat einen grossen Vorteil gegenüber einem normalen [[AVR Embedded Tutorial - Shiftregister/de|Schieberegister]], das sie etwa den Faktor 10 schneller ist. Dies macht sich bei einem grösseren Multiplex bemerkbar.
  
Die folgende Funktionen, sind in folgenden Tutorials beschrieben:
+
Die folgenden Funktionen, sind in folgenden Tutorials beschrieben:
 
* [[AVR Embedded Tutorial - Simple GPIO on and off output/de|GPIO - Aus / Ein-gabe]] - Wie mache ich einen GPIO-Zugriff am AVR.
 
* [[AVR Embedded Tutorial - Simple GPIO on and off output/de|GPIO - Aus / Ein-gabe]] - Wie mache ich einen GPIO-Zugriff am AVR.
 
* [[AVR Embedded Tutorial - SPI/de|SPI]] - Nutzung der Hardware-SPI-Schnittstelle.
 
* [[AVR Embedded Tutorial - SPI/de|SPI]] - Nutzung der Hardware-SPI-Schnittstelle.

Revision as of 17:33, 14 August 2018

Template:Translate

Schieberegister 74HC595 über SPI

Vorwort

Dieser Code ist für einen Atmega328/Arduino mit 16MHz und 74HC595.
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. Dies macht sich bei einem grösseren Multiplex bemerkbar.

Die folgenden Funktionen, sind in folgenden Tutorials beschrieben:

Beschreibung

Dieses Beispiel zeigt, wie man Schieberregister über SPI ansteuert.

Funktionen für die Beschreibung von 74HC595 Schieberegister

Konstanten

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

const
  SPI_SlaveSelect = 2;
  SPI_DataOut     = 3;
  SPI_Clock       = 5;

Funktionen

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

  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.

Hardware Version

  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;

Software Version

Da man SPI sehr gut auch Software emuliert machen kann, zeige ich es hier auch.
Dies ist aber um etwa den Faktor 10 langsamer als die Hardwareversion, dafür kann man beliebige Ports nehmen.

  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_DataOut, True);
        end else begin
          WritePortB(SPI_DataOut, False);
        end;
        WritePortB(SPI_Clock, True);
        WritePortB(SPI_Clock, False);
      end;
      WritePortB(SPI_SlaveSelect, True);

    end;
  end;

Beispiel

Diese Beispiel zeigt da Beschreiben von 2 kaskadierten Schieberegister.

Konstanten und Variablen

Eine 16Bit Variable die einfach hochzählt.

var
  z: UInt16 = 0;

Hauptprogramm

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

begin
  // Alle Pins auf Output.
  DDRB := (1 shl SPI_DataOut) 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.

Siehe auch

Autor: Mathias