@peterfido
toll, danke!
"eigendlich" funktioniert es ja - nur die Funktion, wenn man die Taste lange drückt...
ich suche den Fehler weiter...
Druckbare Version
@peterfido
toll, danke!
"eigendlich" funktioniert es ja - nur die Funktion, wenn man die Taste lange drückt...
ich suche den Fehler weiter...
Ich habe mal die RC5 Routine aus dem http://www.Bascom-Forum.de verwendet. Die GetRC5 war bei mir etwas hakelig.
Der Takt steht auf 8MHZ intern.
Code:'Konfiguration µC:
$regfile = "m8def.dat" 'AT-Mega8
$crystal = 8000000 'Quarz: 16 MHz
$baud = 38400 'Baudrate definieren
$hwstack = 64 ' default use 32 for the hardware stack
$swstack = 64 ' default use 10 for the SW stack
$framesize = 64
'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddrb = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang
Ddrc = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang
Portb = 0
Portc = 0
'-------------------------------------------------------------------------------
'Timer0 = 8 Bit
'wird für RC5 Auswertung benötigt!!!
'Config Rc5 = Pind.3 'Timer0 in Benutzung!!!
Input_pin Alias Pind.3
'Set Portd.3 'Pull Up für Empfänger
'16Bit Timer:
Config Timer1 = Timer , Prescale = 256
On Timer1 Timer1_irq
'Const Timervorgabe = 64911 '100 mal pro Sekunde
'-------------------------------------------------------------------------------
'Variablen:
'-------------------------------------------------------------------------------
'Dim Address As Byte , Command As Byte , Command_old As Bit , Flag As Bit , Addressalt As Byte , Commandalt As Byte , Tmr_exp As Byte 'RC5
Dim Address_rc5 As Byte , Command_rc5 As Byte , Rc5_flag As Bit , Command_old As Bit
'Taste lange gedrückt
'Dim Taste_lang As Word
'Taste 1-6 auf der FB
Dim T1 As Byte , T2 As Byte , T3 As Byte
Dim Empfang As Bit 'ist 0 wenn kein empfang also 255 von address
Dim Sek As Byte 'wenn = 100 dann 1 sec um
Dim L As Integer
'Lampen festlegen
'-------------------------------------------------------------------------------
'Vor Programmstart:
'alle Lampen aus:
Const An = 1
Const Aus = 0
Const Nichts = 255
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
T3 = Nichts
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Print "Programm Start 38400 Baud..."
Do
If Rc5_flag = 1 Then
Reset Rc5_flag
If Address_rc5 = 0 Then 'Adresse 0=TV FB
Incr Sek
If Command_rc5.7 <> Command_old Then
Sek = 0
T3 = Nichts
Command_old = Command_rc5.7
End If
Reset Command_rc5.7 'reset toggle bit
Select Case Command_rc5
Case 0 : Print "CASE = 0"
Case 1 : T1 = 1
T2 = 2
Gosub Lampe1
Case 2 : T1 = 3
T2 = 4
Gosub Lampe1
Case 3 : T1 = 5
T2 = 6
Gosub Lampe1
Case 4 : T1 = 7
T2 = 8
Gosub Lampe1
Case 5 : T1 = 9
T2 = 10
Gosub Lampe1
Case 6 : T1 = 11
T2 = 12
Gosub Lampe1
Case Else : Print "Fehler: " ; Command_rc5
End Select
End If
End If
'_______________________________________________________________________________
Loop
End
'-------------------------------------------------------------------------------
'Relais ansteuern
'-------------------------------------------------------------------------------
Lampe1:
'=============
If T3 = Nichts Then
If L.t1 = 0 Then
T3 = An
Else
T3 = Aus
End If
End If
If Sek < 5 Then
If T3 = An Then
Set L.t1
Print "L" ; T1 ; ":1"
Else
If L.t2 = 1 Then
Reset L.t2
Print "L" ; T2 ; ":0"
Else
Reset L.t1
Print "L" ; T1 ; ":0"
End If
End If
Else
If T3 = An Then
Set L.t2
Print "L" ; T2 ; ":1"
Else
Reset L.t1
Print "L" ; T1 ; ":0"
End If
End If
Gosub Setzen
Return
Setzen:
Portc.5 = L.1
Portc.4 = L.2
Portc.3 = L.3
Portc.2 = L.4
Portc.1 = L.5
Portc.0 = L.6
Portb.5 = L.7
Portb.4 = L.8
Portb.3 = L.9
Portb.2 = L.10
Portb.1 = L.11
Portb.0 = L.12
Return
'*************************************************************************************
'Quelle: Bascom-Forum
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
'**************************************************************************************
Timer1_irq:
If Sek < 255 Then
Incr Sek
End If
Return
Es funktioniert nun alles!
@perterfido
Dein Code läuft mit dem IR Code hier aus dem Forum super flüssig! =D> =D> =D> Vielen Dank dafür.
Probleme hatte ich mit dem Auswerten der lang gedrückten Tasten:
1) wenn beide Leuchtmittel an sind und lange gedrückt wird, soll nur eine ausgehen (es gehen beide aus) Problem behoben.
2) wenn eine an ist und lange gedrückt wird, soll die zweite dazu angehen - etwas aufwendiger, da erst der kurze Tastendruck ausgewertet wurde und die Lampe kurzzeitig ganz ausschaltete bis beide Lampen angingen - nun habe ich diesen Effekt mit einem Timer verhindert(diese Zeitverzögerung läßt sich wohl leider nicht vermeiden).
Ausserdem habe ich die Variable "T3" in Status umbenannt und hier den tasächlichen Satus reingeschrieben und nicht den Sollwert.
Nun läuft es so wie ich es mir vorgestellt habe! Danke peterfido!!!
Code:'Konfiguration µC:
$regfile = "m8def.dat" 'AT-Mega8
$crystal = 8000000 'Quarz: 16 MHz
$baud = 38400 'Baudrate definieren
$hwstack = 64 ' default use 32 for the hardware stack
$swstack = 64 ' default use 10 for the SW stack
$framesize = 64
'-------------------------------------------------------------------------------
'Ein- Ausgänge:
Ddrb = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang
Ddrc = &B11111111 '1 Ausgang, 0 Eingang => Pin PB7-0 als Ausgang
Portb = 0
Portc = 0
'-------------------------------------------------------------------------------
'Timer0 = 8 Bit
Config Timer0 = Timer , Prescale = 8
On Timer0 Timer0_irq
Const Timervorgabe_t0 = 78 'Timeraufruf alle 178µs (10 Samples = 1 Bit = 1,778ms)
Enable Timer0 'Hier werden die Timer aktiviert
Enable Interrupts
'16Bit Timer:
Config Timer1 = Timer , Prescale = 64
On Timer1 Timer1_irq
Const Timervorgabe_t1 = 64286 '100 mal pro Sekunde @ 8MHz
Enable Timer1 'Hier werden die Timer aktiviert
Enable Interrupts
'-------------------------------------------------------------------------------
'Variablen:
'-------------------------------------------------------------------------------
Dim Address_rc5 As Byte , Command_rc5 As Byte , Rc5_flag As Bit , Command_old As Bit
'Taste 1-6 auf der FB
Dim T1 As Byte , T2 As Byte
Dim Status As Byte 'zeigt den Status der gewaehlten Lampe an NICHTS / AN / AUS
Dim Empfang As Bit 'ist 0 wenn kein empfang (also 255 von Variable address)
Dim Zaehler As Byte 'wenn = 100 dann 1 sec um
Dim L As Integer
Dim Setzen_merker As Bit '1 = setzenroutine freigegeben
Dim Z_timer1 As Byte '100 = 1 sec
Input_pin Alias Pind.3
'Set Portd.3 'Pull Up für Empfänger
Const An = 1
Const Aus = 0
Const Nichts = 255
'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 IR-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
'-------------------------------------------------------------------------------
'Vor Programmstart:
Zaehler = 0
Status = Nichts
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Hauptprogramm Do...Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Print "Programm Start 38400 Baud..."
Do
If Rc5_flag = 1 Then
Reset Rc5_flag
If Address_rc5 = 0 Then 'Adresse 0=TV FB
Incr Zaehler
If Command_rc5.7 <> Command_old Then
Zaehler = 0 'wenn ungleich also neuer Befehl, dann Zaehler zurücksetzen
Status = Nichts
Command_old = Command_rc5.7
End If
Reset Command_rc5.7 'reset toggle bit
'Print Command_rc5
Select Case Command_rc5
Case 0 : Gosub Alles_aus 'Print "CASE = 0"
Case 1 : T1 = 1
T2 = 2
Gosub Lampe1
Case 2 : T1 = 3
T2 = 4
Gosub Lampe1
Case 3 : T1 = 5
T2 = 6
Gosub Lampe1
Case 4 : T1 = 7
T2 = 8
Gosub Lampe1
Case 5 : T1 = 9
T2 = 10
Gosub Lampe1
Case 6 : T1 = 11
T2 = 12
Gosub Lampe1
Case 7 : Gosub Gruppe_7
Case 9 : Gosub Gruppe_9
Case 12 : Gosub Alles_aus
Case Else : Print "Fehler: " ; Command_rc5
End Select
End If
End If
'_______________________________________________________________________________
If Z_timer1 > 40 And Setzen_merker = 1 Then 'Schaltvert für Z_Timer1 ist Quarzfrequenz abhängig und soll bei langem Tastendruck verhindern
Setzen_merker = 0 'dass wenn eine Lampe an ist und die zweite hinzukommt, dass die erste kurz aus geht!
Gosub Setzen
End If
Loop
End
'-------------------------------------------------------------------------------
'Relais ansteuern
'-------------------------------------------------------------------------------
'Status = so wie der aktuelle Status IST (nicht wie er sein soll!!!)
Lampe1:
'=============
'aktuellen Status auslesen und setzen
If Status = Nichts Then
If L.t1 = 0 Then
Status = Aus
Else
Status = An
End If
End If
If Zaehler = 0 Then 'WENN KURZ GEDRÜCKT WURDE
'Print Zaehler ; " = Zaehler = 0"
If Status = Aus Then 'wenn lampe eingeschaltet werden soll dann
Set L.t1
'Print "L" ; T1 ; ":1"
Else 'wenn lampe 1 = an
If L.t2 = 1 Then
Reset L.t2
'Print "L" ; T2 ; ":0"
Else
Reset L.t1
'Print "L" ; T1 ; ":0"
End If
End If
End If
'WENN LANGE GEDRÜCKT WURDE
If Zaehler > 2 Then
'Print Zaehler ; " = Zaehler > 2"
If Status = Aus Then
Set L.t2
'Print "Lange" ; T2 ; ":1"
Else
If L.t2 = 0 Then
Set L.t1
Set L.t2
'Print "Lange" ; T1 ; ":1 und " ; T2 ; ":1"
End If
End If
End If
Setzen_merker = 1
'Print "Setzen_merker = " ; Setzen_merker
If Zaehler = 0 Then 'die Variable soll nur bei kurzem Tastendruck eine Zeitverzögerung machen
Z_timer1 = 0 'Timer1 zurücksetzen
End If
'Gosub Setzen
Return
Setzen:
'Print " S E T Z E N "
'Print Zaehler ; " Zaehler"
Portc.5 = L.1
Portc.4 = L.2
Portc.3 = L.3
Portc.2 = L.4
Portc.1 = L.5
Portc.0 = L.6
Portb.5 = L.7
Portb.4 = L.8
Portb.3 = L.9
Portb.2 = L.10
Portb.1 = L.11
Portb.0 = L.12
Return
Timer1_irq:
Timer1 = Timervorgabe_t1
If Z_timer1 < 255 Then
Incr Z_timer1
End If
Return
'*************************************************************************************
'Quelle: Bascom-Forum
Timer0_irq:
Timer0 = Timervorgabe_t0
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
'**************************************************************************************
'GRUPPEN PROGRAMME:
'____________________________
Gruppe_7:
If Zaehler < 2 Then
L.1 = 1
L.2 = 0
L.3 = 1
L.4 = 0
L.5 = 1
L.6 = 0
Else
L.1 = 1
L.2 = 1
L.3 = 1
L.4 = 1
L.5 = 1
L.6 = 1
End If
Gosub Setzen
Return
'____________________________
Gruppe_9:
If Zaehler = 0 Then
L.9 = 1
L.10 = 0
L.11 = 1
L.12 = 0
Else
L.9 = 1
L.10 = 1
L.11 = 1
L.12 = 1
End If
Gosub Setzen
Return
'____________________________
Alles_aus:
L.1 = 0
L.2 = 0
L.3 = 0
L.4 = 0
L.5 = 0
L.6 = 0
L.7 = 0
L.8 = 0
L.9 = 0
L.10 = 0
L.11 = 0
L.12 = 0
Gosub Setzen
Return
Freut mich, dass es dir gefällt. Fairerweise möchte ich erwähnen, dass der IR- Code aus dem http://www.bascom-forum.de/ kommt.