Forum: Mikrocontroller und Digitale Elektronik [ATmega88] RC5 mit Interrupt auslösen (Bascom)


von naeschd (Gast)


Lesenswert?

Hallo

ich habe zur Zeit folgendes Problem:
Ich möchte meinen ATmega88 betriebenen RGBY-Controller fernbedienen. 
Benutze hierfür das Empfängermodul TSOP1736 und natürlich RC5.

Mein Programm (Bascom) ist auch schon sehr gewachsen und enthält 
natürlich unter Anderem auch while-schleifen und waitms, wobei dann 
folgendes Problem auftaucht, dass wenn ich zum falschen Zeitpunkt meine 
FB betätige ich evtl in einer Schleife stecke und die Betätigung der FB 
gar nicht erkannt wird... Um meine Fernbedienung immer sofort zu 
erfassen wäre es ja sinnvol sobald eine Taste gedrückt wurde einen 
Interrupt auszulösen. Wie löse ich den denn am Besten aus?

Bis jetzt habe ich versucht den Ausgang des TSOP1736 auf den INT0 zu 
legen und den auf steigende Flanke konfiguriert. Aber durch die schnelle 
folge von steigenden Flanken beim RC5-Signal funktioniert das natürlich 
nicht...

Wie würdet ihr das lösen, dass die Fernbedienung jederzeit zuverlässig 
ausgelesen werden kann?

Danke für eure Hilfe...

von Hubert G. (hubertg)


Lesenswert?

Das mit den steigenden Flanken auf INT0 funktioniert schon, nur muss das 
Programm entsprechen ausgelegt sein. Lange while-Schleifen und waitms 
sind natürlich nicht das richtige.

von Der M. (naeschd)


Lesenswert?

Hubert G. wrote:
> Das mit den steigenden Flanken auf INT0 funktioniert schon, ...


Wenn ich aber das RC5-Signal auf den INT0-Eingang lege und diesen bei 
steigender Flanke ausführen lasse, springt das Probgramm zwar in den 
Interrupt. Wenn ich jedoch dort den Befehl getrc5() aufrufe um das 
Signal auszulesen bleibt das Programm im Interrupt hängen. Wenn ich den 
getrc5() Befehl entferne springt er nach dem Interrupt auch wieder 
zurück...? kann es da kein Problem geben, dass beim RC5 sehr viele 
steigende Flanken in kurzer Zeit kommen?

Gruß

von Otto (Gast)


Lesenswert?

Setze in der Interrupt-Routine nur ein Flag, dass dann im Hauptprogramm 
den RC5-Empfang aufruft.

Du kannst Dir den Interrupt aber sparen, wenn Du im Programm nicht in 
irgendwelchen Schleifen wartest, sondern einen Zähler hochzählst und 
abhängig vom Zählerstand bestimmte Aktionen ausführst.

Dann kommt das Programm oft genug an der RC5-Dekodierung vorbei.....

Otto

von Flipp F. (flipp86)


Lesenswert?

so ich hol den thread nochmal hoch.
ich habe nämlich genau das selbe problem und bin auch noch zu keiner 
lösung gekommen.

auch die tipps die hier genannt wurden hab ich probiert. klappt aber 
nicht.

ich poste einfach mal meinen versuch. vlt hab ich ja eure tipps noch 
nicht richtig verstanden und umgesetzt.
programmiere nämlich noch nicht so lange mit bascom.
1
$regfile = "m8def.dat"
2
$lib "mcsbyte.lbx"
3
$crystal = 8000000                                          'interner Quarz 8 MHz
4
5
6
Declare Sub Check_input()                                   ' die Subfunktion
7
8
Config Rc5 = Pind.2
9
10
' Timer1 und Timer2 für PWM Betrieb initialisieren
11
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
12
Config Timer2 = Pwm , Compare Pwm = Clear Up , Prescale = 1
13
14
15
Config Pinb.3 = Output                                      'PWM Output rot Timer2
16
Config Pinb.2 = Output                                      'PWM Output grün Timer1
17
Config Pinb.1 = Output                                      'PWM Output blau Timer1
18
19
Led1 Alias Ocr2                                             'PIN 17 PB3
20
Led3 Alias Ocr1al                                           'PIN 16 PB2
21
Led2 Alias Ocr1bl                                           'PIN 15 PB1
22
23
Dim Address As Byte , Command As Byte
24
25
26
Led1 = 0                                                    'startwerte
27
Led2 = 0
28
Led3 = 0
29
30
31
32
Dim Ir_signal As Bit
33
34
35
'Config Timer1 = Falling
36
Enable Interrupts
37
Enable Int0
38
On Int0 Check_rc5
39
40
41
42
43
44
45
Do
46
47
48
   If Ir_signal = 1 Then
49
50
      Getrc5(address , Command)
51
      Ir_signal = 0
52
53
   End If
54
55
56
   Check_input
57
58
59
Loop
60
61
62
63
64
     Sub Check_input()
65
66
                 If Command = 5 Then
67
68
                     While Led1 < 255
69
                          If Ir_signal = 1 Then
70
                             Exit Sub
71
                          End If
72
73
                       Incr Led1
74
75
                       Waitms 20
76
                     Wend
77
78
                End If
79
80
81
     End Sub
82
83
84
End
85
86
87
88
Check_rc5:
89
90
91
      Ir_signal = 1
92
93
Return

was hab ich falsch gemacht?? könnt ihr mir helfen ??

danke für eure hilfe
mfg Flipp

von Rolf I. (for_ro)


Lesenswert?

Nachdem die erste Flanke des RC5 Codes erkannt worden ist, startest du 
im Main-Loop die Erkennung. Für den ersten übertragenen Code fehlt daher 
die erste Flanke, dein GetRC5 funktioniert nicht.
Außerdem ist GetRC5 intern bestimmt unterbrechbar. D.h. bei der nächsten 
Flanke wird zuerst einmal der Interrupt zuschlagen und diese Flanke ist 
dann wieder nicht verfügbar. Du musst also zumindest diesen Interrupt 
vor der Erkennung abschalten. Nach der Erkennung musst du dann den dann 
schon wieder aufgetretenen Interrupt aus dem GIFR löschen, sonst löst 
der Interrupt sofort nach Wieder-Enable aus.
Ich glaube ehrlich gesagt nicht, dass du mit dem GetRC5 Befehl und ext. 
Interrupt in der Lage sein wirst, einen sicheren Empfang zu erreichen.
Außerdem wartet Bascom immer auf zwei komplette Übertragungen, die aber 
über 100ms auseinanderliegen. Die Gesamtzeit für die Ausführung des 
GetRC5 Befehls ist über 150ms, was meistens induskutabel für ein 
allgemeines Disable Interrupts ist.

Gruß

Rolf

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.