TobiasBlome
05.02.2008, 21:20
Hallo,
ich habe eine 7-Segmentanzeige die wunderbar funktioniert hat.
Nun wollte ich ein Paar Funktionen dazu haben und musste einen größeren µC nehmen. Deshalb hab ich eine paar Pinns ändern müssen.
Leider leuchtet nun immer Segment "B" also PD1. Wenn ich PD1 aus der Fassung biege ist der Fehler nicht mehr - also liegt es auf jeden fall an der software.(natürlich funktioniert dann das Segment auch nicht mehr...)
Kann mir jemand sagen warum PD1 gesetzt wird?
AT-Mega8 mit 8MHZ intern (Beschaltung im Code am Ende)
Tobias
'Geschwindigkeitsmessung mit AT-MEGA8 und 2 LaserLichtschranken
'7Segmentanzeige mit 4 Anzeigen
'Version: 0.1
'ohne Zeitmessung - nur Anzeige!!!!
'Version: 0.2
'-------------------------------------------------------------------------------
'Konfiguration µC:
$regfile = "m8def.dat" 'AT-Mega8
$crystal = 8000000 '18432000
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 8 ' default use 10 for the SW stack
$baud = 9600
'_________________________________________________ ______________________________
Ddrb = &B11111111 'PortB = Ausgang (PB0=A usw.)
Ddrc = &B111111 'PortC = Ausgang
Ddrd = &B11110011 'PortD = Ausgang (PD0=Anzeige1, PD4=A2, PD5=A3, PD6=A4) PD2/3 =INT
Config Int0 = Rising 'Falling 'wechsel von High auf Low
Config Int1 = Rising 'Falling 'wechsel von High auf Low
Enable Int0
Enable Int1
'On Int0 Irq0
'On Int1 Irq1
'_________________________________________________ ______________________________
Dim Anzeige_akt As Word 'Aktuelle Zeitmessung
Dim Anzeige_str As String * 5 'Zeit als String
Dim Anzeige_str_len As Byte 'String-Länge
Dim Anzeige_ziffer As String * 1 'Aktuelle Ziffer
Dim Anzeige_pos As Byte 'Aktuelle Ziffer im String
Dim I As Byte 'Allgem. Laufzahl
Dim Test As Word
Dim Zeit As Word
Dim Messzeit As Word 'in Millisekunden
Dim Zeitfake As Word 'damit nicht mit dem Wert 0 gerechnet wird 0=108km/h!!! 'gemessene Zeit von Timer1
Dim Zeit1 As Single
Dim Zeit2 As Single
Dim Zeit3 As Single
Dim Int0_merker As Byte 'als verriegelung für den int0 Eingang
Dim Int1_merker As Byte 'als verriegelung für den int1 Eingang
Dim Timer0merker As Word 'um intMerker zurück zu setzen
'_________________________________________________ ______________________________
'TIMER0 Konfiguration für Ziffernwechsel:
Config Timer0 = Timer , Prescale = 1024 '64 ' Timer0 für Anzeige
Const T0_preload = 0'230 ' Startwert Timer0 für 5000Hz
Tcnt0 = T0_preload
On Timer0 Timer_irq_led ' Timer0-Overflow-Interrupt
Enable Timer0 ' Timer0 starten
Sreg.7 = 1 'Globale Interruptfreigabe
'_________________________________________________ ______________________________
'TIMER1 Konfiguration für Messzeit Lichtschranke:
Config Timer1 = Timer , Prescale = 64
Const Timervorgabe = 65410 '65410 -> 1 kHz also 1Überlauf/Millisekunde
On Timer1 Timer1_irq 'Unteprogramm aufrufen
Enable Interrupts
'_________________________________________________ ______________________________
'Int0_merker = 0 'als verriegelung für den int0 Eingang
'Int1_merker = 0 'als verriegelung für den int1 Eingang
'Zeit = 0 'gemessene Zeit auf 0 setzen
I = 1
'Test = 0
Do
If Zeit =< 500 Or Zeit => 18615 Then 'damit nicht mit dem Wert 0 gerechnet wird 0=108km/h!!!
Zeitfake = 18616
Else
Zeitfake = Zeit
End If
Zeit1 = Messzeit * 0.0058579
Zeit2 = 109.05442 - Zeit1
Zeit3 = Zeit2 * 10 'damit ich eine nachkommastelle habe!!!
Anzeige_akt = 5 'Zeit3 '3 'Wert zum anzeigen
'If Timer0merker => 5000 Then '20000 Then 'als Wartezeit nach einer KM/h Messung
'Incr Test
'Timer0merker = 0
'Int0_merker = 0 'als verriegelung für den int0 Eingang
'Int1_merker = 0 'als verriegelung für den int1 Eingang
'End If
Loop
'_________________________________________________ ______________________________
Timer_irq_led:
Tcnt0 = T0_preload 'Timer wieder laden
Anzeige_str = Str(anzeige_akt) ' Wert in String umwandeln
Anzeige_str_len = Len(anzeige_str) ' Stringlänge messen
Anzeige_pos = Anzeige_str_len - I
Anzeige_pos = Anzeige_pos + 1
Anzeige_ziffer = Mid(anzeige_str , Anzeige_pos , 1)
Portc = 0 'Ghosting vermeiden (damit nich auf allen Anzeigen die selbe Zahl steht!!!)
Portd = 0
Portb = 0
Select Case Anzeige_ziffer 'Ziffer auf Port
Case "0" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 1
Portb.6 = 1
Portb.7 = 1
Portd.5 = 1
Portd.6 = 0
Portd.7 = 0 'NULL
Case "1" :
Portd.0 = 0
Portd.1 = 1
Portd.4 = 1
Portb.6 = 0
Portb.7 = 0
Portd.5 = 0
Portd.6 = 0
Portd.7 = 0 'EINS
Case "2" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 0
Portb.6 = 1
Portb.7 = 1
Portd.5 = 0
Portd.6 = 1
Portd.7 = 0 'ZWEI
Case "3" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 1
Portb.6 = 1
Portb.7 = 0
Portd.5 = 0
Portd.6 = 1
Portd.7 = 0 'DREI
Case "4" :
Portd.0 = 0
Portd.1 = 1
Portd.4 = 1
Portb.6 = 0
Portb.7 = 0
Portd.5 = 1
Portd.6 = 1
Portd.7 = 0 'VIER
Case "5" :
Portd.0 = 1
Portd.1 = 0
Portd.4 = 1
Portb.6 = 1
Portb.7 = 0
Portd.5 = 1
Portd.6 = 1
Portd.7 = 0 'FÜNF
Case "6" :
Portd.0 = 1
Portd.1 = 0
Portd.4 = 1
Portb.6 = 1
Portb.7 = 1
Portd.5 = 1
Portd.6 = 1
Portd.7 = 0 'SECHS
Case "7" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 1
Portb.6 = 0
Portb.7 = 0
Portd.5 = 0
Portd.6 = 0
Portd.7 = 0 'SIEBEN
Case "8" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 1
Portb.6 = 1
Portb.7 = 1
Portd.5 = 1
Portd.6 = 1
Portd.7 = 0 'ACHT
Case "9" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 1
Portb.6 = 1
Portb.7 = 0
Portd.5 = 1
Portd.6 = 1
Portd.7 = 0 'NEUN
Case Else :
Portd.0 = 0
Portd.1 = 0
Portd.4 = 0
Portb.6 = 0
Portb.7 = 0
Portd.5 = 0
Portd.6 = 0
Portd.7 = 0
End Select
'Segment wählen
If I = 1 Then Portc.1 = 1 'EINER
'If I = 2 Then Portc.2 = 1 'ZEHNER
If I = 2 Then
Portc.2 = 1 'ZEHNER
Portd.7 = 1 'EINE Kommastelle
End If
If I = 3 Then Portc.3 = 1 'HUNDERTER
If I = 4 Then Portc.4 = 1 'TAUSENDER
I = I + 1 'Nächste Ziffer
If I >= 5 Then I = 1 'max Anzeigen angeben! damit Anzeige möglichst hell ist(bei 5Anzeigen muss bei der 6. wieder bei 1 Angefangen werden)
Timer0merker = Timer0merker + 1 '+1 um intMerker zurück zu setzen
Return
'Irq0: 'Aufruf bei Lichtschranke 1 per Interrupt
'If Int0_merker = 0 Then
'Timer1 = 0 'Timer auf 0 setzen
'Zeit = 0 'Timer1Zähler auf 0 setzen
'Start Timer1
'Messzeit = 0
'End If
'Int0_merker = 1
'Return
'
'Irq1: 'Aufruf bei Lichtschranke 2 per Interrupt
' Stop Timer1
' If Int1_merker = 0 Then
' Messzeit = Zeit 'gemessene Zeit in Variable Zeit schreiben
' End If
' Int1_merker = 1
' Return
Timer1_irq: 'Aufruf jede oder jede halbe Sekunde
' Timer1 = Timervorgabe 'AUF TIMER EINSTELLUNG ACHTEN!!!!!!!
' Incr Zeit
Return
'-------------------------------------------------------------------------------
'Anschlussbelegung am AT-MEGA8
'-------------------------------------------------------------------------------
'Segment A = PD0 (rote Ader)
'Segment B = PD1
'Segment C = PD4
'Segment D = PB6
'Segment E = PB7
'Segment F = PD5
'Segment G = PD6
'Segment DP = PD7
'Zahl 1 = PC1 ganz rechts EINER (rote Ader)
'Zahl 2 = PC2 2.Stelle von Rechts ZEHNER
'Zahl 3 = PC3 3.Stelle von Rechts Hunderter
'Zahl 4 = PC4 4.Stelle von Rechts Tausender
'Lichtschranke INT0 = PD2
'Lichtschranke INT1 = PD3
ich habe eine 7-Segmentanzeige die wunderbar funktioniert hat.
Nun wollte ich ein Paar Funktionen dazu haben und musste einen größeren µC nehmen. Deshalb hab ich eine paar Pinns ändern müssen.
Leider leuchtet nun immer Segment "B" also PD1. Wenn ich PD1 aus der Fassung biege ist der Fehler nicht mehr - also liegt es auf jeden fall an der software.(natürlich funktioniert dann das Segment auch nicht mehr...)
Kann mir jemand sagen warum PD1 gesetzt wird?
AT-Mega8 mit 8MHZ intern (Beschaltung im Code am Ende)
Tobias
'Geschwindigkeitsmessung mit AT-MEGA8 und 2 LaserLichtschranken
'7Segmentanzeige mit 4 Anzeigen
'Version: 0.1
'ohne Zeitmessung - nur Anzeige!!!!
'Version: 0.2
'-------------------------------------------------------------------------------
'Konfiguration µC:
$regfile = "m8def.dat" 'AT-Mega8
$crystal = 8000000 '18432000
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 8 ' default use 10 for the SW stack
$baud = 9600
'_________________________________________________ ______________________________
Ddrb = &B11111111 'PortB = Ausgang (PB0=A usw.)
Ddrc = &B111111 'PortC = Ausgang
Ddrd = &B11110011 'PortD = Ausgang (PD0=Anzeige1, PD4=A2, PD5=A3, PD6=A4) PD2/3 =INT
Config Int0 = Rising 'Falling 'wechsel von High auf Low
Config Int1 = Rising 'Falling 'wechsel von High auf Low
Enable Int0
Enable Int1
'On Int0 Irq0
'On Int1 Irq1
'_________________________________________________ ______________________________
Dim Anzeige_akt As Word 'Aktuelle Zeitmessung
Dim Anzeige_str As String * 5 'Zeit als String
Dim Anzeige_str_len As Byte 'String-Länge
Dim Anzeige_ziffer As String * 1 'Aktuelle Ziffer
Dim Anzeige_pos As Byte 'Aktuelle Ziffer im String
Dim I As Byte 'Allgem. Laufzahl
Dim Test As Word
Dim Zeit As Word
Dim Messzeit As Word 'in Millisekunden
Dim Zeitfake As Word 'damit nicht mit dem Wert 0 gerechnet wird 0=108km/h!!! 'gemessene Zeit von Timer1
Dim Zeit1 As Single
Dim Zeit2 As Single
Dim Zeit3 As Single
Dim Int0_merker As Byte 'als verriegelung für den int0 Eingang
Dim Int1_merker As Byte 'als verriegelung für den int1 Eingang
Dim Timer0merker As Word 'um intMerker zurück zu setzen
'_________________________________________________ ______________________________
'TIMER0 Konfiguration für Ziffernwechsel:
Config Timer0 = Timer , Prescale = 1024 '64 ' Timer0 für Anzeige
Const T0_preload = 0'230 ' Startwert Timer0 für 5000Hz
Tcnt0 = T0_preload
On Timer0 Timer_irq_led ' Timer0-Overflow-Interrupt
Enable Timer0 ' Timer0 starten
Sreg.7 = 1 'Globale Interruptfreigabe
'_________________________________________________ ______________________________
'TIMER1 Konfiguration für Messzeit Lichtschranke:
Config Timer1 = Timer , Prescale = 64
Const Timervorgabe = 65410 '65410 -> 1 kHz also 1Überlauf/Millisekunde
On Timer1 Timer1_irq 'Unteprogramm aufrufen
Enable Interrupts
'_________________________________________________ ______________________________
'Int0_merker = 0 'als verriegelung für den int0 Eingang
'Int1_merker = 0 'als verriegelung für den int1 Eingang
'Zeit = 0 'gemessene Zeit auf 0 setzen
I = 1
'Test = 0
Do
If Zeit =< 500 Or Zeit => 18615 Then 'damit nicht mit dem Wert 0 gerechnet wird 0=108km/h!!!
Zeitfake = 18616
Else
Zeitfake = Zeit
End If
Zeit1 = Messzeit * 0.0058579
Zeit2 = 109.05442 - Zeit1
Zeit3 = Zeit2 * 10 'damit ich eine nachkommastelle habe!!!
Anzeige_akt = 5 'Zeit3 '3 'Wert zum anzeigen
'If Timer0merker => 5000 Then '20000 Then 'als Wartezeit nach einer KM/h Messung
'Incr Test
'Timer0merker = 0
'Int0_merker = 0 'als verriegelung für den int0 Eingang
'Int1_merker = 0 'als verriegelung für den int1 Eingang
'End If
Loop
'_________________________________________________ ______________________________
Timer_irq_led:
Tcnt0 = T0_preload 'Timer wieder laden
Anzeige_str = Str(anzeige_akt) ' Wert in String umwandeln
Anzeige_str_len = Len(anzeige_str) ' Stringlänge messen
Anzeige_pos = Anzeige_str_len - I
Anzeige_pos = Anzeige_pos + 1
Anzeige_ziffer = Mid(anzeige_str , Anzeige_pos , 1)
Portc = 0 'Ghosting vermeiden (damit nich auf allen Anzeigen die selbe Zahl steht!!!)
Portd = 0
Portb = 0
Select Case Anzeige_ziffer 'Ziffer auf Port
Case "0" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 1
Portb.6 = 1
Portb.7 = 1
Portd.5 = 1
Portd.6 = 0
Portd.7 = 0 'NULL
Case "1" :
Portd.0 = 0
Portd.1 = 1
Portd.4 = 1
Portb.6 = 0
Portb.7 = 0
Portd.5 = 0
Portd.6 = 0
Portd.7 = 0 'EINS
Case "2" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 0
Portb.6 = 1
Portb.7 = 1
Portd.5 = 0
Portd.6 = 1
Portd.7 = 0 'ZWEI
Case "3" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 1
Portb.6 = 1
Portb.7 = 0
Portd.5 = 0
Portd.6 = 1
Portd.7 = 0 'DREI
Case "4" :
Portd.0 = 0
Portd.1 = 1
Portd.4 = 1
Portb.6 = 0
Portb.7 = 0
Portd.5 = 1
Portd.6 = 1
Portd.7 = 0 'VIER
Case "5" :
Portd.0 = 1
Portd.1 = 0
Portd.4 = 1
Portb.6 = 1
Portb.7 = 0
Portd.5 = 1
Portd.6 = 1
Portd.7 = 0 'FÜNF
Case "6" :
Portd.0 = 1
Portd.1 = 0
Portd.4 = 1
Portb.6 = 1
Portb.7 = 1
Portd.5 = 1
Portd.6 = 1
Portd.7 = 0 'SECHS
Case "7" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 1
Portb.6 = 0
Portb.7 = 0
Portd.5 = 0
Portd.6 = 0
Portd.7 = 0 'SIEBEN
Case "8" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 1
Portb.6 = 1
Portb.7 = 1
Portd.5 = 1
Portd.6 = 1
Portd.7 = 0 'ACHT
Case "9" :
Portd.0 = 1
Portd.1 = 1
Portd.4 = 1
Portb.6 = 1
Portb.7 = 0
Portd.5 = 1
Portd.6 = 1
Portd.7 = 0 'NEUN
Case Else :
Portd.0 = 0
Portd.1 = 0
Portd.4 = 0
Portb.6 = 0
Portb.7 = 0
Portd.5 = 0
Portd.6 = 0
Portd.7 = 0
End Select
'Segment wählen
If I = 1 Then Portc.1 = 1 'EINER
'If I = 2 Then Portc.2 = 1 'ZEHNER
If I = 2 Then
Portc.2 = 1 'ZEHNER
Portd.7 = 1 'EINE Kommastelle
End If
If I = 3 Then Portc.3 = 1 'HUNDERTER
If I = 4 Then Portc.4 = 1 'TAUSENDER
I = I + 1 'Nächste Ziffer
If I >= 5 Then I = 1 'max Anzeigen angeben! damit Anzeige möglichst hell ist(bei 5Anzeigen muss bei der 6. wieder bei 1 Angefangen werden)
Timer0merker = Timer0merker + 1 '+1 um intMerker zurück zu setzen
Return
'Irq0: 'Aufruf bei Lichtschranke 1 per Interrupt
'If Int0_merker = 0 Then
'Timer1 = 0 'Timer auf 0 setzen
'Zeit = 0 'Timer1Zähler auf 0 setzen
'Start Timer1
'Messzeit = 0
'End If
'Int0_merker = 1
'Return
'
'Irq1: 'Aufruf bei Lichtschranke 2 per Interrupt
' Stop Timer1
' If Int1_merker = 0 Then
' Messzeit = Zeit 'gemessene Zeit in Variable Zeit schreiben
' End If
' Int1_merker = 1
' Return
Timer1_irq: 'Aufruf jede oder jede halbe Sekunde
' Timer1 = Timervorgabe 'AUF TIMER EINSTELLUNG ACHTEN!!!!!!!
' Incr Zeit
Return
'-------------------------------------------------------------------------------
'Anschlussbelegung am AT-MEGA8
'-------------------------------------------------------------------------------
'Segment A = PD0 (rote Ader)
'Segment B = PD1
'Segment C = PD4
'Segment D = PB6
'Segment E = PB7
'Segment F = PD5
'Segment G = PD6
'Segment DP = PD7
'Zahl 1 = PC1 ganz rechts EINER (rote Ader)
'Zahl 2 = PC2 2.Stelle von Rechts ZEHNER
'Zahl 3 = PC3 3.Stelle von Rechts Hunderter
'Zahl 4 = PC4 4.Stelle von Rechts Tausender
'Lichtschranke INT0 = PD2
'Lichtschranke INT1 = PD3