Hallöle Allerseits ^^.

Das eine Problem war nun gebannt und kam auch nicht wieder, dafür ein Anderes. Ich kann es aber auch nur beschreiben, und zwar wie folgt:

Zum Auf- und Abdimmen einer bzw. mehrerer LED habe ich den Timer0 mit einem Prescaler von 64 versehen (8MHz Systemtakt) und anschließend den Timer0 immer auf 249 vorgeladen. Es klingt vielleicht ein wenig umständlich, dass ich den Timer mit NUR 6 Takten betreibe, aber so ist das LED-Fading einfach viel besser einstellbar als mit einem Prescaler von 8 und Vorladen um die 170.
Wie dem auch sei - ihr seht im ersten Programmabschnitt den ersten Case, in welchem bei [alle Eingangsbits = 1] alle Ausgangsregister auf 1 gesetzt werden, also alle LED = Off.
In einer speziellen Sub (standardgemäß über den CASE selektiert) wurde nun der Timer aufgerufen und sollte die Ausgänge mit einer LED-PWM auf- und abdimmen.

Und was geschah? NICHTS!

Also habe ich ein Testprogramm auf einer neuen Seite geschrieben, in welchem der lediglich 2 Test-CASE vorkamen - die LED fadete so, wie sie sollte.

Also wieder zurück ins Hauptprogramm und - funktioniert noch immer nicht.

Also habe ich den Übetäter kurz deaktiviert (den ersten Case mit dem " ' " in Schrift gewandelt) und - fadet noch immer nicht.
Nach gut einer Stunde Suchen habe ich dann alle Case, bis auf den letzten (in dem der Timer genutzt wurde) deaktiviert. Und plötzlich - funktioniert.
Also nacheinander alle Step-by-step wieder reaktiviert. Als ich dann beim ersten CASE ankam, funktionierten die anderen wieder problemlos.
Habe diesen dann auch wieder reaktiviert und was soll ich sagen - keine Spur mehr von einem Problem. Die Ausgänge fadeten ohne Murren.

Mittlerweile läuft das Programm fehlerfrei und ich teste jede neue CASE ausgiebig, bevor ich diese endgültig abspeichere.
Beispielsweise hatte ich auch das Problem der Signalüberschneidung. Am Ende der ISR des Timer0 stehen ja die angesteuerten Ports mit entsprechenden Bedingungen drin. Da ich aber unter verschiedenen Bedingungen bestimmte Ports ansteuere, kam es beim Fading dazu, dass die LED nur halbhell aufleuchteten.
Wie ich das gelöst habe, seht ihr am Ende des Codes...

Code:
$regfile = "m8515.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 32
$framesize = 60


'-------------------------------------------------------------------------------
'  *** Konfiguriere Ein- und Ausgangsports ***

Config Porta = Input
Config Portb = Output
Config Portc = Output
Config Portd = Output

Porta = &HFF       ' Aktiviert die internen Pullup-Widerstände
Portb = &HFF       ' schaltet alle Ausgänge 1, LED = 0
Portc = &HFF
Portd = &HFF


'-------------------------------------------------------------------------------
'  *** Konfiguriere Timer ***

Config Timer0 = Timer , Prescale = 64
On Timer0 Timerroutine
Enable Timer0
Start Timer0
Enable Interrupts


'-------------------------------------------------------------------------------
'  *** Deklarieren der Variablen ***

Dim Programm As Byte
Dim Zaehler As Word
Dim Timerzaehler As Word
Dim Led_rack0 As Word       '                   Abrufbar wenn nur ein Rack gefordert
Dim Led_rack1 As Word       '             Acht LED-Racks - abrufbar, wenn mehr als ein Racks gefordert
Dim Led_rack2 As Word       '             Jedes Rack steht dabei für ein Regalfach, egal ob horizontal oder vertikal
Dim Led_rack3 As Word
Dim Led_rack4 As Word
Dim Led_rack5 As Word
Dim Led_rack6 As Word
Dim Led_rack7 As Word
Dim Led_rack8 As Word
Dim Choose_rack As Byte       '           Variable zum Weiterschalten eines Racks in einer Ablaufprozedur
Dim Folgesequenz As Byte       '          Variable zum Weiterschalten einer Sequenz in die Folgende
Dim M1 As Bit       '                     Programmabbruch-Variable


'-------------------------------------------------------------------------------
'  *** Deklarieren der Subroutinen ***

Declare Sub All_off
Declare Sub All_on
Declare Sub Horizontal_lines
Declare Sub Vertical_lines
Declare Sub Straight
Declare Sub Diagonal_falling
Declare Sub Diagonal_rising
Declare Sub Net
Declare Sub Net_invert
Declare Sub Arrow_up
Declare Sub Pulsing_rack
Declare Sub Left_to_right


'-------------------------------------------------------------------------------
'   ===============================
'      ***** Hauptprogramm *****
' ===================================

Do
   Programm = Pina       '                         Variable übernimmt das Portregister von Port A
   Programm = Programm And &B00011111       '      Die ersten 3 Bits von Port A werden deaktiviert, somit brauchen
'                                                  im folgenden Select nur noch die Folgebits stehen

   Select Case Programm
         Case &B11111 : Call All_off       '                   00000
         Case &B11110 : Call All_on       '                    00001
         Case &B11101 : Call Horizontal_lines       '          00010
         Case &B11100 : Call Vertical_lines       '            00011
         Case &B11011 : Call Straight       '                  00100
         Case &B11010 : Call Diagonal_falling       '          00101
         Case &B11001 : Call Diagonal_rising       '           00110
         Case &B11000 : Call Net       '                       00111
         Case &B10111 : Call Net_invert       '                01000
         Case &B10110 : Call Arrow_up       '                  01001
         Case &B10101 : Call Pulsing_rack       '              01010
         Case &B10100 : Call Left_to_right       '             01011


   End Select


   If Programm = &B11111 Then M1 = 1 Else M1 = 0       ' Programmabbruch-Bedingung


Loop





'-------------------------------------------------------------------------------
' ====================================
'      ****  Unterprogramme  ****
'   ================================

Sub All_off:       '                00000
   Portd = &B11111111
   Portc = &B11111111
   Portb = &B11111111
   Choose_rack = 0       '                   Setzt bei Programmabbruch Variable zurück
   Disable Timer0       '                    Setzt bei Programmabbruch Timer0 Ausser Kraft
End Sub All_off


Sub All_on:       '                 00001
   Portd = &B00000000
   Portc = &B00000000
   Portb = &B00000000
End Sub All_on


Sub Horizontal_lines:       '       00010
   Portd = &B10101010
   Portb = &B10101010
   Portc = &B10101010
End Sub Horizontal_lines


Sub Vertical_lines:       '         00011
   Portd = &B00000000
   Portc = &B11111111
   Portb = &B00000000
End Sub Vertical_lines


Sub Straight:       '               00100
   Portd = &B11111111
   Portc = &B00000000
   Portb = &B11111111
End Sub Straight


Sub Diagonal_falling :       '      00101
   Portd = &B00100100
   Portc = &B01001001
   Portb = &B10010010
End Sub Diagonal_falling


Sub Diagonal_rising:       '        00110
   Portd = &B10010010
   Portc = &B01001001
   Portb = &B00100100
End Sub Diagonal_rising


Sub Net:  '                         00111
   Portd = &B10101010
   Portc = &B01010101
   Portb = &B10101010
End Sub Net


Sub Net_invert:       '             01000
   Portd = &B01010101
   Portc = &B10101010
   Portb = &B01010101
End Sub Net_invert


Sub Arrow_up:       '               01001
   Portd = &B11011101
   Portc = &B10111011
   Portb = &B11011101
End Sub Arrow_up


Sub Pulsing_rack:       '           01010
   Enable Timer0       '                        Startet Timer0 (muss ja nicht immer laufen)
'----- Aufdimmen -----
      For Zaehler = 0 To 300
      Led_rack0 = Zaehler
      Waitms 10
      Next Zaehler
'----- Abdimmen -----
      For Zaehler = 300 To 0 Step -1
      Led_rack0 = Zaehler
      Waitms 10
      Next Zaehler
End Sub Pulsing_rack


Sub Left_to_right:
' Diese Sub dimmt jeweils 3 LED-Streifen (bestehend aus je 1 Port) nacheinander auf und in gleicher Reihenfolge wieder ab.
' Mit Hilfe der Variable "CHOOSE_RACK" war es möglich, jeweils um 1 LED-Rack (1 Port) weiterzuschalten, ohne eine neue
' FOR-Schleife aufbauen zu müssen.
   Enable Timer0
   Choose_rack = Choose_rack + 1       '          01011
Aufdimmen:
   For Zaehler = 0 To 300
   If M1 = 1 Then Exit Sub       '                 Abbruchbedingung
   If Choose_rack = 1 Then Led_rack1 = Zaehler
   If Choose_rack = 2 Then Led_rack2 = Zaehler
   If Choose_rack = 3 Then Led_rack3 = Zaehler
   Waitms 3
   Next Zaehler
   If Choose_rack = 3 Then Gosub Abdimmen:

Abdimmen:
   For Zaehler = 300 To 0 Step -1
   If M1 = 1 Then Exit Sub
   If Choose_rack = 4 Then Led_rack1 = Zaehler
   If Choose_rack = 5 Then Led_rack2 = Zaehler
   If Choose_rack = 6 Then Led_rack3 = Zaehler
   Waitms 3
   Next Zaehler
   If Choose_rack = 6 Then Choose_rack = 0

End Sub Left_to_right




End

'-------------------------------------------------------------------------------
'  ***  ISR für Timer erzeugen - Overflow-Counter in Warteposition bringen ***

Timerroutine:

   Timer0 = 249
   Incr Timerzaehler
   If Timerzaehler = 300 Then Timerzaehler = 0       ' Auflösung der LED's von 300Hz

' Die nachfolgenden Port-PWM-Ansteuerungen werden durch die Programm-Bedingung separiert.
' Ohne Trennung gäbe es eine Signalüberschneidung, welche die Helligkeit um 50% reduziert.

'---------- Sub Pulsing_Rack ----------
If Programm = &B10101 Then
   If Timerzaehler < Led_rack0 Then Portb = &B00000000 Else Portb = &B11111111
End If

'---------- Sub Left_To_Right ----------
If Programm = &B10100 Then
   If Timerzaehler < Led_rack1 Then Portb = &B00000000 Else Portb = &B11111111
   If Timerzaehler < Led_rack2 Then Portc = &B00000000 Else Portc = &B11111111
   If Timerzaehler < Led_rack3 Then Portd = &B00000000 Else Portd = &B11111111
End If


Return

Bin echt froh, dass ich an vielen Stellen selbst weiterkomme, aber ohne eure Hilfe würde der Code sicher um Einiges größer.
Wobei ich aber auch sagen muss, dass es keinen nennenswerten Unterschied zur Schreibweise "PinA = &B00011101" und "PinA = 11101" gibt. Habe es mehrfach geprüft - die Dateigröße bleibt gleich.
Der Code oben liegt derzeit übrigens bei ca. 1,7KB - und für meine Verhältnisse ist das echt verdammt wenig. Denke, dass das Deklarieren der Subs auch eine ganze Menge raus haut. Gosub-Sprungmarken ohne Deklaration der Sub ziehen doch schon ihren Speicherplatz...



LG - Maik