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

From Lazarus wiki
Jump to navigationJump to search
m (Fixed template loop; modded categories to German; added language category)
m (→‎Initialisierung und Hauptschleife: Updated page link to bypass redirect page)
 
(11 intermediate revisions by one other user not shown)
Line 22: Line 22:
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
const
 
const
   Digit: packed array[0..15] of byte = (
+
   digits: packed array[0..15] of byte = (
 
   %00111111,  // = 0
 
   %00111111,  // = 0
 
   %00000110,  // = 1
 
   %00000110,  // = 1
Line 33: Line 33:
 
   %01111111,  // = 8
 
   %01111111,  // = 8
 
   %01100111,  // = 9
 
   %01100111,  // = 9
   %01110111,  // = a
+
   %01110111,  // = a Für Hex-Ausgabe
 
   %01111100,  // = b
 
   %01111100,  // = b
 
   %00111001,  // = c
 
   %00111001,  // = c
Line 47: Line 47:
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
const
 
const
   anzDigit = 4;
+
   DigitCount = 4;
 
var
 
var
   Digit: array[0..anzDigit - 1] of byte;
+
   Number: array[0..DigitCount - 1] of byte;
 
</syntaxhighlight>
 
</syntaxhighlight>
 
  
 
====Multiplex====
 
====Multiplex====
  
Das ist das Herz des Multiplexes. Bei jedem Durchlauf des Timers, wird das Segment gewechselt. Wen man dies sehen will, muss man die Timerfrequenz reduzieren, das man dies von Auge sieht.Für dieses Beispiel wird der Timer0 verwendet.
+
Das ist das Herz des Multiplexes. Bei jedem Durchlauf des Timers, wird das Segment gewechselt. Wen man dies sehen will, muss man die Timerfrequenz reduzieren, das man dies von Auge sieht. Für dieses Beispiel wird der '''Timer0''' verwendet.
  
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
Line 63: Line 62:
 
   begin
 
   begin
 
     segPos := segPos + 1;
 
     segPos := segPos + 1;
     if (segPos > anzSegment - 1) then begin
+
     if (segPos > DigitCount - 1) then begin
 
       segPos := 0;
 
       segPos := 0;
 
     end;
 
     end;
Line 70: Line 69:
 
     WritePortA(latchPin, True);
 
     WritePortA(latchPin, True);
  
     shiftOut595(digits[Digit[segPos]]); // Aktuelle Ziffer im Segment ansteuern.
+
     shiftOut595(digits[Number[segPos]]); // Aktuelle Ziffer im Segment ansteuern.
     shiftOut595(1 shl segPos);         // Aktuelles Segment aktivieren.
+
     shiftOut595(1 shl segPos);           // Aktuelles Segment aktivieren.
 
   end;
 
   end;
 
</syntaxhighlight>
 
</syntaxhighlight>
Line 94: Line 93:
 
Genaueres über Timer hier:
 
Genaueres über Timer hier:
  
* [[AVR Embedded Tutorial - Timer/Counter/de|Timer]]
+
* [[AVR Embedded Tutorial - Timer, Counter/de|Timer]]
 +
 
 +
Dieses Beispiel gibt Abwechselnd 1234 und 5678 aus.
  
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
Line 114: Line 115:
 
   // Hauptschleife
 
   // Hauptschleife
 
   repeat
 
   repeat
     Digit[0] := 1;
+
     Number[0] := 1;
     Digit[1] := 2;
+
     Number[1] := 2;
     Digit[2] := 3;
+
     Number[2] := 3;
     Digit[3] := 4;
+
     Number[3] := 4;
 
     delay;
 
     delay;
  
     Digit[0] := 5;
+
     Number[0] := 5;
     Digit[1] := 6;
+
     Number[1] := 6;
     Digit[2] := 7;
+
     Number[2] := 7;
     Digit[3] := 8;
+
     Number[3] := 8;
 
     delay;
 
     delay;
 
   until 1 = 2;
 
   until 1 = 2;

Latest revision as of 22:40, 2 February 2020

Deutsch (de) English (en)

Multiplex

Portzugriffe

Wie die Schieberegisterbefehle auf die Ports zugreifen, siehe hier:

Beispiel

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 gespeichert.

const
  digits: packed array[0..15] of byte = (
  %00111111,  // = 0
  %00000110,  // = 1
  %01011011,  // = 2
  %01001111,  // = 3
  %01100110,  // = 4
  %01101101,  // = 5
  %01111101,  // = 6
  %00000111,  // = 7
  %01111111,  // = 8
  %01100111,  // = 9
  %01110111,  // = a Für Hex-Ausgabe
  %01111100,  // = b
  %00111001,  // = c
  %01011110,  // = d
  %01111001,  // = e
  %01110001); // = f

Werte der einzelnen Segmente

Als Beispiel wird eine 4-stellige 7-Segmentanzeige angesteuert. Wen man einen grösseren Multiplex will, muss man dies Zahl erhöhen.

const
  DigitCount = 4;
var
  Number: array[0..DigitCount - 1] of byte;

Multiplex

Das ist das Herz des Multiplexes. Bei jedem Durchlauf des Timers, wird das Segment gewechselt. Wen man dies sehen will, muss man die Timerfrequenz reduzieren, das man dies von Auge sieht. Für dieses Beispiel wird der Timer0 verwendet.

  procedure Timer0_Interrupt; public Name 'TIM0_COMPA_ISR'; interrupt;
  const
    segPos: byte = 0;
  begin
    segPos := segPos + 1;
    if (segPos > DigitCount - 1) then begin
      segPos := 0;
    end;

    WritePortA(latchPin, False);
    WritePortA(latchPin, True);

    shiftOut595(digits[Number[segPos]]); // Aktuelle Ziffer im Segment ansteuern.
    shiftOut595(1 shl segPos);           // Aktuelles Segment aktivieren.
  end;

Delay

Ein einfaches Delay. dies wird beim Zifferwechsel in der Hauptschleife benötigt.

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

Initialisierung und Hauptschleife

Hier der Timer0 für den Mutiplex initialisiert, auch werden die benötigten Port auf Ausgabe geschalten.

Genaueres über Timer hier:

Dieses Beispiel gibt Abwechselnd 1234 und 5678 aus.

begin
  // Interrupt sperren.
  asm cli end;

  // Ports auf Ausgabe schalten.
  DDRA := (1 shl dataOutPin) or (1 shl latchPin) or (1 shl clockPin);

  // -- Timer initialisieren
  TCCR0A := (1 shl 1);
  TCCR0B := TCCR0B or %101;
  TIMSK0 := TIMSK0 or (1 shl OCIE0A);

  // Interrupt frei geben.
  asm sei end;

  // Hauptschleife
  repeat
    Number[0] := 1;
    Number[1] := 2;
    Number[2] := 3;
    Number[3] := 4;
    delay;

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

Siehe auch

Autor: Mathias