PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 7 Segmentanzeige



TobiasBlome
14.08.2007, 17:42
Hallo,
ich möchte 4 7-Segmentanzeigen multiplexen. Das Programm läuft prinziepjell - aber da ist ein Problem:

wenn ich 123 auf der Anzeige haben möchte steht dort 1233 und nach einigen Sekunden warten steht dort plötzlich 3233

wenn ich 1234 auf der Anzeige haben möchte steht dort 2100 und nach einigen Sekunden warten steht dort plötzlich 0100


Kann mir da jemand helfen?


'7Segmentanzeige mit 4 Anzeigen

$regfile = "ATtiny2313.dat" 'ATTiny2313
$crystal = 20000000 '20MHz Quarz
Ddrb = &B11111111 'PortB = Ausgang (PB0=A usw.)
Ddrd = &B1111111 'PortD = Ausgang (PD3=Anzeige1, PD4=A2, PD5=A3, PD6=A4)




Dim Y As String * 5 At &H70
Dim Z(5) As Byte At &H70 Overlay
Dim Led As Word
Dim X(5) As Byte
Dim Test As Integer
Dim Test2 As Integer
Dim Zaehler As Byte 'für LED Anzeige wählen...

Enable Interrupts


Do

'LED:::EZHT
Led = 123 'LED - Anzeigewert

For Test2 = 0 To 6 'Wert sichern .....
X(test2) = Z(test2)
Next Test2



For Zaehler = 3 To 6 'Zaehler = PortD 3-6 Anzeige wählen)
Test = X(zaehler)
Select Case Test


'Led-Segmente als Zahlen definieren:
Case 48 : Portb = 63 'NULL
Case 49 : Portb = 6 'EINS
Case 50 : Portb = 91 'ZWEI
Case 51 : Portb = 79 'DREI
Case 52 : Portb = 102 'VIER
Case 53 : Portb = 109 'FÜNF
Case 54 : Portb = 125 'SECHS
Case 55 : Portb = 7 'SIEBEN
Case 56 : Portb = 127 'ACHT
Case 57 : Portb = 111 'NEUN
Case 58 : Portb = 128 'DP -> geht das als PORT zu setzen???
Case Else : Portb = 0
End Select

'Anzeige auswählen???
Portd.zaehler = 1
waitus 100 'Zeit für jede Anzeige
'zum testen Waitms 500 'waitus 100 'Zeit für jede Anzeige
Portd.zaehler = 0
Next Zaehler




Y = Str(led)
If Z(4) = 0 Then 'Führende Nullen eliminieren
Do
Z(5) = Z(4)
Z(4) = Z(3)
Z(3) = Z(2)
Z(2) = Z(1)
Z(1) = 0
Loop Until Z(5) > 0
End If



Loop

TobiasBlome
14.08.2007, 20:35
so, ich habe noch ein paar Variablen namen geändert

'7Segmentanzeige mit 4 Anzeigen

$regfile = "ATtiny2313.dat" 'ATTiny2313
$crystal = 20000000 '20MHz Quarz
Ddrb = &B11111111 'PortB = Ausgang (PB0=A usw.)
Ddrd = &B1111111 'PortD = Ausgang (PD3=Anzeige1, PD4=A2, PD5=A3, PD6=A4)

Dim Led2 As String * 5 At &H70
Dim Z(5) As Byte At &H70 Overlay
Dim Led As Word
Dim X(5) As Byte
Dim Test As Integer
Dim Test2 As Integer
Dim Anzeige_x As Byte 'für LED-Anzeige wählen...

Enable Interrupts


Do

'LED:=:EZHT
Led = 123 'LED - Anzeigewert

For Test2 = 0 To 5 'Wert sichern .....
X(test2) = Z(test2)
Next Test2




'Anzeige durchwechseln (hochzählen)
For Anzeige_x = 3 To 6 'Zaehler = PortD 3-6 Anzeige wählen)
Test = X(anzeige_x)
Select Case Test


'Led-Segmente als Zahlen definieren:
Case 48 : Portb = 63 'NULL
Case 49 : Portb = 6 'EINS
Case 50 : Portb = 91 'ZWEI
Case 51 : Portb = 79 'DREI
Case 52 : Portb = 102 'VIER
Case 53 : Portb = 109 'FÜNF
Case 54 : Portb = 125 'SECHS
Case 55 : Portb = 7 'SIEBEN
Case 56 : Portb = 127 'ACHT
Case 57 : Portb = 111 'NEUN
Case 58 : Portb = 128 'DP -> geht das als PORT zu setzen???
Case Else : Portb = 0
End Select


'Anzeige auswählen und Ein- / Ausschalten
Portd.anzeige_x = 1 'Anzeige AN
Waitus 100 'Zeit für jede Anzeige
'zum testen Waitms 500 'waitus 100 'Zeit für jede Anzeige
Portd.anzeige_x = 0 'Anzeige AUS
Next Anzeige_x


Led2 = Str(led)


If Z(4) = 0 Then 'Führende Nullen eliminieren
Do
Z(5) = Z(4)
Z(4) = Z(3)
Z(3) = Z(2)
Z(2) = Z(1)
Z(1) = 0
Loop Until Z(5) > 0
End If



Loop

TobiasBlome
15.08.2007, 15:53
Hat denn keiner eine Idee? vielleicht einen kleinen Vorschlag zum ausprobieren?

Tobias

Michael
15.08.2007, 16:48
Hallo TobiasBlome,


Hat denn keiner eine Idee?

Beim darüberfliegen fällt mir das ins Auge:
For Test2 = 0 To 5 'Wert sichern .....
X(test2) = Z(test2)
Next Test2

Dazu ein Text aus der Bascom-Hilfe:
The first element of an array is always one.

also nicht null ;)

Gruß, Michael

darwin.nuernberg
15.08.2007, 18:08
Für Multiplex-Anzeigen haben andere und ich son einiges hier im Forum beigetragen.

Warum die Ganze Brühe nochmals anwärmen?

Schau doch mal den folgenden Beitrag an:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=148650#148650

TobiasBlome
15.08.2007, 18:09
ja, da ist etwas drann...

hab´ ich sofort geändert. Aber es macht keinen Unterschied ob 1 oder 0 und das merkwürdige 2 oder 3 geht auch! Bei 4 fehlt die erste Zahl...

Aber vielleicht habe ich ja mehrere kleine Fehler!

Also vielen Dank,

Tobias

TobiasBlome
15.08.2007, 18:13
@darwin.nuernberg
NaJa, ich dachte: lass doch den µC arbeiten, dann kann man den BCD Konverter sparen... oder?

Tobias

TobiasBlome
15.08.2007, 18:15
@darwin.nuernberg
noch etwas: kann der BCD Konverter Kommastellen?

Tobias

darwin.nuernberg
15.08.2007, 18:16
Ja geht auch, wenn Du genug Ports frei hast, warum nicht.

Das Segmentdecoden ist auch kein akt, aber wenn das ganze in einer Schaltung mit mehreren Funktionen ist, dann muss man um jeden Pin Kämpfen.

EDIT:
Kommastellen : NEIN, das wäre ja dann das 8. Segment und das wird nicht als Zahl decodiert. Den muss man dann wieder zusätzlich ansteuern oder wie Du vor hattest mit einem kompletten Port (vom AVR) realisieren.

Also ein Port für die Decaden und ein zusätzlicher Port für die Segmente nebst dezimalpunkt.



https://www.roboternetz.de/phpBB2/album_thumbnail.php?pic_id=1415
Segmente a-g = 7 PLUS dezimapunkt = 8

Also ohne zusätzliche Harware maximal 8 Decaden (Anzeige) mit mind. 2 Ports realisierbar.

TobiasBlome
15.08.2007, 19:07
...aha...

Also weil ich die Hardware schon fertig habe, bleibe ich bei meiner Softwareansteuerung ohne BCD-Konverter.
Oder hat jemand ein fertiges Programm um die 7-Segmente anzusteuern (ohne BCD-Konverter)? Wie schon gesagt - warum das Rad 2x erfinden :-)

Tobias

darwin.nuernberg
15.08.2007, 19:38
Stell dich nicht so an...


Led_port Alias Portb ' Port An Den Die Segmente "hängen"
Dim Wer As String * 1 ' String einzelnes Zeichen der Zahl

' Port-Pin zu 7-segement - g f e d c b a

Select Case Wert
Case "0" : Led_port = &B00111111 ' hier die Port-Pins ansteuern,
Case "1" : Led_port = &B00000110 ' welche das Segment ansteuern soll
Case "2" : Led_port = &B01011011
Case "3" : Led_port = &B01001111
Case "4" : Led_port = &B01100110
Case "5" : Led_port = &B01101100
Case "6" : Led_port = &B01111101
Case "7" : Led_port = &B00000000
Case "8" : Led_port = &B00000111
Case "9" : Led_port = &B01101111
Case Else Led_port = &B00000000
End Select

TobiasBlome
15.08.2007, 19:48
???
wie - was meinst du damit: stell dich nicht so an?
Also mein Prog. steht doch schon oben drinn! NUR das die Funktion nicht die gewünschte ist... siehe ersten Beitrag. (oder hab ich etwas falsch verstanden?)

Tobias

peterfido
15.08.2007, 19:54
Ich habe das mal zu Fuss erledigt. Ist eigentlich nicht schwer. Zuerst wählen, welche der 4 Ziffern leuchten soll. Diese aktivieren, dann den Wert anzeigen. Ziffer deaktivieren, nächste aktivieren, Wert anzeigen, deaktivieren,...
PRinzipiell machst du es auch so. Du solltest mal den Stack erhöhen, da ich keine Angabe darüber finden kannt.

TobiasBlome
15.08.2007, 19:59
>>Du solltest mal den Stack erhöhen

? :oops: ääh damit hab ich noch nichts gemacht...
deswegen taucht in meinem Programm auch nichts davon auf. was/wieviel soll ich denn nehmen?

Tobias

Michael
15.08.2007, 20:01
Hallo TobiasBlome,


hab´ ich sofort geändert. Aber es macht keinen Unterschied ob 1 oder 0 und das merkwürdige 2 oder 3 geht auch! Bei 4 fehlt die erste Zahl...

Aber vielleicht habe ich ja mehrere kleine Fehler!
dann hilft es sicher, das bisherige korrigierte Programm nochmal zur Ansicht hier einzustellen.

Gruß, Michael

darwin.nuernberg
15.08.2007, 20:02
ich glaub wir reden gerade total aneinander vorbei,

do
___aber warum fragst du denn wie es deodiert werden soll,
___wenn du das schon anders gelöst hast,
___was aber nicht funktioniert,
___und darum hier danach fragst wie du es lösen kannst.
loop

TobiasBlome
15.08.2007, 20:16
ja richtig - hier mein aktuelles Programm!

und der FEHLER:
wenn Variable LED=1234 --> dann Anzeige 43
wenn Variable LED=123 -> dann Anzeige 3321

(In Zukunft soll noch ein Dezimalpunkt hinzukommen)


'7Segmentanzeige mit 4 Anzeigen

$regfile = "ATtiny2313.dat" 'ATTiny2313
$crystal = 20000000 '20MHz Quarz


$hwstack = 64 ' default use 32 for the hardware stack
$swstack = 64 ' default use 10 for the SW stack




Ddrb = &B11111111 'PortB = Ausgang (PB0=A usw.)
Ddrd = &B1111111 'PortD = Ausgang (PD3=Anzeige1, PD4=A2, PD5=A3, PD6=A4)

Dim Led2 As String * 5 At &H70
Dim Z(5) As Byte At &H70 Overlay
Dim Led As Word
Dim X(5) As Byte
Dim Test As Integer
Dim Test2 As Integer
Dim Anzeige_x As Byte 'für LED-Anzeige wählen...

Enable Interrupts


Do

'LED:=:EZHT
Led = 123 'LED - Anzeigewert

For Test2 = 1 To 5 'Wert sichern .....
X(test2) = Z(test2)
Next Test2




'Anzeige durchwechseln (hochzählen)
For Anzeige_x = 3 To 6 'Zaehler = PortD 3-6 Anzeige wählen)
Test = X(anzeige_x)
Select Case Test


'Led-Segmente als Zahlen definieren:
Case 48 : Portb = 63 'NULL
Case 49 : Portb = 6 'EINS
Case 50 : Portb = 91 'ZWEI
Case 51 : Portb = 79 'DREI
Case 52 : Portb = 102 'VIER
Case 53 : Portb = 109 'FÜNF
Case 54 : Portb = 125 'SECHS
Case 55 : Portb = 7 'SIEBEN
Case 56 : Portb = 127 'ACHT
Case 57 : Portb = 111 'NEUN
Case 58 : Portb = 128 'DP -> geht das als PORT zu setzen???
Case Else : Portb = 0
End Select


'Anzeige auswählen und Ein- / Ausschalten
Portd.anzeige_x = 1 'Anzeige AN
Waitus 100 'Zeit für jede Anzeige
'Waitms 100 'waitus 100 'Zeit für jede Anzeige
Portd.anzeige_x = 0 'Anzeige AUS
Next Anzeige_x


Led2 = Str(led)


If Z(4) = 0 Then 'Führende Nullen eliminieren
Do
Z(5) = Z(4)
Z(4) = Z(3)
Z(3) = Z(2)
Z(2) = Z(1)
Z(1) = 0
Loop Until Z(5) > 0
End If



Loop


Tobias

TobiasBlome
15.08.2007, 20:25
oh entschuldigung, ich habe noch einen Wichtigen Fehler vergessen:
Auf der Anzeige mit der der 1 (LED=123 -> dann Anzeige 3321) taucht manchmal eine 3 auf...

TobiasBlome
16.08.2007, 17:47
Hat denn keiner eine Idee?
Och nee - jetzt stehe ich wieder wie am Anfang vom Betrag...

Tobias

peterfido
16.08.2007, 18:16
Ich weiss nicht, wie du das verdrahtet hast. Ich würde erstmal nur eine Ziffer aktivieren und alle Zahlen einzeln durchlaufen lassen. Dann die Nächste usw.

Meine Ziffern sehen so aus:

Dim Zahl(10) As Byte
Zahl(10) = &B01000000
Zahl(1) = &B01111001
Zahl(2) = &B00100100
Zahl(3) = &B00110000
Zahl(4) = &B00011001
Zahl(5) = &B00010010
Zahl(6) = &B00000010
Zahl(7) = &B01111000
Zahl(8) = &B00000000
Zahl(9) = &B00010000

Die 10 ist natürlich die Ziffer 0.

Dann halt

Portb = Zahl(1)

usw

TobiasBlome
16.08.2007, 19:44
Verdrahtung:
Segment A=PB0, B=PB1, C=PB2, D=PB3, E=PB4, F=PB5, G=PB6, DP=PB7
EINER=PD3, ZEHNER=PD4, HUNDERTER=PD5, TAUSENDER=PD6

Zum Test:
wenn ich eine 1 haben möchte, wird auf der Hunderter und auf der Tausender-Stelle je eine 1 angezeigt und nach ca10 sekunden ist die Anzeige dunkel...

darwin.nuernberg
17.08.2007, 21:10
Irgendwie kommt es mir so vor als ob ich mit einer Wand rede.

Eigentlich ist alles erklärt, Du musst halt etwas flexibel sein, und die Informationen entsprechend umsetzen.

In den von mir vorgestellten Links sind Schaltbilder vorhanden.

Anstelle des 7-Segment-Decoders kannst Du natürlich einen Port des AVR's nehmen.

Wo klemmt es denn da?

Du brauchst doch nur anstelle des 4-Bit Wertes nun das Bitmuster für die Segmente setzen.

Und mein Beispiel (das Bitmuster für die Segmente) kann natürlich bei Dir ganz anders aussehen, bzw. die Segmente können bei Dir ganz anders angeschlossen sien, sonst hätte ich da ja auch nicht so viel Kommentare reigeschrieben.

EDIT:
Ich glaube Dein Problem ist, dass Du statisch denkst. Ein Multiplexer ist jedoch dynamsich (etwa Vierdimensional). Du muss also für jeden Zeitabschnitt

beginn Segment 1, während Segment 1, verlassen Segment 1
beginn Segment 2, während Segment 2, verlassen Segment 2
beginn Segment 3, während Segment 3, verlassen Segment 3
beginn Segment 4, während Segment 4, verlassen Segment 4


eine Art Momentaufnahme machen und genau betrachten was Du während diesen machst.

Das ist sozusagen die 4. Dimension.

TobiasBlome
17.08.2007, 21:26
@darwin.nuernberg
>>Irgendwie kommt es mir so vor als ob ich mit einer Wand rede<<

Also entweder du gehst konkret auf mein Programm ein oder du lässt es. Was hab ich davon wenn du mir sagst ich "muss flexiebel sein" und "die Informationen entsprechend umsetzen"??? Das ich an Stelle der 4Bit-Wandlers NUR einen Port des AVR´s einsetzen muss ist mir klar. Und wenn DU einmal in MEIN Programm gesehen hättest, hättest du festgestellt das ich einen Port für die 4Bitansteuerung benutzt habe.

>>In den von mir vorgestellten Links sind Schaltbilder vorhanden.
<<
Lies mal meine Problemstellung: Nach ein paar Sekunden ändern sich die Zahlen auf der Anzeige. WAS HAT DAS MIT DER VERDRAHTUNG ZU TUN?!

Sorry - aber das musste mal gesagt werden!