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

From Lazarus wiki
Jump to navigationJump to search
 
(25 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Translate}}
+
{{LanguageBar}}
  
 
=Schieberegister=
 
=Schieberegister=
Der Beispielcode ist für ein ATtiny2313.
+
 
 +
Der Beispielcode ist für ein ATtiny44.
 +
 
 
Schieberegister werden folgende verwendet:
 
Schieberegister werden folgende verwendet:
 +
 
* Lesen: 74HC165
 
* Lesen: 74HC165
 
* Schreiben: 74HC595.
 
* 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.
+
 
 +
{{Warning|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.
 
Will man '''MSB''' und '''LSB''' vertauschen, dann muss man dementsprechend einfach '''to''' mit '''downto''' austauschen.
  
 
==Portzugriffe==
 
==Portzugriffe==
 +
 
Wie die Schieberegisterbefehle auf die Ports zugreifen, siehe hier: [[AVR Embedded Tutorial - Simple GPIO on and off output/de|GPIO-Ausgabe]].<br>Nicht vergessen die Ausgänge auch als Ausgang einzustellen (DDRx).
 
Wie die Schieberegisterbefehle auf die Ports zugreifen, siehe hier: [[AVR Embedded Tutorial - Simple GPIO on and off output/de|GPIO-Ausgabe]].<br>Nicht vergessen die Ausgänge auch als Ausgang einzustellen (DDRx).
  
 
==Port-Konstanten==
 
==Port-Konstanten==
Die verwendeten Pins des ATtiny2313 und der Shiftregister. Beim AVR kann man beliebige Pins nehmen.
+
 
 +
Die verwendeten Pins des ATtiny44 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.
 
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.
  
 
{| class="wikitable"
 
{| class="wikitable"
!IC        !! colspan="2"| Attiny2313 !! colspan="2"| 74HC165 !! colspan="2"| 74HC595  
+
!IC        !! colspan="2"| Attiny44 !! colspan="2"| 74HC165 !! colspan="2"| 74HC595  
 
|-
 
|-
 
!          !! PinNr !! Bezeichnung    !! PinNr !!Bezeichnung  !! PinNr !! Bezeichnung
 
!          !! PinNr !! Bezeichnung    !! PinNr !!Bezeichnung  !! PinNr !! Bezeichnung
 
|-
 
|-
|dataInPin  || 12    || PB0           || 10    || DS          ||      ||  
+
|dataOutPin || 13    || PA0            ||      ||            || 14    || DS
 +
|-
 +
|dataInPin  || 12    || PA1           || 10    || DS          ||      ||  
 
|-
 
|-
|dataOutPin || 2    || PD0            ||      ||            || 14    || DS
+
|latchPin  || 11    || PA2           || 1    || PL          || 12    || ST_CP
|-
 
|latchPin  || 3    || PD1           || 1    || PL          || 12    || ST_CP
 
 
|-
 
|-
|clockPin  || 6    || PD2           || 2    || CP          || 11    || SH_CP
+
|clockPin  || 10    || PA3           || 2    || CP          || 11    || SH_CP
 
|}
 
|}
 +
 +
Für den Port wird eine Variable deklariert, dies hat den Vorteil, das man nicht alle Ports in den Shiftregister-Funktionen ändern muss.
  
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 +
var
 +
  shiftPORT: byte absolute PORTA;
 +
  shiftDDR:  byte absolute DDRA;
 +
  shiftPIN:  byte absolute PINA;
 
const
 
const
   // PortB       
+
   dataOutPin = 0;
  dataInPin  = 0; // PB0
+
   dataInPin  = 1;
 
+
   latchPin  = 2;
   // PortD
+
   clockPin  = 3;
  dataOutPin = 0; // PD0
 
   latchPin  = 1; // PD1
 
   clockPin  = 2; // PD2
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
==Schieberegister schreiben 74HC595==
 
==Schieberegister schreiben 74HC595==
 +
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
procedure shiftOut595(val: Byte);
 
procedure shiftOut595(val: Byte);
Line 50: Line 60:
 
   for i := 7 downto 0 do begin  // MSBFIRST
 
   for i := 7 downto 0 do begin  // MSBFIRST
 
     if (val and (1 shl i)) <> 0 then begin
 
     if (val and (1 shl i)) <> 0 then begin
       WritePortD(dataOutPin, True);
+
       shiftPORT := shiftPORT or (1 shl dataOutPin);
 
     end else begin
 
     end else begin
       WritePortD(dataOutPin, False);
+
       shiftPORT := shiftPORT and not (1 shl dataOutPin);
 
     end;
 
     end;
     WritePortD(clockPin, True);
+
     shiftPORT := shiftPORT or (1 shl clockPin);
     WritePortD(clockPin, False);
+
     shiftPORT := shiftPORT and not (1 shl clockPin);
 
   end;
 
   end;
 
end;
 
end;
Line 61: Line 71:
  
 
==Schieberegister lesen 74HC165==
 
==Schieberegister lesen 74HC165==
 +
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
function ShiftIn165: Byte;
 
function ShiftIn165: Byte;
Line 68: Line 79:
 
   Result := 0;
 
   Result := 0;
 
   for i := 0 to 7 do begin  // LSBFIRST
 
   for i := 0 to 7 do begin  // LSBFIRST
     Result := (Result shl 1) or Byte(ReadPortB(dataInPin));
+
     Result   := (Result shl 1) or ((shiftPIN and (1 shl dataInPin)) shr dataInPin);
     WritePortD(clockPin, True);
+
     shiftPORT := shiftPORT or (1 shl clockPin);
     WritePortD(clockPin, False);
+
     shiftPORT := shiftPORT and not (1 shl clockPin);
 
   end;
 
   end;
end;</syntaxhighlight>
+
end;
 +
</syntaxhighlight>
  
 
==Schieberegister Arduino==
 
==Schieberegister Arduino==
 +
 
Diese Version entspricht dem '''shiftIn''' von Arduino.
 
Diese Version entspricht dem '''shiftIn''' von Arduino.
 +
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
function ShiftIn: Byte;
 
function ShiftIn: Byte;
Line 83: Line 97:
 
   Result := 0;
 
   Result := 0;
 
   for i := 0 to 7 do begin  // LSBFIRST
 
   for i := 0 to 7 do begin  // LSBFIRST
     WritePortD(clockPin, True);
+
     shiftPORT := shiftPORT or (1 shl clockPin);
     Result := (Result shl 1) or Byte(ReadPortB(dataInPin));
+
     Result   := (Result shl 1) or ((shiftPIN and (1 shl dataInPin)) shr dataInPin);
     WritePortD(clockPin, False);
+
     shiftPORT := shiftPORT and not (1 shl clockPin);
 
   end;
 
   end;
 
end;
 
end;
Line 93: Line 107:
  
 
===Lesen von einem Schieberegister===
 
===Lesen von einem Schieberegister===
 +
 
Bevor man das Schieberegister auslesen kann, muss der Portzustand in das Latchregister geschrieben werden, dies geschieht über den  
 
Bevor man das Schieberegister auslesen kann, muss der Portzustand in das Latchregister geschrieben werden, dies geschieht über den  
 
LatchPin.
 
LatchPin.
  
 
====Beispiel für ein 74HC165====
 
====Beispiel für ein 74HC165====
 +
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
var
 
var
Line 103: Line 119:
  
 
   // Daten in Latch
 
   // Daten in Latch
   WritePortD(latchPin, False);
+
   shiftPORT := shiftPORT and not (1 shl latchPin);
   WritePortD(latchPin, True);
+
   shiftPORT := shiftPORT or (1 shl latchPin);
  
   // Schieberegister beschreiben
+
   // Schieberegister auslesen
 
   b := ShiftIn74HC165;
 
   b := ShiftIn74HC165;
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
====Beispiel für kaskadierte 74HC165====
  
====Beispiel für kaskadierte 74HC165====
 
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
var
 
var
Line 118: Line 134:
  
 
   // Daten in Latch
 
   // Daten in Latch
   WritePortD(latchPin, False);
+
   shiftPORT := shiftPORT and not (1 shl latchPin);
   WritePortD(latchPin, True);
+
   shiftPORT := shiftPORT or (1 shl latchPin);
  
   // Schieberegister beschreiben
+
   // Schieberegister auslesen
 
   b0 := ShiftIn74HC165;
 
   b0 := ShiftIn74HC165;
 
   //...
 
   //...
Line 128: Line 144:
  
 
===Schreiben in ein Schieberegister===
 
===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.
 
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====
 
====Beispiel für ein 74HC595====
 +
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
var
 
var
Line 137: Line 155:
 
   b := 123;
 
   b := 123;
  
   // Schieberegister auslesen
+
   // Schieberegister schreiben
 
   shiftOut595(b);
 
   shiftOut595(b);
  
 
   // Daten in Latch
 
   // Daten in Latch
   WritePortD(latchPin, False);
+
   shiftPORT := shiftPORT and not (1 shl latchPin);
   WritePortD(latchPin, True);
+
   shiftPORT := shiftPORT or (1 shl latchPin);
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
====Beispiel für kaskadierte 74HC595====
  
====Beispiel für kaskadierte 74HC595====
 
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
var
 
var
 
   b0, bn: Byte;
 
   b0, bn: Byte;
 
begin
 
begin
   b := 123;
+
   b0 := 123;
 +
  //...
 +
  bn := 789;
  
   // Schieberegister auslesen
+
   // Schieberegister schreiben
 
   shiftOut595(b0);
 
   shiftOut595(b0);
 
   // ...
 
   // ...
Line 159: Line 179:
  
 
   // Daten in Latch
 
   // Daten in Latch
   WritePortD(latchPin, False);
+
   shiftPORT := shiftPORT and not (1 shl latchPin);
   WritePortD(latchPin, True);
+
   shiftPORT := shiftPORT or (1 shl latchPin);
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
= Siehe auch =
 +
 +
* Übersichtseite [[AVR Embedded Tutorial/de|AVR Embedded Tutorials]]
 +
* [[AVR Embedded Tutorial - SPI Shiftregister/de|SPI Schieberegister]] - Schieberegister 74HC595 über SPI ansteuern (starke Beschleunigung).
 +
 +
Autor: [[User:Mathias|Mathias]]
  
[[Category:AVR]] {{AutoCategory}}
+
[[Category:AVR/de]]
 +
[[Category:Arduino/de]]
 +
[[Category:Embedded/de]]
 +
[[Category:Tutorials/de]]
 +
{{AutoCategory}}

Latest revision as of 14:21, 3 August 2023

Deutsch (de) English (en)

Schieberegister

Der Beispielcode ist für ein ATtiny44.

Schieberegister werden folgende verwendet:

  • Lesen: 74HC165
  • Schreiben: 74HC595.
Warning-icon.png

Warnung: 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 ATtiny44 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 Attiny44 74HC165 74HC595
PinNr Bezeichnung PinNr Bezeichnung PinNr Bezeichnung
dataOutPin 13 PA0 14 DS
dataInPin 12 PA1 10 DS
latchPin 11 PA2 1 PL 12 ST_CP
clockPin 10 PA3 2 CP 11 SH_CP

Für den Port wird eine Variable deklariert, dies hat den Vorteil, das man nicht alle Ports in den Shiftregister-Funktionen ändern muss.

var
  shiftPORT: byte absolute PORTA;
  shiftDDR:  byte absolute DDRA;
  shiftPIN:  byte absolute PINA;
const
  dataOutPin = 0;
  dataInPin  = 1;
  latchPin   = 2;
  clockPin   = 3;

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
      shiftPORT := shiftPORT or (1 shl dataOutPin);
    end else begin
      shiftPORT := shiftPORT and not (1 shl dataOutPin);
    end;
    shiftPORT := shiftPORT or (1 shl clockPin);
    shiftPORT := shiftPORT and not (1 shl clockPin);
  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 ((shiftPIN and (1 shl dataInPin)) shr dataInPin);
    shiftPORT := shiftPORT or (1 shl clockPin);
    shiftPORT := shiftPORT and not (1 shl clockPin);
  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
    shiftPORT := shiftPORT or (1 shl clockPin);
    Result    := (Result shl 1) or ((shiftPIN and (1 shl dataInPin)) shr dataInPin);
    shiftPORT := shiftPORT and not (1 shl clockPin);
  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
  shiftPORT := shiftPORT and not (1 shl latchPin);
  shiftPORT := shiftPORT or (1 shl latchPin);

  // Schieberegister auslesen
  b := ShiftIn74HC165;

Beispiel für kaskadierte 74HC165

var
  b0, bn: Byte;
begin

  // Daten in Latch
  shiftPORT := shiftPORT and not (1 shl latchPin);
  shiftPORT := shiftPORT or (1 shl latchPin);

  // 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 schreiben
  shiftOut595(b);

  // Daten in Latch
  shiftPORT := shiftPORT and not (1 shl latchPin);
  shiftPORT := shiftPORT or (1 shl latchPin);

Beispiel für kaskadierte 74HC595

var
  b0, bn: Byte;
begin
  b0 := 123;
  //...
  bn := 789;

  // Schieberegister schreiben
  shiftOut595(b0);
  // ...
  shiftOut595(bn);

  // Daten in Latch
  shiftPORT := shiftPORT and not (1 shl latchPin);
  shiftPORT := shiftPORT or (1 shl latchPin);

Siehe auch

Autor: Mathias