PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 7-Segmentanzeige Steuerung mit mehrdim. Array?



Powell
03.02.2011, 20:24
Hallo zusammen,

habe ein projekt wo ich 10 7-Segmentanzeigen multiplexe und bin mir nicht sicher bezüglich der Software, zum einen ob meine Idee so clever ist und zum anderen wie ich es in code umsetzen kann.

Ich betreibe das ganze an einem ATMega32. So sieht es aus:

Über ein Poti lese ich einen Zahlenwert (Word, 0-1023) ein, der über fünf 7-segmentanzeigen mit einem Vorfaktor als fünfstellige Zahl ausgegeben werden solle. (Z.B.: Poti = 768 -> Anzeige: 20 * 768 = 15.360)

Jede der 7-Segmentanzeigen hat nun 7+1 (Punkt) = 8 verschiedene LEDs deren individuelle zusammensetzung eine bestimmte Zahl ergibt (z.B. "7.")
Pro 7 Segment-Anzeige also ein 8er Array mit binärwerten (1 oder 0)

Weiterhin werden die 5 Anzeigen gemultiplext, heißt also neben dem 7-segment-zustands array (sprich welche ziffer zeigt diese anzeige an) brauche ich noch ein multiplex array was durch einen timer-interrupt permanent inkrementiert wird.

Von diesen 5er Anzeigen gibt es jetzt 2 Stück, also insgesamt 10 die gemultiplext werden.

So schön die Theorie, jetzt habe ich aber keine ahnung wie ich das ganze in bascom implementiere (die hilfe zu arrays ist sehr dürftig). Alles was ich daraus mitnehmen kann ist dass man "dim multiplexer(10) as byte" schreiben könnte. Würde auch perfekt passen, denn mit 8 verschiedenen LEDs pro Anzeige könnte man schön sagen "Wert 234 entspricht z.B. der 7." Vielleicht kann mir hier wer weiterhelfen, habe noch nie mit arrays in bascom gearbeitet, danke!

for_ro
03.02.2011, 20:50
Genau so würde ich es auch machen.
Wenn du die 8 Segmente dann an einen Port anschließt, brauchst du den Port nur auf das jeweilige Byte zu setzen und den Common Pin einzuschalten.
Die 7-Segment Werte kannst du dir auch in ein Array legen.
Dann sieht die Ausgabe z.B. so aus:
Config Base = 0 'deine Arrays beginnen mit Index 0
Dim Segmente(10) as Byte
Dim Multiplexer(10) as Byte

Am besten im Timer steht dann
Portx = Segmente(Multiplexer(index))

chr-mt
03.02.2011, 20:52
Hi,
du kannst das auch über eine Lookup Table machen.
Ich habe das mal für eine Uhr-Anzeige so gemacht, daß ich einen kompletten Zeichensatz, inklusive Buchstaben (so gut das eben auf 7 Segmenten geht) in eine Tabelle geschrieben habe.
Über den ASCII Code konnte ich dann direkt das entsprechende Zeichen ausgeben. Fand' ich recht praktisch. ;)

Gruß
Christopher

Powell
03.02.2011, 21:09
Vielen Dank ihr zwei, hat mir schon mal weitergeholfen.

Wie kann ich das machen wenn ich aus platzgründen nicht alles an einen Port anschließen kann?

@ christopher: kannst du ggf. mal ein codebeispiel posten? Weiß leider nicht wie man eine Lookup Table macht, hatte aber auch schon an sowas wie ne matrix gedacht...

Powell
03.02.2011, 21:14
Ah und noch etwas bevor ich es vergesse (da lag noch so ein bisschen ein problem bei mir): Wie lese ich ein Array schnell ein ohne eine iterationsschleife machen zu müssen?

Dachte mir das irgendwie so: Segmente = (1, 0 , 1, 0, 1, 1, 1, 0)

Macht der Compiler aber nicht...

chr-mt
03.02.2011, 21:35
kannst du ggf. mal ein codebeispiel posten?

Das ist ganz gut beim Befehl "lookup" beschrieben.

Hier mal ein Beispiel von mir...




'Angenommen der Wert für die 7-Segment - Anzeige ist eine 7
Dim Wert As Byte
Dim Ausgabe As Byte

Wert = 7
Ausgabe = Lookup(wert , Mein_zeichensatz) 'Aus der Tabelle holen

'In der Variablen "Ausgabe" steht jetzt das 7-Segment-Bitmuster für das Zeichen "7"
'und kann dann ausgegeben werden

Mein_zeichensatz:
Data &B11111100 '"0"
Data &B01100000 '"1"
Data &B11011010 '"2"
Data &B11110010 '"3"
Data &B01100110 '"4"
Data &B10110110 '"5"
Data &B10111110 '"6"
Data &B11100000 '"7"
Data &B11111110 '"8"
Data &B11110110 '"9"


'Man kann die Tabelle auch so schreiben:
Auch_mein_zeichensatz:
Data &B11111100 , &B01100000 , &B11011010 , &B11110010 , &B01100110 , &B10110110 , &B10111110 , &B11100000 , &B11111110 , &B11110110

'Allerdings finde ich es untereinander übersichtlicher, da man dann Kommentare dranhängen kann.


Übrigens muß zB. bei Integerwerten ein Prozentzeichen angehängt werden um die Daten als Integer zu kennzeichnen.
Ist in der Hilfe zwar so gemacht, aber bei Lookup nicht erklärt.
Wenn man da nicht drauf achtet, kann man sich kaputtsuchen.
Beim Befehl Restore steht da übrigens was dazu (ganz unten)

Gruß
Christopher

Powell
03.02.2011, 23:32
Hallo Christopher,

danke dir vielmals, dein Codebeispiel hat mir unglaublich weitergeholfen.

rossir
07.02.2011, 22:45
Mit Spass am Knobeln läßt sich auch eine Formel finden die den lookup durch direkte Berechnung ersetzt. Z.B.:
int lookup(int x) {
int tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
tmp2=x+1;
tmp1= x==2?-1:(x-1)/( x-2);
tmp5=tmp1;
tmp1-=tmp2;

tmp4=(tmp1+tmp5+1)%tmp1+2;
tmp1=70^tmp2;
tmp3=tmp1-2;
tmp1++;

tmp7=tmp1;
tmp6=2*(tmp1%tmp2) &tmp3;

tmp3-=3;
tmp1&=tmp3;
tmp2=(((tmp1+tmp3|tmp7)^tmp5 |tmp2)+4)|tmp7;
tmp1=(4|tmp7|tmp4)+tmp3;
tmp1^=2;
tmp1|=tmp7+1;
tmp1^=tmp5;
tmp1=tmp1/2+6;
tmp1|=tmp7+1;
return (tmp1^tmp2)+tmp7-((sign(tmp6)*tmp4+1)^1)-tmp6;
}Zugegeben, etwas häßlich und voluminös geraten. Vielleicht geht's ja eleganter? :cheesy:

E-Fan
27.02.2011, 17:15
@powel:
Warum zerpfückst Du Deine Variable nicht in ihre einzelnen Bestandteile und schickst die Daten per SPI an MAX7219/7221? Dann wär kein Array nötig in dem die dekodierten Werte abgelegt sind und die Steuerroutinen werden ebenfalls in die externe Hardware ausgelagert.
Ich muss mir eine Messwertanzeige mit mindestens 24 7-"Segmentern" basteln. An sich lässt sich das einfach durch einen an einen Timer gekoppelten Interrupt und zwei bis drei Befehlen zusammenschrauben, hab aber Bedenken das ich mir die Segmente zerschieße wenn der AVR mal hängen bleibt.

peterfido
27.02.2011, 21:52
Dafür gibt es zur Not den Watchdog.

Vitis
28.02.2011, 10:03
Das auf die Ports verteilen würd ich nicht raten, das geht auf die Performance
entweder die Bits auseinanderpfriemeln und verteilen oder mehrere
Bytes aus Tabellen holen und verodern / verunden mit den Ports ...
machbar aber nicht ideal.