Difference between revisions of "AVR Embedded Tutorial - Multiplex/de"
m (→Initialisierung und Hauptschleife: Updated page link to bypass redirect page) |
|||
(16 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | {{ | + | {{LanguageBar}} |
=Multiplex= | =Multiplex= | ||
==Portzugriffe== | ==Portzugriffe== | ||
− | |||
− | * [[AVR Embedded Tutorial - Shiftregister/de]] | + | Wie die Schieberegisterbefehle auf die Ports zugreifen, siehe hier: |
+ | |||
+ | * [[AVR Embedded Tutorial - Simple GPIO on and off output/de|GPIO]] | ||
+ | * [[AVR Embedded Tutorial - Shiftregister/de|Schieberegister]] | ||
==Beispiel== | ==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. | 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. | 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. | In dieser Konstante sind die LED-Kombinationen der Ziffern gespeichert. Zusätzlich sind noch HEX-Zeichen gespeichert. | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
const | const | ||
− | + | digits: packed array[0..15] of byte = ( | |
%00111111, // = 0 | %00111111, // = 0 | ||
%00000110, // = 1 | %00000110, // = 1 | ||
Line 32: | 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 41: | Line 42: | ||
====Werte der einzelnen Segmente==== | ====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. | Als Beispiel wird eine 4-stellige 7-Segmentanzeige angesteuert. Wen man einen grösseren Multiplex will, muss man dies Zahl erhöhen. | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
const | const | ||
− | + | DigitCount = 4; | |
var | var | ||
− | + | Number: array[0..DigitCount - 1] of byte; | |
</syntaxhighlight> | </syntaxhighlight> | ||
+ | ====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. | ||
− | |||
− | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
procedure Timer0_Interrupt; public Name 'TIM0_COMPA_ISR'; interrupt; | procedure Timer0_Interrupt; public Name 'TIM0_COMPA_ISR'; interrupt; | ||
Line 58: | Line 62: | ||
begin | begin | ||
segPos := segPos + 1; | segPos := segPos + 1; | ||
− | if (segPos > | + | if (segPos > DigitCount - 1) then begin |
segPos := 0; | segPos := 0; | ||
end; | end; | ||
Line 65: | Line 69: | ||
WritePortA(latchPin, True); | WritePortA(latchPin, True); | ||
− | shiftOut595(digits[ | + | shiftOut595(digits[Number[segPos]]); // Aktuelle Ziffer im Segment ansteuern. |
− | shiftOut595(1 shl segPos); | + | shiftOut595(1 shl segPos); // Aktuelles Segment aktivieren. |
end; | end; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
====Delay==== | ====Delay==== | ||
+ | |||
Ein einfaches Delay. dies wird beim Zifferwechsel in der Hauptschleife benötigt. | Ein einfaches Delay. dies wird beim Zifferwechsel in der Hauptschleife benötigt. | ||
+ | |||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
procedure delay; | procedure delay; | ||
Line 82: | Line 88: | ||
====Initialisierung und Hauptschleife==== | ====Initialisierung und Hauptschleife==== | ||
+ | |||
Hier der Timer0 für den Mutiplex initialisiert, auch werden die benötigten Port auf Ausgabe geschalten. | Hier der Timer0 für den Mutiplex initialisiert, auch werden die benötigten Port auf Ausgabe geschalten. | ||
− | Genaueres über Timer hier: [[AVR Embedded Tutorial - Timer | + | Genaueres über Timer hier: |
+ | |||
+ | * [[AVR Embedded Tutorial - Timer, Counter/de|Timer]] | ||
+ | |||
+ | Dieses Beispiel gibt Abwechselnd 1234 und 5678 aus. | ||
<syntaxhighlight lang="pascal"> | <syntaxhighlight lang="pascal"> | ||
Line 104: | Line 115: | ||
// Hauptschleife | // Hauptschleife | ||
repeat | repeat | ||
− | + | Number[0] := 1; | |
− | + | Number[1] := 2; | |
− | + | Number[2] := 3; | |
− | + | Number[3] := 4; | |
delay; | delay; | ||
− | + | Number[0] := 5; | |
− | + | Number[1] := 6; | |
− | + | Number[2] := 7; | |
− | + | Number[3] := 8; | |
delay; | delay; | ||
until 1 = 2; | until 1 = 2; | ||
Line 119: | Line 130: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | = Siehe auch = | |
− | * Übersichtseite [[AVR Embedded Tutorial/de]] | + | |
+ | * Übersichtseite [[AVR Embedded Tutorial/de|AVR Embedded Tutorial]] | ||
+ | |||
+ | Autor: [[User:Mathias|Mathias]] | ||
− | [[Category: | + | [[Category:AVR/de]] |
− | [[Category: | + | [[Category:Arduino/de]] |
− | [[Category: | + | [[Category:Embedded/de]] |
+ | [[Category:Tutorials/de]] | ||
+ | {{AutoCategory}} |
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
- Übersichtseite AVR Embedded Tutorial
Autor: Mathias