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
Lesezeichen