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
Lesezeichen