Die hier bisher vorgeschlagene Lösung mittels eines Levels-Interrupts Intx GetRC5 anzustoßen hat den Nachteil, dass:
- die ISR für die ganze Zeit des Codempfangs (bis zu 130ms) den MC blockiert
- GetRC5 viele Fehler liest, da die Synchronisation wegen der fehlenden ersten Flanke wackelt
- zwei Interrupts belegt werden (Timer0 und INTx)

hier der alte Code: siehe https://www.roboternetz.de/phpBB2/ze...ag.php?t=18140
Code:
 $regfile = "m16def.dat"                                    'Controllertyp,
 $framesize = 32                                            'Stackanweisungen
 $swstack = 32
 $hwstack = 64
 $crystal = 8000000                                         'Die Frequenz des verwendeten Quarzes
 $baud = 9600                                               'Die Baudrate für RS232 Ausgabe.

 $lib "mcsbyte.lbx"

 'RC5 benötigt Timer0 Interrupt !
 Config Rc5 = Pind.3
 On Int1 Int1_int                                           'Nosave würde 52 Takte = 6,5uS sparen
 Enable Int1
 Config Int1 = Falling
 Enable Interrupts

 'Rückgabewerte der ISR
 Dim Address_rc5 As Byte , Command_rc5 As Byte , Rc5_flag As Bit

 Do
    If Rc5_flag = 1 Then
      Reset Rc5_flag
        Print "toggle:" ; Command_rc5.7;
        'clear the toggle bit
        Command_rc5 = Command_rc5 And &B01111111
        Print " Adresse:" ; Address_rc5 ; " Code:" ; Command_rc5
    End If
    'Waitms 100
 Loop

End

'Lesen der RC5 Codes
Int1_int:                                                   'Interrupt Handler For Int1
   Disable Int1
   Enable Interrupts                                        'für Timer0 Overflow GetRC5
   Getrc5(address_rc5 , Command_rc5)
   Set Rc5_flag                                             'Flag für RC5 Daten
   Gifr = Gifr Or &H80                                      'clear Flag Int1
   Enable Int1
Return
Codelänge: 444Word = 888Byte


Hier eine Lösung, die den BASCOM-Befehl GetRC5 nur mit der Timer0-Overflow-ISR nachbildet.
Vorteile:
- ISR dauert nur ca. 8µs alle 178µs (Timer0-Overflow), d.h. ca. 5% MC-Last (keine Blockierung)
- liest den RC5 Code fehlerfrei, da er sich auf jede Flanke synchronisiert
- belegt nur den Timer0-Interrupt
Code:
 'Decodierung eines RC5-Codes

  $regfile = "m16def.dat"                                   'Controllertyp
  $framesize = 32                                           'Stackanweisungen
  $swstack = 32
  $hwstack = 64                                             'Achtung ISR=32 Byte
  $crystal = 8000000                                        'bei Änderung den Timer0 neu einstellen!!
  $baud = 9600                                              'Die Baudrate für RS232 Ausgabe.

  $lib "mcsbyte.lbx"                                        'ACHTUNG:numeric<>string conversion routines only for bytes

  Config Portb.0 = 0
  Input_pin Alias Pinb.0                                    'Pin für TSOP1736

  Config Timer0 = Timer , Prescale = 8
  On Timer0 Timer_irq
  Const Timervorgabe = 78                                   'Timeraufruf alle 178µs (10 Samples = 1 Bit = 1,778ms)
  Enable Timer0                                             'Hier werden die Timer aktiviert
  Enable Interrupts

  'Timing für 10 Samples Per Bit = 1,778ms
  Const Samples_early = 8                                   'Flanke Frühestens Nach 8 Samples
  Const Samples_late = 12                                   'Flanke Spätestens Nach 12 Samples
  Const Samples_min = 3                                     'Flanke Vor 3 Samples - > Paket Verwerfen

  'Variablen der ISR
  Dim Sample As Byte                                        'eigentlich Bit, spart aber 46Byte ROM
  Dim Ir_lastsample As Byte                                 'zuletzt gelesenes Sample
  Dim Ir_bittimer As Byte                                   'zählt die Aufrufe von Timer_IRQ
  Dim Ir_data_tmp As Word                                   'Bitstream
  Dim Ir_bitcount As Byte                                   'Anzahl gelesener Bits


  'Rückgabewerte der ISR
  Dim Address_rc5 As Byte , Command_rc5 As Byte , Rc5_flag As Bit

  Do
    If Rc5_flag = 1 Then
      Reset Rc5_flag
        Print "toggle:" ; Command_rc5.7;
        'clear the toggle bit
        Command_rc5 = Command_rc5 And &B01111111
        Print " Adresse:" ; Address_rc5 ; " Code:" ; Command_rc5
    End If
    'Waitms 100
  Loop

End


Timer_irq:
  Timer0 = Timervorgabe
  Sample = Not Input_pin

  'bittimer erhöhen (bleibt bei 255 stehen)
  If Ir_bittimer < 255 Then Incr Ir_bittimer

  'flankenwechsel erkennen
  If Ir_lastsample <> Sample Then

     If Ir_bittimer <= Samples_min Then
       'flanke kommt zu früh: paket verwerfen
       Ir_bitcount = 0
     Else
       'nur Flankenwechsel in Bit-Mitte berücksichtigen
       If Ir_bittimer >= Samples_early Then
           If Ir_bittimer <= Samples_late Then
             'Bit speichern
              Shift Ir_data_tmp , Left , 1
              Ir_data_tmp = Ir_data_tmp + Sample
              Incr Ir_bitcount
           Else
              'Flankenwechsel zu spät: Neuanfang mit gemessener Flanke
              Ir_bitcount = 1
              Ir_data_tmp = Sample
           End If
           'bittimer zurücksetzen wenn Timer > Samples_early
           Ir_bittimer = 0
       End If
     End If

    'Kontrolle des Startbits auf 1
     If Ir_bitcount = 1 Then Ir_bitcount = Ir_data_tmp.0

     'Alle 14 Bits gelesen?
     If Ir_bitcount >= 14 Then
       Command_rc5 = Ir_data_tmp                            'Bit 6 und 7 siehe unten
       Shift Ir_data_tmp , Right , 6
       Address_rc5 = Ir_data_tmp And &B00011111
       'For extended RC5 code, the extended bit is bit 6 of the command.
       Command_rc5.6 = Not Ir_data_tmp.6
       'The toggle bit is stored in bit 7 of the command
       Command_rc5.7 = Ir_data_tmp.5
       'Paket erfolgreich gelesen
       Set Rc5_flag
       'paket zurücksetzen
       Ir_bitcount = 0
     End If

  End If
  'sample im samplepuffer ablegen
  Ir_lastsample = Sample

Return
Codelänge: 483Word = 966 Byte, d.h. zusätzlich nur 78 Byte