-         

Ergebnis 1 bis 5 von 5

Thema: RC5 Abfrage funktioniert per Polling, aber nicht per INT0

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    31.01.2006
    Beiträge
    23

    RC5 Abfrage funktioniert per Polling, aber nicht per INT0

    Anzeige

    Servus.

    Ich stehe hier vor einem Phänomen, welches ich mir nicht ganz erklären kann.

    Ich habe lange rumgedockert und gesucht um nun endlich eine RC5 IR Fernbedieung auswerten zu können.

    Als Controllerboard verwende ich das RN-Control.
    Programmiere mit BASCOM.
    IR Fernbedienung: Phillips
    Empfänger: Keine Ahnung. Hab ich aus einem Technisat Reciever ausgebaut.


    Der funktionierende Polling basierte Code:

    Code:
    $regfile = "m32def.dat"                                     
    $crystal = 16000000                                        
    $baud = 9600
    
    Config Rc5 = Pina.1
    
    Enable Interrupts
    
    Dim Address As Byte , Command As Byte
    
    Print "Waiting for RC5..."
    
    Sound Portd.7 , 400 , 450                                   'BEEP
    Sound Portd.7 , 400 , 250                                   'BEEP
    Sound Portd.7 , 400 , 450                                   'BEEP
    
    Do
      Getrc5(address , Command)
      Command = Command And &B01111111
      If Address < 255 Then
       Print Address ; "  " ; Command
      End If
    Loop
    End
    Der Code funktioniert vom feinsten.
    Dieser oben gezeigte Code, war eig. nur um die generelle Funktionalität zu testen. Also: Zwekc erfüllt.

    Da das Polling aber überaus unschön und unpraktikabel ist, wollte ich das ganze Interrupt gesteuert umsetzen. ... Dies ist mein bisheriger Code:

    Code:
    $regfile = "m32def.dat"                                    
    $crystal = 16000000                                       
    $baud = 9600                                               
    
    $lib "mcsbyte.lbx"
    
    Config Rc5 = Pind.3
    
    On Int0 Int0_int                                           
    Enable Int0
    Enable Interrupts
    
    Dim Address As Byte , Command As Byte , Rc5_flag As Bit
    
    Sound Portd.7 , 400 , 450                                   'BEEP
    Sound Portd.7 , 400 , 250                                   'BEEP
    Sound Portd.7 , 400 , 450                                   'BEEP
    
    Do
            Print "Hallo"
            Waitms 1000
    Loop
    
    End
    
    'Lesen der RC5 Codes
    Int0_int:                                                   'Interrupt Handler For Int1
      Disable Int0
        Address = 0
        Command = 0
        Getrc5(address , Command)
        Command = Command And &B01111111
         Print Address ; "  " ; Command
       Enable Int0
    Return
    Hier funktioniert so ziemlich garnichts. In der Mail ist ein Print eingebaut, welcher jede Sekune "Hallo" sagt.

    Wenn das Programm startet funktioniert die Ausgabe durch Print auch. Sobald einmal die IR Fernbedienung betätigt wird, scheint sich alles wegzuhängen.

    Es wird keine Ausgabe des Empfangs getätigt. Das Programm springt nicht mehr in die Mainschleife zurück.

    Hat da wer ne Idee woran das liegen könnte?

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Hallo,
    ich glaube nicht, dass das so etwas wird.
    Falls du dein Signal nicht auf Pind.2 und Pind.3 liegen hast, geht es eh nicht.
    Dein Int0 liegt doch wohl auf Pind.2, RC5 ist auf Pind.3 konfiguriert.
    Aber auch dann wird es eher nicht gehen. Zum einen hast du nicht konfiguriert, auf welcher Flanke der Interrupt ausgelöst werden soll. Ob es da einen Default gibt, weiss ich gerade nicht.
    Die GETRC5() Funktion wird regelmäßig nicht den ersten Impuls mitkriegen, da die ISR Int0_int ja erst beim Flankenwechsel aufgerufen wird.
    Davon ab würde ich so einen Zeitfresser wie GETRC5 niemals in eine ISR stecken. Ich meine mich zu erinnern, dass die 150ms braucht, um zu einem Output zu kommen. Während der Zeit tut sich nichts in deinem System.

    Gruß

    Rolf

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791
    Hallo luvat,

    probier 'mal dies hier:
    Code:
    'IR-Empfänger an Pind.2 initialisieren:
    Config Rc5 = Pind.2
    On Int0 Rc5_receive
    Enable Int0
    Config Int0 = Falling
    Enable Interrupts
    
    'Hauptprogramm:
    Reset Rc5_flag
    Do
      For I = 1 To 4
        Locate I , 1
        Lcd "Warte auf IR ..."
        If Rc5_flag = 1 Then
          Reset Rc5_flag
          Gosub Rc5_display
        End If
        Wait 1
      Next I
      Cls
    Loop
    
    'RC5 auf LCD anzeigen:
    Rc5_display:
      If Address <> 255 Then
        Command = Command And &B01111111
        Cls
        Locate 2 , 1
        Lcd "Addr:   Cmd:"
        Locate 3 , 1
        Lcd Address ; " "
        Locate 3 , 9
        Lcd Command ; " "
        Wait 1
        Cls
      End If
    Return
    
    'RC5 einlesen:
    Rc5_receive:
      Disable Int0
      Enable Interrupts
      Getrc5(address , Command)
      Set Rc5_flag
      Gifr = Gifr Or &B01000000                       'Clear Flag Int0
      Enable Int0
    Return
    Gruß Dirk

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Hallo,
    wenn du schon einen externen Interrupt Pin benutzt, dann würde ich die Auswertung auch direkt selber machen.
    Ich bin mir sehr sicher, dass GETRC5() das erste Paket nicht richtig erkennen kann, da die erste Flanke fehlt. Ist das Paket dann nach 25ms durch, kommt eine Pause von 114ms, bevor das zweite Paket gesendet wird.
    Jetzt wird der Befehl in weiteren 25ms erkannt. Der µC hat bei 16MHz in der Zwischenzeit 2.500.000 Zyklen abgespult. Bleibt man einen Moment zu lange auf der Taste sind es wieder 2.500.000 Zyklen. Und auch bei Dirks Version findet das Ganze in einer ISR statt.
    Hast du in der ISR die Zeiten der Flankenwechsel in einem kleinen Array mitgeloggt, brauchst du im Hauptprogramm nur diese paar Befehle um einen gültigen RC5 Befehl zu erkennen:
    Code:
    If Flanken_anzahl > 15 And Flanken_anzahl < 27 And Flanken_anzahl.0 = 0 Then
       If Imp_array(2) > kurz_min And Imp_array(2) < kurz_max And Imp_array(3) > kurz_min And Imp_array(3) < kurz_max Then       
          I = 4
          Daten = 1
          While I < Flanken_anzahl
             Shift Daten , Left
             Daten.0 = Daten.1
             If Imp_array(i) > kurz_min And Imp_array(i) < kurz_max Then
                Incr I
                If Imp_array(i) <= kurz_min Or Imp_array(i) >= kurz_max Then
                   Exit While         'fehlerhafter Empfang
                End If
             Elseif Imp_array(i) > lang_min And Imp_array(i) < lang_max Then
                Toggle Daten.0
             Else
                Exit While            'fehlerhafter Empfang
             End If
             Incr I
          Wend
          If I >= Flanken_anzahl Then
             If Imp_array(i) > lang_min And Imp_array(i) < lang_max Then
                Shift Daten , Left
             End If
             Temp_daten = Daten
             Rc5_befehl = Temp_daten And &B00111111
             Shift Temp_daten , Right , 6
             Rc5_adresse = Temp_daten And &B00111111
             Print  "Adresse=" ; Rc5_adresse ; ", Befehl=" ; Rc5_befehl
          End If
       End If
    End If
    Und das geht bestimmt 1000 mal so schnell, denn 2500 Zyklen braucht er sicher nicht dafür.

    Gruß

    Rolf

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.05.2007
    Beiträge
    594
    Hier im Forum gibts irgendwo ne selbstgebastelte RC5-Routine die super im Interrupt funktioniert. Such die mal raus, die tuts fantastisch!

Berechtigungen

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