AVR Embedded Tutorial - SPI-Slave/de

From Free Pascal wiki
Revision as of 15:46, 29 August 2018 by Mathias (talk | contribs) (Created page with "{{Translate}} =SPI als Slave= ==Vorwort== SPI kann man auch als Slave verwenden.<br> Das SPI auf eine Eingabe reagieren kann, löst man dies am besten Interruptgesteuert. D...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Template:Translate

SPI als Slave

Vorwort

SPI kann man auch als Slave verwenden.
Das SPI auf eine Eingabe reagieren kann, löst man dies am besten Interruptgesteuert.


Die folgenden Funktionen, sind in folgenden Tutorials beschrieben:

  • GPIO - Aus / Ein-gabe - Wie mache ich einen GPIO-Zugriff am AVR.
  • UART - Serielle Ein und Ausgabe über UART (COM-Port).
  • SPI - Nutzung der Hardware-SPI-Schnittstelle.

Beispiel Atmega328 / Arduino Uno/Nano

Units

Wird für SEI benötig.

uses
  intrinsics;

Konstanten und Variablen

Variablen für Ringpuffer.

const
  // Buffergrösse
  SPI_Buf_Len = 255;

var
  // Pufferezeiger unf Puffer
  SPI_Buf_FirstOut: byte = 0;
  SPI_Buf_LastIn: byte = 0;
  SPI_Buf_Data: array[0..SPI_Buf_Len - 1] of byte;

Pins welche an PORTB für SPI benötigt werden.
Wird aber nur gebraucht, wen man etwas sendet.

type
  TSPI_GPIO = bitpacked record
    p0, p1, SlaveSelect, MOSI, MISO, Clock, p6, p7: boolean;
  end;

var
  SPI_Port: TSPI_GPIO absolute PORTB;
  SPI_DDR: TSPI_GPIO absolute DDRB;

Zeichen von SPI empfangen

Sobald der Master am SS anklopft, wird der Interrupt ausgelöst und das kommende Zeichen in den Ringpuffer geschrieben.

  procedure SPI_Int_Send; public Name 'SPI__STC_ISR'; interrupt;
  var
    tchr: byte;
  begin
    tchr := SPDR;
    if tchr <> 0 then begin
      SPI_Buf_Data[SPI_Buf_LastIn] := tchr;
      Inc(SPI_Buf_LastIn);
      if SPI_Buf_LastIn >= SPI_Buf_Len then begin
        SPI_Buf_LastIn := 0;
      end;
    end;
  end;

Hauptprogramm

Im Hauptprogramm wird einfach geprüft, ob etwas im Ringpuffer ist und sobald etwas dort ist, wird es über UART ausgegeben.

var
  ch: byte;

begin
  // UART auf inizialisieren.
  UARTInit;

  // SPI als Slave, Interrupt gesteuert.
  SPCR := (1 shl SPE) or (1 shl SPIE);

  // Interrupt aktivieren.
  avr_sei;

  // SendePin
  SPI_DDR.MISO := True; // Nur nötig, wen der Slave auch sendet.

  repeat
    while SPI_Buf_LastIn <> SPI_Buf_FirstOut do begin // Ist etwas im Puffer ?
      ch := SPI_Buf_Data[SPI_Buf_FirstOut];
      Inc(SPI_Buf_FirstOut);
      if SPI_Buf_FirstOut >= SPI_Buf_Len then begin
        SPI_Buf_FirstOut := 0;
      end;
      UARTSendChar(char(ch));
    end;
  until 1 = 2;
end.


Siehe auch

Autor: Mathias