PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zeitproblem mit 7-Segmentanzeige



Der Einsteiger
28.01.2014, 21:37
Hallo Leute,
ich habe mir eine 7-Segmentanzeige mit 4 Stellen gebaut. Dazu habe ich vier Segmente mit CA jeweils an PNP-Transistoren geschaltet, und die einzelnen Pins an einen ULN2803A. Die Anzeige funktioniert nach vielen Tests soweit auch, doch habe ich ein enormes Zeitproblem. Damit meine ich, dass wenn ich eine 4stellige Zahl im Terminal von Bascom eingebe, es erst einmal eine Sekunde braucht, bis mir diese überhaupt im PC angezeigt wird, und wenn ich Enter gedrückt habe es noch einmal ca. 1 Sekunde braucht bis das Display am MC umschlägt... . Woran liegt das und wie kann ich das ändern/verbessern ?

Der Einsteiger

Und hier noch das Programm :


$regfile = "m32def.dat"
$crystal = 16000000
$baud = 9600
$hwstack = 200
$swstack = 200
$framesize = 400

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''

Dim Stringinput As String * 10
Dim A As Byte

Dim Var1 As Byte
Dim Var2 As Byte
Dim Var3 As Byte
Dim Var4 As Byte

Dim Stelle1 As String * 2
Dim Stelle2 As String * 2
Dim Stelle3 As String * 2
Dim Stelle4 As String * 2

Dim Dis(11) As Byte

Dim Cnt As Byte
Cnt = 0

'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''

Config Serialin = Buffered , Size = 20

'Summer:
Config Portd.7 = Output

'einzelne Elemente
Config Portd.3 = Output
Config Portd.4 = Output
Config Portd.5 = Output
Config Portd.6 = Output
Portd.3 = 1
Portd.4 = 1
Portd.5 = 1
Portd.6 = 1

Config Portc = Output

Config Timer1 = Timer , Prescale = 8
On Timer1 Timer_irq
Const Timervorgabe = 25536

' Pins
Dis(1) = &B00111111
Dis(2) = &B00000110
Dis(3) = &B01011011
Dis(4) = &B01001111
Dis(5) = &B01100110
Dis(6) = &B01101101
Dis(7) = &B01111101
Dis(8) = &B00000111
Dis(9) = &B01111111
Dis(10) = &B01101111
Dis(11) = &B00000000

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''

Sound Portd.7 , 400 , 450
Sound Portd.7 , 400 , 250
Sound Portd.7 , 400 , 450
Wait 2

Enable Timer1
Enable Interrupts

Do
A = Ischarwaiting()
If A = 1 Then
Input Stringinput
End If
Disable Interrupts
Stelle1 = Left(stringinput , 1)
Stelle2 = Mid(stringinput , 2 , 1 )
Stelle3 = Mid(stringinput , 3 , 1 )
Stelle4 = Right(stringinput , 1)

Var1 = Val(stelle1)
Var2 = Val(stelle2)
Var3 = Val(stelle3)
Var4 = Val(stelle4)
Enable Interrupts
Wait 1
Loop

End

Timer_irq:
Timer1 = Timervorgabe

Cnt = Var1 + 1
Portd.3 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.3 = 1

Cnt = Var2 + 1
Portd.4 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.4 = 1

Cnt = Var3 + 1
Portd.5 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.5 = 1

Cnt = Var4 + 1
Portd.6 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.6 = 1

Return

Rofo88
30.01.2014, 01:21
Du hast auch ein Wait 1 in der Hauptschleife, da wartet er halt ne Sekunde...

Der Einsteiger
02.02.2014, 12:41
Vielen Dank für deine Antwort Rofo88.
Hat mir sehr geholfen, da ich das Wait 1 immer übersehen habe...
Habe auch noch die Baudrate auf 19200 gesetzt und jetzt geht es ganz gut :)

Hier also noch mal das funktionierende Programm :


$regfile = "m32def.dat"
$crystal = 16000000
$baud = 19200
$hwstack = 200
$swstack = 200
$framesize = 400

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''

Dim Stringinput As String * 10
Dim A As Byte

Dim Var1 As Byte
Dim Var2 As Byte
Dim Var3 As Byte
Dim Var4 As Byte

Dim Stelle1 As String * 2
Dim Stelle2 As String * 2
Dim Stelle3 As String * 2
Dim Stelle4 As String * 2

Dim Dis(11) As Byte

Dim Cnt As Byte
Cnt = 0

'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''

Config Serialin = Buffered , Size = 20

'Summer:
Config Portd.7 = Output

'einzelne Elemente
Config Portd.3 = Output
Config Portd.4 = Output
Config Portd.5 = Output
Config Portd.6 = Output
Portd.3 = 1
Portd.4 = 1
Portd.5 = 1
Portd.6 = 1

Config Portc = Output

Config Timer1 = Timer , Prescale = 8
On Timer1 Timer_irq
Const Timervorgabe = 25536

' Pins
Dis(1) = &B00111111
Dis(2) = &B00000110
Dis(3) = &B01011011
Dis(4) = &B01001111
Dis(5) = &B01100110
Dis(6) = &B01101101
Dis(7) = &B01111101
Dis(8) = &B00000111
Dis(9) = &B01111111
Dis(10) = &B01101111
Dis(11) = &B00000000

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''

Sound Portd.7 , 400 , 450
Sound Portd.7 , 400 , 250
Sound Portd.7 , 400 , 450
Wait 2

Enable Timer1
Enable Interrupts

Do
A = Ischarwaiting()
If A = 1 Then
Input Stringinput
End If
Disable Interrupts
Stelle1 = Left(stringinput , 1)
Stelle2 = Mid(stringinput , 2 , 1 )
Stelle3 = Mid(stringinput , 3 , 1 )
Stelle4 = Right(stringinput , 1)

Var1 = Val(stelle1)
Var2 = Val(stelle2)
Var3 = Val(stelle3)
Var4 = Val(stelle4)
Enable Interrupts
'Wait 1
Loop

End

Timer_irq:
Timer1 = Timervorgabe

Cnt = Var1 + 1
Portd.3 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.3 = 1

Cnt = Var2 + 1
Portd.4 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.4 = 1

Cnt = Var3 + 1
Portd.5 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.5 = 1

Cnt = Var4 + 1
Portd.6 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.6 = 1

Return

- - - Aktualisiert - - -

Jetzt gibt es aber doch noch ein Problem:
Ich habe jetzt mit einem zweiten Board einen Zähler programmiert. Der soll von 1000 bis 9999 hochzählen usw. und dann die einzelnen Zahlen per Uart schicken, doch bekomme ich irgendwelche Zahlen angezeigt und nicht die, die richtig sind.

Woran kann das liegen ?


$regfile = "m32def.dat"
$crystal = 16000000
$baud = 19200
$hwstack = 200
$swstack = 200
$framesize = 400

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''

Dim Zaehler As Word
Zaehler = 1000

'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''

'Summer:
Config Portd.7 = Output

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''

Sound Portd.7 , 400 , 450
Sound Portd.7 , 400 , 250
Sound Portd.7 , 400 , 450
Wait 2

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''

Do
Zaehler = Zaehler + 1

If Zaehler > 9999 Then
Zaehler = 1000
End If

Print Zaehler

Waitms 500
Loop

End

for_ro
02.02.2014, 14:14
Hallo Einsteiger,
du schickst ein Word (Zaehler), also 2 Byte raus, liest aber einen String, also ASCII_Zeichen ein.
Du solltest beides gleich machen. Also z.B. beim Einlesen ebenfalls
Dim Zaehler as Word
...
Input Zaehler

Außerdem musst du unbedingt deine Timer ISR überdenken. Die ewig langen Waitus 3333 gehen dort überhaupt nicht.
Wenn du eine Stelle 3333µs anzeigen willst, dann konfiguriere den Timer so, dass er alle 3333µs (300x pro Sekunde) überläuft.
In der ISR schaltest du dann die Stelle um eins weiter und zeigst sie an. Das geht dann auch mit den schwächeren Timer 0 oder 2 und Timer1 bleibt für wichtigere Aufgaben erhalten.
Mit der 15ms dauernden ISR würdest du später ganz bestimmt Probleme bekommen.

Der Einsteiger
02.02.2014, 18:14
Du solltest beides gleich machen.
Dann könnte ich ja beim Sender auch das schreiben :


$regfile = "m32def.dat"
$crystal = 16000000
$baud = 19200
$hwstack = 200
$swstack = 200
$framesize = 400

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''

Dim Zaehler As Word
Zaehler = 1000
Dim Outstring As String * 5

'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''

'Summer:
Config Portd.7 = Output

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''

Sound Portd.7 , 400 , 450
Sound Portd.7 , 400 , 250
Sound Portd.7 , 400 , 450
Wait 2

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''

Do
Zaehler = Zaehler + 1

If Zaehler > 9999 Then
Zaehler = 1000
End If

Outstring = Str(zaehler)

Print Outstring

Wait 1
Loop

End

Ich mache einfach aus dem Word ein String...
Es funktioniert auch, wenn ich in meinen Terminal Emu schaue, doch wenn ich den Sender an mein Anzeigeboard stecke nicht. Warum geht das nicht ? Jetzt ist es doch das Gleiche, oder ?

for_ro
03.02.2014, 23:56
Ich könnte mir vorstellen, dass es an den Endezeichen liegt.
Input wartet bei einem String auf ein CR, während ein Print CR+LF sendet.
Füge mal beim Empfänger diesen Befehl hinzu:
Config Input = Crlf , Echo = Crlf
und ändere den Input Befehl so:
Input Stringinput , Noecho
Dann sollte es gehen.

Der Einsteiger
04.02.2014, 16:19
Danke für die Antwort, doch funktioniert es immer noch nicht. Er zeigt beim Anfang zwar kurz noch alles richtig an, doch hängt er sich schnell auf und zeigt dann wieder nur noch 1000 an und ändert sich nicht mehr... 1000,1001,1002,1003,10irgendwas und dann nur noch 1000 oder so...
Woran liegt das denn jetzt schon wieder ? Hab es doch so gemacht wie du es geschrieben hast, oder ?


$regfile = "m32def.dat"
$crystal = 16000000
$baud = 19200
$hwstack = 200
$swstack = 200
$framesize = 400

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''

Dim Stringinput As String * 10
Dim A As Byte

Dim Var1 As Byte
Dim Var2 As Byte
Dim Var3 As Byte
Dim Var4 As Byte

Dim Stelle1 As String * 2
Dim Stelle2 As String * 2
Dim Stelle3 As String * 2
Dim Stelle4 As String * 2

Dim Dis(11) As Byte

Dim Cnt As Byte
Cnt = 0

'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''

Config Input = Crlf , Echo = Crlf

Config Serialin = Buffered , Size = 20

'Summer:
Config Portd.7 = Output

'einzelne Elemente
Config Portd.3 = Output
Config Portd.4 = Output
Config Portd.5 = Output
Config Portd.6 = Output
Portd.3 = 1
Portd.4 = 1
Portd.5 = 1
Portd.6 = 1

Config Portc = Output

Config Timer1 = Timer , Prescale = 8
On Timer1 Timer_irq
Const Timervorgabe = 25536

' Pins
Dis(1) = &B00111111
Dis(2) = &B00000110
Dis(3) = &B01011011
Dis(4) = &B01001111
Dis(5) = &B01100110
Dis(6) = &B01101101
Dis(7) = &B01111101
Dis(8) = &B00000111
Dis(9) = &B01111111
Dis(10) = &B01101111
Dis(11) = &B00000000

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''

Sound Portd.7 , 400 , 450
Sound Portd.7 , 400 , 250
Sound Portd.7 , 400 , 450
Wait 2

Enable Timer1
Enable Interrupts

Do
A = Ischarwaiting()
If A = 1 Then
Input Stringinput , Noecho
End If
Disable Interrupts
Stelle1 = Left(stringinput , 1)
Stelle2 = Mid(stringinput , 2 , 1 )
Stelle3 = Mid(stringinput , 3 , 1 )
Stelle4 = Right(stringinput , 1)

Var1 = Val(stelle1)
Var2 = Val(stelle2)
Var3 = Val(stelle3)
Var4 = Val(stelle4)
Enable Interrupts
'Wait 1
Loop

End

Timer_irq:
Timer1 = Timervorgabe

Cnt = Var1 + 1
Portd.3 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.3 = 1

Cnt = Var2 + 1
Portd.4 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.4 = 1

Cnt = Var3 + 1
Portd.5 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.5 = 1

Cnt = Var4 + 1
Portd.6 = 0
Portc = Dis(cnt)
Waitus 3333
Portc = Dis(11)
Portd.6 = 1

Return

for_ro
04.02.2014, 20:34
Hallo Einsteiger,
dieses Programm funktioniert bei mir flimmerfrei.

$regfile = "m32adef.dat"
$crystal = 16000000
$baud = 9600
$hwstack = 200
$swstack = 200
$framesize = 400

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''

Config Input = Crlf , Echo = Crlf
Dim Stringinput As String * 10
Dim A As Byte

Dim Var(4) As Byte

Dim Stelle1 As String * 2
Dim Stelle2 As String * 2
Dim Stelle3 As String * 2
Dim Stelle4 As String * 2
Dim Stelle As Byte
Dim Dis(11) As Byte

Dim Cnt As Byte
Cnt = 0

'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''

Config Serialin = Buffered , Size = 20

'Summer:
Config Portd.7 = Output

'einzelne Elemente
Config Portd.3 = Output
Config Portd.4 = Output
Config Portd.5 = Output
Config Portd.6 = Output
Portd.3 = 1
Portd.4 = 1
Portd.5 = 1
Portd.6 = 1

Config Portc = Output

Config Timer0 = Timer , Prescale = 256
On Timer0 Timer_irq

' Pins
Dis(1) = &B00111111
Dis(2) = &B00000110
Dis(3) = &B01011011
Dis(4) = &B01001111
Dis(5) = &B01100110
Dis(6) = &B01101101
Dis(7) = &B01111101
Dis(8) = &B00000111
Dis(9) = &B01111111
Dis(10) = &B01101111
Dis(11) = &B00000000

Dis(1) = &B11000000 '&B01101111
Dis(2) = &B11111100 '&B00111111
Dis(3) = &B10010010 '&B00000110
Dis(4) = &B10011000 '&B01011011
Dis(5) = &B10101100 '&B01001111
Dis(6) = &B10001001 '&B01100110
Dis(7) = &B10000001 '&B01101101
Dis(8) = &B11011100 '&B01111101
Dis(9) = &B10000000 '&B00000111
Dis(10) = &B10001000 '&B01111111

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''
Stelle = 2
Sound Portd.7 , 400 , 450
Sound Portd.7 , 400 , 250
Sound Portd.7 , 400 , 450
Wait 2

Enable Timer0
Enable Interrupts

Do
A = Ischarwaiting()
If A = 1 Then
Input Stringinput , Noecho
End If
Stelle1 = Left(stringinput , 1)
Stelle2 = Mid(stringinput , 2 , 1 )
Stelle3 = Mid(stringinput , 3 , 1 )
Stelle4 = Right(stringinput , 1)
Var(1) = Val(stelle1)
Var(2) = Val(stelle2)
Var(3) = Val(stelle3)
Var(4) = Val(stelle4)
Loop

End

Timer_irq:
Portc = 255 'alte Stelle ausschalten
Portd.stelle = 0 'alle Segmente ausschalten
Incr Stelle 'nächste Stelle
If Stelle = 7 Then Stelle = 3 'wieder von vorne
Cnt = Var(stelle -2) + 1 'da Stelle von 3-6 zählt, Var() aber von 1-4, muss man 2 abziehen
Portd.stelle = 1 'Stelle einschalten
Portc = Dis(cnt) 'Segmente einschalten
Return

Der Einsteiger
05.02.2014, 21:37
Vielen Dank für eure Hilfe :) Jetzt funktioniert die Anzeige ohne Probleme
Habe nur noch das Portc = 255 in Portc = 0 geändert...