AVR Embedded Tutorial - SPI Shiftregister/de
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 folgende Funktionen, sind in folgenden Tutorials beschrieben:
- Delay
- UART, Serielle Schnittstelle
- SPI - Nutzung der Hardware-SPI-Schnittstelle.
Beschreibung
Dieses Beispiel zeigt, wie man Schieberregister über SPI ansteuert.
Funktionen für EEPROM (24LC256) Ansteuerung.
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
- Übersichtseite AVR Embedded Tutorial
Autor: Mathias