Codebeispiel für Lesen von RC5 Code mit Interrupt-Routine
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
Liste der Anhänge anzeigen (Anzahl: 1)
AVR Timer Rechner
@-tomas-:
Zitat:
Das Tool berücksichtigt leider nicht die 52 Takte aus der PUSH-Orgie von 26 Registern (siehe Code oben) und kommt dann
bei 8 Mhz auf Const Timervorgabe = 81 (anstatt 78 )...
... das hat mich als BASCOM-User noch weiter beschäftigt. Die Abweichungen gegenüber der "normalen" Berechnung von Timer-Startwerten sind ja teilweise gigantisch.
Ich habe da 'mal einen "Rechner" für Timer-Startwerte für BASCOM in Excel geschrieben. Dabei bin ich von 53 Takten ausgegangen, die am Anfang jeder ISR für das Sichern der Register gebraucht werden.
Könntest du das 'mal testen und mir evtl. Fehler schreiben!?
Gruß Dirk