-
Hilfe zum DZM
Hallo,
ich habe hier den Code von einem DZM und hätte gerne noch einen kleinen zusatz weiss aber nicht wie ich den einbaue.
Es soll folgende Funktion gegeben sein: Wenn an Pinb.7 ein LOW Signal anliegt soll der DZM keine Anzeige auf den 7 Segmentanzeigen ausgeben (Er soll aber trotzdem weiterlaufen, nur die Anzeigen sollen tot sein!). Wäre echt nett wenn mir jemand helfen könnte.
Hier mal der Code:
Code:
' Hardware:
' ---------
' PD0: gelbe LED
' PD6: Signaleingang
' PB0-PB6: 7-segment - Segment A bis G
' PD1-PD5: 7-segment - Ziffer - Select
$regfile = "2313def.dat" 'AT90S2313
$crystal = 8000000 '8MHz Quarz
Ddrb = &B11111111 'PortB = Ausgang
Ddrd = &B0111111 'PortD = Ausgang bis auf PD6
Dim Icount As Long At &H60
Dim Wcountlo As Word At &H60 Overlay
Dim Wcounthi As Word At &H62 Overlay
Dim Temp As Integer At &H80
Dim Temp2 As Integer At &H80 Overlay
Dim Y As String * 5 At &H70
Dim Z(5) As Byte At &H70 Overlay
Dim Frequenz As Long
Dim Freq As Word
Dim Freq1 As Word
Dim Freq2 As Word
Dim Timeout As Byte
Dim Impulse As Byte
Dim X(5) As Byte
Dim Test As Integer
Dim Test2 As Integer
Dim Zaehler As Byte
Timeout = 0
On Icp1 Oncapture
On Ovf1 Onoverflow
Config Timer1 = Timer , Prescale = 8 , Capture Edge = Rising
Enable Icp1
Enable Ovf1
Enable Interrupts
'*******************
'* Start-Animation *
'*******************
Do
Portb = 1
Portd = 2
Waitms 50
Portd = 4
Waitms 50
Portd = 8
Waitms 50
Portd = 16
Waitms 50
Portb = 2
Waitms 50
Portb = 64
Waitms 50
Portd = 8
Waitms 50
Portd = 4
Waitms 50
Portd = 2
Waitms 50
Portb = 16
Waitms 50
Portb = 8
Waitms 50
Portd = 4
Waitms 50
Portd = 8
Waitms 50
Portd = 16
Waitms 50
Portb = 4
Waitms 50
Portb = 64
Waitms 50
Portd = 8
Waitms 50
Portd = 4
Waitms 50
Portd = 2
Waitms 50
Portb = 32
Waitms 50
Loop Until Temp2 = 1 'Bis zum 1. Impuls
'******************************************
'* Hauptschleife - LED-Anzeigen ansteuern *
'******************************************
Main:
Incr Timeout 'Bei Timeout: 0 U/min.
If Timeout = 10 Then
Timeout = 10
Freq = 0
Y = Str(freq)
Z(1) = 0
Z(2) = 0
Z(3) = 0
Z(4) = 0
Z(5) = 48
End If
For Test2 = 1 To 5 'Wert sichern .....
X(test2) = Z(test2)
Next Test2
For Test2 = 1 To 400 '..... und 400 mal Anzeigen
For Zaehler = 1 To 5
Test = X(zaehler)
Select Case Test
Case 48 : Portb = 63
Case 49 : Portb = 6
Case 50 : Portb = 91
Case 51 : Portb = 79
Case 52 : Portb = 102
Case 53 : Portb = 109
Case 54 : Portb = 125
Case 55 : Portb = 39
Case 56 : Portb = 127
Case 57 : Portb = 111
Case Else : Portb = 0
End Select
Portd.zaehler = 1
Waitus 100 'Zeit für jede Anzeige
Portd.zaehler = 0
Next Zaehler
Next Test2
Goto Main
'*************************************
'* Interrupt-Routine (Zeiten messen) *
'* (wird bei jedem Impuls ausgelöst) *
'*************************************
Oncapture:
Disable Icp1
Incr Impulse
If Impulse = 8 Then
Impulse = 0
Timeout = 0
Wcountlo = Timer1
Timer1 = 0
Frequenz = 240000000 / Icount 'Umrechnung für 4-Zylinder
Wcounthi = 0
Freq2 = Freq1
Freq1 = Frequenz
Frequenz = Freq1 + Freq2
Frequenz = Frequenz / 2
Freq = Frequenz
If Freq > 5999 Then Portd.0 = 1 'Wenn Drehzahl über 5999 LED an
if Freq < 4000 Then Portd.0 = 0 'Wenn Drehzahl unter 4000 LED aus
If Freq < 150 Then
Freq = 0
Y = Str(freq)
Z(1) = 0
Z(2) = 0
Z(3) = 0
Z(4) = 0
Z(5) = 48
Else
Y = Str(freq)
If Z(5) = 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
End If
End If
End If
Temp = 1
Enable Icp1
Return
Onoverflow:
Incr Wcounthi
Return
Dann habe ich noch eine frage: Bei überschreiten einer bestimmten Drehzahl soll ein Port 1 geben und bei unterschreiten einer anderen Drehzahl soll der gleiche Port 0 geben. Ich habe es gerade wie im folgenden gemacht, was aber sicher so nicht funktioniert oder?
If Freq > 5999 Then Portd.0 = 1 'Wenn Drehzahl über 5999 LED an
if Freq < 4000 Then Portd.0 = 0 'Wenn Drehzahl unter 4000 LED aus[/quote]
-
Keiner der mit helfen kann? Ist echt wichtig komme sonst nicht weiter :(
Danke schonmal.
-
Was meinst du mit "tot" ? garnix (finster) oder nur "nicht ändern" ?
Der Drehzahlvergleich für Port 1 is ok, wenn dir klar ist, daß in dem Bereich 4000- 5999 ein anderes Verhalten ist, je nachdem, ob die Drehzahl steigt oder von oben abfällt.
-
Mit tot meine ich, das die Anzeigen einfach aus sind.
Und mit der LED die leuchten soll habe ich mich vielelicht etwas schlecht ausgedrückt:
Sobald ich einmal über 5999rpm komme soll die LED so lange leuchten bis ich einmal unter 4000rpm war, dann soll sie ausgehen. Wenn ich dann wieder über 5999rpm komme geht das ganze von vorne los.
-
Re: Hilfe zum DZM
Ok mit der Drehzahl, das scheint mir zu passen
Anzeige finster:
Code:
'-------------- ANZEIGE an ---------------------
IF herzeigen = 1 THEN
'--------------------------------------------------
For Test2 = 1 To 400 '..... und 400 mal Anzeigen
For Zaehler = 1 To 5
...usw...
Next Zaehler
Next Test2
ELSE
'--------------------------------------------------
'-------------- ANZEIGE finster----------------
'--------------------------------------------------
Portb = 0
Portd = 0
END IF
-
Ich habs nun versucht zu ändern, ich hoffe das stimmt nun alles:
Code:
' Hardware:
' ---------
' PD0: gelbe LED (ab 6250 Umdr./min.)
' PD6: Signaleingang
' PB0-PB6: 7-segment - Segment A bis G
' PD1-PD5: 7-segment - Ziffer - Select
$regfile = "2313def.dat" 'AT90S2313
$crystal = 8000000 '8MHz Quarz
Ddrb = &B01111111 'PortB = Ausgang
Ddrd = &B0111111 'PortD = Ausgang bis auf PD6
portd = &B10000000 'Pullup von Pinb.7 Aktivieren
Pinb.7 alias herzeigen
Dim Icount As Long At &H60
Dim Wcountlo As Word At &H60 Overlay
Dim Wcounthi As Word At &H62 Overlay
Dim Temp As Integer At &H80
Dim Temp2 As Integer At &H80 Overlay
Dim Y As String * 5 At &H70
Dim Z(5) As Byte At &H70 Overlay
Dim Frequenz As Long
Dim Freq As Word
Dim Freq1 As Word
Dim Freq2 As Word
Dim Timeout As Byte
Dim Impulse As Byte
Dim X(5) As Byte
Dim Test As Integer
Dim Test2 As Integer
Dim Zaehler As Byte
Timeout = 0
On Icp1 Oncapture
On Ovf1 Onoverflow
Config Timer1 = Timer , Prescale = 8 , Capture Edge = Rising
Enable Icp1
Enable Ovf1
Enable Interrupts
'*******************
'* Start-Animation *
'*******************
Do
Portb = 1
Portd = 2
Waitms 50
Portd = 4
Waitms 50
Portd = 8
Waitms 50
Portd = 16
Waitms 50
Portb = 2
Waitms 50
Portb = 64
Waitms 50
Portd = 8
Waitms 50
Portd = 4
Waitms 50
Portd = 2
Waitms 50
Portb = 16
Waitms 50
Portb = 8
Waitms 50
Portd = 4
Waitms 50
Portd = 8
Waitms 50
Portd = 16
Waitms 50
Portb = 4
Waitms 50
Portb = 64
Waitms 50
Portd = 8
Waitms 50
Portd = 4
Waitms 50
Portd = 2
Waitms 50
Portb = 32
Waitms 50
Loop Until Temp2 = 1 'Bis zum 1. Impuls
'******************************************
'* Hauptschleife - LED-Anzeigen ansteuern *
'******************************************
Main:
Incr Timeout 'Bei Timeout: 0 U/min.
If Timeout = 10 Then
Timeout = 10
Freq = 0
Y = Str(freq)
Z(1) = 0
Z(2) = 0
Z(3) = 0
Z(4) = 0
Z(5) = 48
End If
For Test2 = 1 To 5 'Wert sichern .....
X(test2) = Z(test2)
Next Test2
'******************************************
'* Anzeigen an *
'******************************************
if herzeigen = 1 Then 'Wenn herzeigen = 1 dann...
For Test2 = 1 To 400 '..... und 400 mal Anzeigen
For Zaehler = 1 To 5
Test = X(zaehler)
Select Case Test
Case 48 : Portb = 63
Case 49 : Portb = 6
Case 50 : Portb = 91
Case 51 : Portb = 79
Case 52 : Portb = 102
Case 53 : Portb = 109
Case 54 : Portb = 125
Case 55 : Portb = 39
Case 56 : Portb = 127
Case 57 : Portb = 111
Case Else : Portb = 0
End Select
Portd.zaehler = 1
Waitus 100 'Zeit für jede Anzeige
Portd.zaehler = 0
Next Zaehler
Next Test2
'******************************************
'* Anzeigen aus *
'******************************************
Else 'Wenn herzeigen = 0 Anzeigen aus
Portb = 0
Portd = 0
END IF
Goto Main
'*************************************
'* Interrupt-Routine (Zeiten messen) *
'* (wird bei jedem Impuls ausgelöst) *
'*************************************
Oncapture:
Disable Icp1
Incr Impulse
If Impulse = 8 Then
Impulse = 0
Timeout = 0
Wcountlo = Timer1
Timer1 = 0
Frequenz = 240000000 / Icount 'Umrechnung für 4-Zylinder
Wcounthi = 0
Freq2 = Freq1
Freq1 = Frequenz
Frequenz = Freq1 + Freq2
Frequenz = Frequenz / 2
Freq = Frequenz
If Freq > 5999 Then Portd.0 = 1 'Wenn Drehzahl über 5999 LED an
if Freq < 4000 Then Portd.0 = 0 'Wenn Drehzahl unter 4000 LED aus
If Freq < 150 Then
Freq = 0
Y = Str(freq)
Z(1) = 0
Z(2) = 0
Z(3) = 0
Z(4) = 0
Z(5) = 48
Else
Y = Str(freq)
If Z(5) = 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
End If
End If
End If
Temp = 1
Enable Icp1
Return
Onoverflow:
Incr Wcounthi
Return
Muss ich irgentwas ausser ®file ändern wenn ich einen ATMega8 verwenden möchte oder geht das nicht so ohne weiteres?
Danke!
-
Hallo hardstyleroxx,
> Muss ich irgentwas ausser ®file ändern wenn ich einen ATMega8
> verwenden möchte oder geht das nicht so ohne weiteres?
Eigentlich musst Du nur das Regfile ändern. Uneigentlich musst Du auch gucken, ob die Zweitbelegungen des neuen Chips nicht mit den Erstbelegungen kollidieren.
ICP liegt beim 2313 auf dem Pin PD6, beim Mega 8 liegt ICP auf PB0
PB verwendest Du aber als Ausgang für die Leds.
Ciao,
Werner
P.S. by the way, Du verwendest den ICP Interrupt zur Ermittlung der Zeit, liest dann aber in der ICP-Routine den Timer aus statt die Capture Register. Das schöne an den Capture Regisern ist ja gerade, das sie den Zählerstand beim Interrupt aufruf enthalten. Unabhängig davon, ob der Atmel während des Interrupt Aufrufs gerade mit etwas anderem beschäftigt war.
Kommt ein Zündimpuls z.B. unmittelbar nach einem Timerüberlauf, ist der Atmel mit dem OVF-Interrupt beschäftigt und arbeitet den ICP Interrupt erst danach ab. Liest den Timer also zu spät aus. Nungut, so schnell dreht Dein Motor wahrscheinlich nicht, daß das einen signifikanten Fehler produziert. Ich finde es nur unschön.
-
Der Code ist nicht von mir, ich habe ihn so im Internet gefunden!
Mit deiner Kritik kann ich leider nichts anfangen da ich nur bahnhof verstehe :(
Nochmal zum ändern des Chips: Ich muss aber an dem Code selber nichts ändern (ausser ®file) sondern nur an der beschaltung oder?
So ist nun die beschaltung des ATMega8
' Hardware:
' ---------
' PD0: Signaleingang
' PD6: LED am
' PB0-PB6: 7-segment - Segment A bis G
' PD1-PD5: 7-segment - Ziffer - Select
$regfile = "m8def.dat" 'ATMega8
$crystal = 8000000 '8MHz Quarz
Ddrb = &B01111111 'PortB = Ausgang
Ddrd = &B1111110 'PortD = Ausgang bis auf PD6
portd = &B10000000 'Pullup von Pinb.7 Aktivieren
-
Hallo hardstyleroxx,
> Der Code ist nicht von mir, ich habe ihn so im Internet gefunden!
das hab ich mir gedacht. Trotzdem solltest Du imo den Code verstehen wenn Du ihn einsetzt.
> Nochmal zum ändern des Chips: Ich muss aber an dem Code selber
> nichts ändern (ausser ®file) sondern nur an der beschaltung oder?
Am Code mußt Du einiges ändern.
Wie schon gesagt, Du verwendest den ICP Interrupt für Deine Signalerfassung und Port B als Ausgang für die LEDs. ICP ist aber beim Mega8 die Zweitbelegung des Pins B0 und ein Pin gleichzeitig als Eingang und als Ausgang geht nicht.
So wie Deine Software aufgebaut ist, brauchst Du einen Interrupt für die Zeiterfassung. Anschlüsse die einen Interrupt auslösen können sind bei den AVRs, die Pins mit den Zweitbelegungen Int0, Int1, ICP und, mit etwas externer Beschaltung die Pins AIN0 bzw. 1.
AIN0 & 1 lassen wir mal außen vor, denn dafür müsstest Du mit dem Analog Komparator rumspielen. Bleiben als mögliche Signaleingänge:
ICP = PB0
INT0 = PD2
INT1 = PD3
Bei INT0 & 1 müsstest Du nur Deine Interrupt Aufruf umschreiben.
Statt "On Icp1 Oncapture" -> "On Int0(1) Oncapture".
Aber das bringt Dich auch nicht weiter, denn PD2 und 3 verwendest Du ebenso wie PB0 um Deine Leds anzusteuern.
Du wirst also zumindest die Ausgabe Routine umschreiben müssen um einen der drei Pins als Signaleingang frei zu bekommen.
Der von Dir vorgesehene Pin PD0 geht nicht, denn PD0 kann wie gesagt keinen Interrupt auslösen, das können beim Mega 8 nur PB0, PD2 und PD3.
Ciao,
Werner
-
Gut, dann kann ich das vergessen :( Ich glaube kaum das jemand von euch so lieb ist und den Code umschreibt oder? Ich verstehe da nämlich sogut wie gar nichts von und bin erst am anfang was Ucs angeht.