AVR Embedded Tutorial - Shiftregister/de
Schieberegister
Der Beispielcode ist für ein ATtiny2313. Schieberegister werden folgende verwendet:
- Lesen: 74HC165
- Schreiben: 74HC595.
Achtung, die Leseroutine ist nicht kompatibel mit Arduino shiftIn(... ! Die Arduino Lesefunktion ist für andere Schieberegister. Der Clock muss anders angesteuert werden.
Will man MSB und LSB vertauschen, dann muss man dementsprechend einfach to mit downto austauschen.
Portzugriffe
Wie die Schieberegisterbefehle auf die Ports zugreifen, siehe hier: GPIO-Ausgabe.
Nicht vergessen die Ausgänge auch als Ausgang einzustellen (DDRx).
Port-Konstanten
Die verwendeten Pins des ATtiny2313 und der Shiftregister. Beim AVR kann man beliebige Pins nehmen. Ich habe die Ports, ausgenommen des Data-Ports, global deklariert, somit ist der Zugriff aus die Schiftregister ein wenig schneller. Wen man sie lokal übergeben würde, würde alles komplizierter werden, da wir direkten Portzugriff verwenden. Arduino macht dies anders, aber dafür ist es etwa um den Faktor 10x langsamer.
IC | Attiny2313 | 74HC165 | 74HC595 | |||
---|---|---|---|---|---|---|
PinNr | Bezeichnung | PinNr | Bezeichnung | PinNr | Bezeichnung | |
dataInPin | 12 | PB0 | 10 | DS | ||
dataOutPin | 2 | PD0 | 14 | DS | ||
latchPin | 3 | PD1 | 1 | PL | 12 | ST_CP |
clockPin | 6 | PD2 | 2 | CP | 11 | SH_CP |
const
// PortB
dataInPin = 0; // PB0
// PortD
dataOutPin = 0; // PD0
latchPin = 1; // PD1
clockPin = 2; // PD2
Schieberegister schreiben 74HC595
procedure shiftOut595(val: Byte);
var
i: Byte;
begin
for i := 7 downto 0 do begin // MSBFIRST
if (val and (1 shl i)) <> 0 then begin
WritePortD(dataOutPin, True);
end else begin
WritePortD(dataOutPin, False);
end;
WritePortD(clockPin, True);
WritePortD(clockPin, False);
end;
end;
Schieberegister lesen 74HC165
function ShiftIn165: Byte;
var
i: Byte;
begin
Result := 0;
for i := 0 to 7 do begin // LSBFIRST
Result := (Result shl 1) or Byte(ReadPortB(dataInPin));
WritePortD(clockPin, True);
WritePortD(clockPin, False);
end;
end;
Schieberegister Arduino
Diese Version entspricht dem shiftIn von Arduino.
function ShiftIn: Byte;
var
i: Byte;
begin
Result := 0;
for i := 0 to 7 do begin // LSBFIRST
WritePortD(clockPin, True);
Result := (Result shl 1) or Byte(ReadPortB(dataInPin));
WritePortD(clockPin, False);
end;
end;
Beispiel für die Verwendung der Schieberegister
Lesen von einem Schieberegister
Bevor man das Schieberegister auslesen kann, muss der Portzustand in das Latchregister geschrieben werden, dies geschieht über den LatchPin.
Beispiel für ein 74HC165
var
b: Byte;
begin
// Daten in Latch
WritePortD(latchPin, False);
WritePortD(latchPin, True);
// Schieberegister auslesen
b := ShiftIn74HC165;
Beispiel für kaskadierte 74HC165
var
b0, bn: Byte;
begin
// Daten in Latch
WritePortD(latchPin, False);
WritePortD(latchPin, True);
// Schieberegister auslesen
b0 := ShiftIn74HC165;
//...
bn := ShiftIn74HC165;
Schreiben in ein Schieberegister
Wen die Daten in das Schieberegister geschrieben sind, muss man noch den Latch Takten, das die aktuellen Ausgänge aktiv werden.
Beispiel für ein 74HC595
var
b: Byte;
begin
b := 123;
// Schieberegister auslesen
shiftOut595(b);
// Daten in Latch
WritePortD(latchPin, False);
WritePortD(latchPin, True);
Beispiel für kaskadierte 74HC595
var
b0, bn: Byte;
begin
b := 123;
// Schieberegister auslesen
shiftOut595(b0);
// ...
shiftOut595(bn);
// Daten in Latch
WritePortD(latchPin, False);
WritePortD(latchPin, True);