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

From Lazarus wiki
Jump to navigationJump to search
Line 18: Line 18:
  
 
Die Ausgabe erfolgt über zwei Schieberegister (74HC595). Wen der AVR genügend GPIO hat, kann man dies auch über diese machen.
 
Die Ausgabe erfolgt über zwei Schieberegister (74HC595). Wen der AVR genügend GPIO hat, kann man dies auch über diese machen.
 +
 +
====Digits Konstante für 7-Segmentanzeige====
 +
In dieser Konstante sind die LED-Kombinationen der Ziffern gespeichert. Zusätzlich sind noch HEX-Zeichen, Blank und Minus gespeichert.
 +
<syntaxhighlight lang="pascal">
 +
const
 +
  digits: packed array[0..17] of byte = (
 +
    %00111111,  // = 0
 +
    %00110000,  // = 1
 +
    %10011011,  // = 2
 +
    %10111001,  // = 3
 +
    %10110100,  // = 4
 +
    %10101101,  // = 5
 +
    %10101111,  // = 6
 +
    %00111000,  // = 7
 +
    %10111111,  // = 8
 +
    %10111101,  // = 9
 +
 +
    %10110111,  // = a
 +
    %10111100,  // = b
 +
    %10111001,  // = c
 +
    %10011110,  // = d
 +
    %10111001,  // = e
 +
    %10110001,  // = f
 +
    %00000000,  // = blank
 +
    %10000000); // = -
 +
</syntaxhighlight>
  
 
====Multiplex====
 
====Multiplex====
Line 28: Line 54:
 
     p: byte = 0;
 
     p: byte = 0;
 
   begin
 
   begin
     p := p + 1;
+
     p := p + 1;                   // Anzeigen durchzählen
 
     if (p > 3) then begin
 
     if (p > 3) then begin
 
       p := 0;
 
       p := 0;
Line 36: Line 62:
 
     WritePortD(latchPin, True);
 
     WritePortD(latchPin, True);
  
     shiftOut595(digits[zahl[p]]);
+
     shiftOut595(digits[zahl[p]]); // Digit aus Tabelle
     shiftOut595(1 shl p);
+
     shiftOut595(1 shl p);         // Zu zeigende Anzeige
 
   end;
 
   end;
 
</syntaxhighlight>
 
</syntaxhighlight>

Revision as of 00:06, 10 November 2017

Warning-icon.png

Warnung: In Arbeit

Multiplex

Portzugriffe

Wie die Schieberegisterbefehle auf die Ports zugreifen, siehe hier: GPIO-Ausgabe.
Nicht vergessen die Ausgänge auch als Ausgang einzustellen (DDRx).

AVR Embedded Tutorial - Shiftregister/de

Beispiel

Als Beispiel wird eine 4-stellige 7-Segmentanzeige angesteuert.

var
  zahl: array[0..3] of byte;

Bei jedem Timerdurchlauf, wird ein anderes Segment angesteuert. Somit muss der Timer 4 mal durchlaufen, bis ein Frame aktualisiert ist. Für eine konstante Wiederholfrequenz, ist der Timer am besten geeignet, da er regelmässig aufgerufen wird. Man könnte ein Multiplex auch in der Hauptloop machen, aber wen dort eine kleine Pause vorkommt, dann fängt die Anzeige an zu flackern.

Die Ausgabe erfolgt über zwei Schieberegister (74HC595). Wen der AVR genügend GPIO hat, kann man dies auch über diese machen.

Digits Konstante für 7-Segmentanzeige

In dieser Konstante sind die LED-Kombinationen der Ziffern gespeichert. Zusätzlich sind noch HEX-Zeichen, Blank und Minus gespeichert.

const
  digits: packed array[0..17] of byte = (
    %00111111,  // = 0
    %00110000,  // = 1
    %10011011,  // = 2
    %10111001,  // = 3
    %10110100,  // = 4
    %10101101,  // = 5
    %10101111,  // = 6
    %00111000,  // = 7
    %10111111,  // = 8
    %10111101,  // = 9

    %10110111,  // = a
    %10111100,  // = b
    %10111001,  // = c
    %10011110,  // = d
    %10111001,  // = e
    %10110001,  // = f
    %00000000,  // = blank
    %10000000); // = -

Multiplex

Das ist das Herz des Multiplexes.

  procedure Timer0_Interrupt; public Name 'TIMER0_COMPA_ISR'; interrupt;
  var
    d: integer;
  const
    p: byte = 0;
  begin
    p := p + 1;                    // Anzeigen durchzählen 
    if (p > 3) then begin
      p := 0;
    end;

    WritePortD(latchPin, False);
    WritePortD(latchPin, True);

    shiftOut595(digits[zahl[p]]);  // Digit aus Tabelle
    shiftOut595(1 shl p);          // Zu zeigende Anzeige
  end;

Delay

Ein einfaches Delay.

procedure delay;
var
  i: integer;
begin
  for i := 0 to 200 do asm Nop end;
end;

Initialisierung und Hauptloop

begin
  cli();
  
  // Ports auf Ausgabe schalten.
  ModePortD(dataOutPin, True);
  ModePortD(latchPin, True);
  ModePortD(clockPin, True);

  // -- Timer initialisieren
  TCCR0A := (1 shl WGM01);
  TCCR0B := TCCR0B or %101;
  TIMSK := TIMSK or (1 shl OCIE0A);
  sei();
  // --- Ende timer
  repeat
    zahl[0] := 1;
    zahl[1] := 2;
    zahl[2] := 3;
    zahl[3] := 4;
    delay;

    zahl[0] := 5;
    zahl[1] := 6;
    zahl[2] := 7;
    zahl[3] := 8;
    delay;
  until 1 = 2;
end.