- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: RC5 mit Timer kombinieren funktioniert nicht

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    09.10.2004
    Beiträge
    54

    RC5 mit Timer kombinieren funktioniert nicht

    Anzeige

    Powerstation Test
    Hallo,

    kann mir jemand erklären warum der folgende Code funktioniert:

    Code:
    $regfile = "m8def.dat"
    $crystal = 3686400
    $baud = 9600
    $lib "mcsbyte.lbx"
    Config Rc5 = Pinc.5
    
    Enable Interrupts
    
    Dim Zaehler As Byte
    Dim Address As Byte , Command As Byte
    
    Dim I As Byte
    Dim Led1 As Byte
    Dim Led2 As Byte
    Dim Led3 As Byte
    
    Dim D1 As Byte
    Dim D2 As Byte
    Dim D3 As Byte
    Dim D4 As Byte
    Dim D5 As Byte
    Dim D6 As Byte
    Dim D2_1 As Byte
    Dim D4_1 As Byte
    Dim D6_1 As Byte
    
    Zaehler = 0
    
    Do
      Getrc5(address , Command)
    
       If Command = 16 Then
        Zaehler = Zaehler + 1
       Elseif Command = 144 Then
        Zaehler = Zaehler + 1
       Elseif Command = 17 Then
        Zaehler = Zaehler - 1
       Elseif Command = 145 Then
        Zaehler = Zaehler - 1
       End If
    
    
       Print Zaehler ; " " ; Led1 ; " " ; Led2 ; " " ; Led3
    
    
    D1 = Zaehler                                                'aktueller Zählwert
    D2_1 = Zaehler - 40                                         '40 subtrahieren, weil in 6er-Schritten bis 240
    D2 = Not D2_1                                               'Wert invertieren -> LED wird dunkler
    D3 = Zaehler - 80
    D4_1 = Zaehler - 120
    D4 = Not D4_1
    D5 = Zaehler - 160
    D6_1 = Zaehler - 200
    D6 = Not D6_1
    
      If Zaehler <= 40 Then
       Led1 = 240
       Led2 = D1 * 6
       Led3 = 0
      Else
      If Zaehler <= 80 Then
       Led1 = D2 * 6
       Led2 = 240
       Led3 = 0
      Else
      If Zaehler <= 120 Then
       Led1 = 0
       Led2 = 240
       Led3 = D3 * 6
      Else
      If Zaehler <= 160 Then
       Led1 = 0
       Led2 = D4 * 6
       Led3 = 240
      Else
      If Zaehler <= 200 Then
       Led1 = D5 * 6
       Led2 = 0
       Led3 = 240
      Else
      If Zaehler <= 240 Then
       Led1 = 240
       Led2 = 0
       Led3 = D6 * 6
      Else
        If Zaehler > 240 Then                                   'Restwert von 15 (255-240) "abschneiden"
         Led1 = 240
         Led2 = 0
         Led3 = 0                                               'LED bleibt dunkel
        End If
      End If
      End If
      End If
      End If
      End If
      End If
    Loop
    
    End

    dieser hier nach Einbau eines Timers aber nicht mehr:

    Code:
    $regfile = "m8def.dat"
    $crystal = 3686400
    $lib "mcsbyte.lbx"
    Config Rc5 = Pinc.5
    $baud = 9600
    
    Ddrd = &B11111111
    Ddrb = &B11111111
    
    
    Config Timer0 = Timer , Prescale = 8
    On Timer0 Timer_irq
    Enable Timer0
    Enable Interrupts
    
    Dim Zaehler As Byte
    Dim Address As Byte , Command As Byte
    
    Dim I As Byte
    Dim Led1 As Byte
    Dim Led2 As Byte
    Dim Led3 As Byte
    
    Dim D1 As Byte
    Dim D2 As Byte
    Dim D3 As Byte
    Dim D4 As Byte
    Dim D5 As Byte
    Dim D6 As Byte
    Dim D2_1 As Byte
    Dim D4_1 As Byte
    Dim D6_1 As Byte
    
    Zaehler = 0
    
    Do
                                                              'Hauptschleife
     Getrc5(address , Command)
    
       If Command = 16 Then
        Zaehler = Zaehler + 1
       Elseif Command = 144 Then
        Zaehler = Zaehler + 1
       Elseif Command = 17 Then
        Zaehler = Zaehler - 1
       Elseif Command = 145 Then
        Zaehler = Zaehler - 1
       End If
    
    
       Print Zaehler ; " " ; Led1 ; " " ; Led2 ; " " ; Led3
    
    
    D1 = Zaehler                                                'aktueller Zählwert
    D2_1 = Zaehler - 40                                         '40 subtrahieren, weil in 6er-Schritten bis 240
    D2 = Not D2_1                                               'Wert invertieren -> LED wird dunkler
    D3 = Zaehler - 80
    D4_1 = Zaehler - 120
    D4 = Not D4_1
    D5 = Zaehler - 160
    D6_1 = Zaehler - 200
    D6 = Not D6_1
    
      If Zaehler <= 40 Then
       Led1 = 240
       Led2 = D1 * 6
       Led3 = 0
      Else
      If Zaehler <= 80 Then
       Led1 = D2 * 6
       Led2 = 240
       Led3 = 0
      Else
      If Zaehler <= 120 Then
       Led1 = 0
       Led2 = 240
       Led3 = D3 * 6
      Else
      If Zaehler <= 160 Then
       Led1 = 0
       Led2 = D4 * 6
       Led3 = 240
      Else
      If Zaehler <= 200 Then
       Led1 = D5 * 6
       Led2 = 0
       Led3 = 240
      Else
      If Zaehler <= 240 Then
       Led1 = 240
       Led2 = 0
       Led3 = D6 * 6
      Else
        If Zaehler > 240 Then                                   'Restwert von 15 (255-240) "abschneiden"
         Led1 = 240
         Led2 = 0
         Led3 = 0                                               'LED bleibt dunkel
        End If
      End If
      End If
      End If
      End If
      End If
      End If
    
    Loop
    
    Timer_irq:                                                  'Timer-Interrupt
     Timer0 = 237
     I = I + 1
    
     If I = 240 Then
      I = 0
     End If
    
     If I >= Led1 Then
     Portd.0 = 0
     Portd.1 = 0
     Portd.2 = 0
     Portd.3 = 0
     Portd.4 = 0
     Portd.5 = 0
     End If
     If I < Led1 Then
     Portd.0 = 1
     Portd.1 = 1
     Portd.2 = 1
     Portd.3 = 1
     Portd.4 = 1
     Portd.5 = 1
     End If
    
     If I >= Led2 Then
     Portd.6 = 0
     Portd.7 = 0
     Portb.0 = 0
     Portb.1 = 0
     Portb.2 = 0
     Portb.3 = 0
     End If
     If I < Led2 Then
     Portd.6 = 1
     Portd.7 = 1
     Portb.0 = 1
     Portb.1 = 1
     Portb.2 = 1
     Portb.3 = 1
     End If
    
     If I >= Led3 Then
     Portb.4 = 0
     Portb.5 = 0
     Portc.0 = 0
     Portc.1 = 0
     Portc.2 = 0
     Portc.3 = 0
     End If
     If I < Led3 Then
     Portb.4 = 1
     Portb.5 = 1
     Portc.0 = 1
     Portc.1 = 1
     Portc.2 = 1
     Portc.3 = 1
     End If
    
    Return
    End
    Mir kommt es momentan vor allen auf die Print-Zeile an. Bei der ersten Code-Variante werden mir im Terminalprogramm permanent die Zählerwerte und die Berechneten Werte (LED) angezeigt.
    Ber der zweiten Code-Variante wird mir nur ab und zu mal eine "0" angezeigt.
    Woran kann das liegen, ich habe doch eigentlich nur einen Timer eingebaut???

    Grüße und Danke
    Enrico

  2. #2
    Gast
    Hi,
    Vorsicht: Prescale = 8 und preload timer0 = 237
    ist recht flott.
    Kann sein, der Bursche macht ausser Interrupts überhaupt nix oder selten. mfg PicNick

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    09.10.2004
    Beiträge
    54
    Danke für deine Antwort.
    Aber ich glaube nicht, dass es zu schnell geht. Zur Zeit versuche ich ja mit dem Code ein Infarot-Signal zum Zählen zu benutzen. Der Zähler geht bis 255. Vorher habe ich das ganze mit einem einfachen Potentiometer und A/D-Wandler ausprobiert. Dabei hat es problemlos funktioniert.

    Ist es nicht so, dass die Hauptschleife unabhängig vom Timerinteruppt abläuft?
    Was könnte ich denn im Programm ändern?

    Grüße und danke
    Enrico

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Hi, die Sache is so: Die Hauptschleife nudelt zwar vor sich hin, aber jeder Interrupt stoppt sie, und die Interruptroutine (timer_irq) läuft ab, dann geht's weiter.
    Kommt nun die IRpt Routine zu oft dran, kommt die Hauptschleife einfach nicht voran.
    Preload 237 heißt, er zÄhlt von dort bis 255, also 18 mal, das is nicht viel:
    ein paar zerquetschte microSekunden, da schafft er grad ein paar Befehle

    Man kann das alles auch berechnen, aber setz doch einfach zum Testen den Prescaler von 8 auf 1024 und den Preload von 237 auf 1, egal ob das Sinn macht. ABER:
    Liegt das Problem darin, kommt der Print wieder regelmäßig und du weißt, wo der Hund liegt.
    Dann kannst du dich ja wieder hinarbeiten zu schnelleren Interrupts
    mfg robert

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    09.10.2004
    Beiträge
    54
    Hallo,

    danke erst mal für deine Hilfe.
    Leider funktioniert das aber nicht so wie gedacht.
    Wenn ich die Einstellungen so vor nehme wie du gesagt hast, kommt der Print-Befehl nur wenn ich eine Taste auf der Fernbedienung drücke -> allerding kommt im Terminalprogramm auch nicht das was ich erwartet habe.

    Wenn ich allerdings den folgenden Code:

    Getrc5(address , Command)
    If Command = 16 Then
    Zaehler = Zaehler + 1
    Elseif Command = 144 Then
    Zaehler = Zaehler + 1
    Elseif Command = 17 Then
    Zaehler = Zaehler - 1
    Elseif Command = 145 Then
    Zaehler = Zaehler - 1
    Else
    Zaehler = Zaehler
    End If


    durch den hier ersetzte:

    Incr Zaehler

    kommt das was soll auch im Terminalprogramm. Es läuft zwar sehr langsam ab, aber es funktioniert. Leider kann ich so meine Fernbedienung nicht benutzen.
    Der Print-Befehl soll am Ende sowieso wieder aus dem Programm verschwinden, der ist jetzt nur zum testen gedacht. Wenn ich ihn rausnehme, läuft es mit Incr Zaehler genau so ab wie ich mir das vorstelle.
    Leider fällt mir momentan dazu keine Lösung ein... ;-(

    Grüße und danke
    Enrico

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Also bei einem Prescaler von 8 und einem 8 Bit Timer mit 3686400 Hz löst dein Timer immhin 25600 mal in der Sekunde einen Interrupt aus, wenn ich das richtig sehe. Das heißt alle: 39,0625 Mikrosekunden!

    "Incr Zaehler" heißt übrigens nur, dass Zähler um eins erhöht wird!

    MFG Moritz

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    09.10.2004
    Beiträge
    54
    Ja, das ist schon klar, nur warum funktioniert es mit incr Zaehler problemlos und sobald ich stattdessen Getrc5(address , Command) schreibe nicht mehr.
    Mir scheint es so, als ob der µC dann stehenbleibt.
    Wie könnte ich es denn jetzt anstellen, dass ständig abgefragt wird ob ein neuer Befehl per Infarot reingekommen ist und mit diesem Befehl auch noch gearbeitet werden kann? Gleichzeitig muss aber auch noch der Timer ohne "ruckeln" ablaufen.

    Selbst wenn ich den Timer sehr langsam ablaufen lasse funktioniert es nicht.

    Grüße und danke
    Enrico

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    29.12.2004
    Beiträge
    5
    Hallo Enrico,
    das funktioniert deshalb nicht, weil der Befehl GetRC5 intern den Timer0 verwendet, d.h. Du kannst ihn in Deinem Programm nicht verwenden und müßtest auf Timer 1 oder 2 ausweichen.

    Gruß
    Uwe

  9. #9
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Na ja, der GETRC5 wartet natürlich, bis was da is, vorher geht nix weiter.
    INCR flutscht durch, klaro.
    Zwei sachen passieren grad: Frau ruft zum Essen und
    ich seh grad im HELP, daß GETRC5 selber den TIMER0 verwendet, da wirst du wohl besser auf einen anderen wechseln müssen.
    Ich schau dann nach, ob's irgendeinen Interrrupt oder ischar für den RC5 gibt. mfg robert

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    09.10.2004
    Beiträge
    54
    danke für den Tip mit dem Timer0, ich werde das am Wochenende mal ausprobieren - momentan geht es leider nicht...
    melde mich wieder, wenn ich soweit bin...

    Grüße und danke
    Enrico

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen