rc5 decoder Atmega16 funktioniert nicht

OP #3166908
Lesenswert?

Hallo,
ich habe mal wieder ein kleines Problem. Ich bin gerade dabei mir einen 
Vorverstärker mit Atmega16 und TDA7439 als Herzstück zu bauen. Alles 
läuft soweit einwandfrei (LCD und TDA). Nun möchte ich das ganze um 
einen RC5-Empfänger ergänzen. An PB2 habe ich einen TSOP1136 
angeschlossen, mit 10k Pullup. Als Code verwende ich eine angepasste 
Version hiervon: 
http://www.rn-wissen.de/index.php/RC5-Decoder_f%C3%BCr_ATMega, weil mein 
Timer0 schon mit dem Drehimpulsgeber beschäftigt ist und INT0 und INT1 
vom LCD belegt werden. meine rc5.h:
1
 #ifndef _RC5_H_
2
#define _RC5_H_
3

4
#include <inttypes.h>
5

6
#define RC5_INT2 2
7

8
#define RC5_ALL 0xff
9

10
typedef struct
11
{
12
  volatile uint8_t code;
13
  volatile uint8_t addr;
14
  volatile signed char flip;
15
} rc5_t;
16

17
extern rc5_t rc5;
18
extern void rc5_init (uint8_t addr);
19

20
#endif /* _RC5_H_ */

meine rc5.c:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
#include "rc5.h"
5

6
#ifndef RC5_PRESCALE
7
#define RC5_PRESCALE 64
8
#endif  /* RC5_PRESCALE */
9

10
/* ******************************************************************************** */
11

12
rc5_t rc5;
13

14
/* ******************************************************************************** */
15

16
#ifndef F_CPU
17
#error Please define F_CPU
18
#endif /* !F_CPU */
19

20
/* µs for a whole bit of RC5 (first & second part) */
21
#define RC5_BIT_US   (64*27)
22

23
#define RC5_TICKS \
24
        ((uint8_t) ((uint32_t) (F_CPU / 1000 * RC5_BIT_US / 1000 / RC5_PRESCALE)))
25

26
#define RC5_DELTA \
27
        (RC5_TICKS / 6)
28

29
typedef union
30
{
31
        uint16_t w;
32
        uint8_t  b[2];
33
} code_t;
34

35
static code_t code;
36
static uint8_t rc5_addr;
37

38
/* Number of Bits received so far */
39
/* Number of Interrupts occured so far */
40
static uint8_t nbits;
41
static uint8_t nint;
42

43
/* ******************************************************************************** */
44

45
void rc5_init (uint8_t addr)
46
{
47
        nint  = 0;
48
        nbits = 0;
49
        rc5.flip = -1;
50

51
        rc5_addr = addr;
52

53
#if (RC5_PRESCALE==1024)
54
        TCCR2 |= ((1 << CS22) | (1 << CS20) | (1 << CS21));
55
#elif   (RC5_PRESCALE==256)
56
        TCCR2 |= ((1 << CS22) | (1 << CS21));
57
#elif   (RC5_PRESCALE==64)
58
        TCCR2 |= (1 << CS22);
59
#else
60
#error This RC5_PRESCALE is not supported
61
#endif /* RC5_PRESCALE */
62

63
        /* INTx on falling edge */
64
        /* clear pending INTx */
65
        /* enable INTx interrupt */
66
MCUCR &= ~(1 << ISC2);
67
GIFR |= (1 << INTF2);
68
GICR |= (1 << INT2);
69
}
70

71
/* ******************************************************************************** */
72

73
ISR(TIMER2_OVF_vect)
74
{
75
        TIMSK &= ~(1 << TOIE2);
76

77
        uint8_t _nbits = nbits;
78
        code_t _code = code;
79

80
        if (26 == _nbits)
81
        {
82
                _nbits++;
83
                _code.w <<= 1;
84
        }
85

86
        if (27 == _nbits
87
                && _code.b[1] >= 0x30 /* AGC == 3 */
88
                && 0 > rc5.flip)
89
        {
90
                uint8_t _rc5_code;
91
                uint8_t _rc5_addr;
92
                /* we do the bit manipulation stuff by hand, because of code size */
93
                _rc5_code = _code.b[0] & 0x3f; /* 0b00111111 : #0..#5 */
94
                _code.w <<= 2;
95
                _rc5_addr = _code.b[1] & 0x1f; /* 0b00011111 : #6..#10 */
96

97
                if ((rc5_addr & 0x80)
98
                        || rc5_addr == _rc5_addr)
99
                {
100
                        rc5.code = _rc5_code;
101
                        rc5.addr = _rc5_addr;
102
                        signed char flip = 0;
103
                        if (_code.b[1] & 0x20) /* 0b00100000 : #11 */
104
                                flip = 1;
105
                        rc5.flip = flip;
106
                }
107
        }
108

109
        nint = 0;
110
        nbits = 0;
111

112
        /* INTx on falling edge */
113
        /* clear pending INTx */
114
        /* enable INTx interrupt */
115

116
MCUCR &= ~(1 << ISC2);
117
GIFR |= (1 << INTF2);
118
GICR |= (1 << INT2);
119

120
}
121

122
/* ******************************************************************************** */
123

124

125
ISR(INT2_vect)
126
{
127
        code_t _code = code;
128
        uint8_t _nint = nint;
129

130
        uint8_t tcnt0 = TCNT2;
131
        TCNT2 = 0;
132

133
        if (0 == _nint)
134
        {
135

136
            MCUCR &= ~(1 << ISC2);
137

138
                TIFR |= (1 << TOV2);
139
                TIMSK |= (1 << TOIE2);
140
                _code.w = 0;
141
        }
142
        else
143
        {
144
                /* Number of bits of the just elapsed period */
145
                uint8_t n = 1;
146

147
                /* Bits received so far */
148
                uint8_t _nbits = nbits;
149

150
                /* is TCNT0 close to RC5_TICKS or RC5_TICKS/2 ? */
151
                if (tcnt0 > RC5_TICKS + RC5_DELTA)
152
                        goto invalid;
153
                else if (tcnt0 < RC5_TICKS/2 - RC5_DELTA)
154
                        goto invalid;
155
                else if (tcnt0 > RC5_TICKS - RC5_DELTA)
156
                        n = 2;
157
                else if (tcnt0 > RC5_TICKS/2 + RC5_DELTA)
158
                        goto invalid;
159

160
                /* store the just received 1 or 2 bits */
161
                do
162
                {
163
                        _nbits++;
164
                        if (_nbits & 1)
165
                        {
166
                                _code.w <<= 1;
167
                                _code.b[0] |= _nint & 1;
168
                        }
169
                }
170
                while (--n);
171

172
                if (0)
173
                {
174
                        invalid:
175

176
                        /* disable INTx, run into Overflow0 */
177
                        GICR &= ~(1 << INT2);
178

179
                        _nbits = 0;
180
                }
181

182
                nbits = _nbits;
183
        }
184

185
        code = _code;
186
        nint = 1+_nint;
187
}

der restliche relevante Teil:
1
...
2
#include "rc5.h"
3
...
4
void main()
5
{
6
...
7
  rc5_init(RC5_ALL);
8
  sei(); 
9
        while(1) {
10
           if (-1 == rc5.flip){}
11
           else {
12
            GLCD_ClearScreen();
13
            GLCD_WriteInt(rc5.code);
14
            rc5.flip = -1;
15
          
16
       }
17
   }
18
}
Ich habe jetzt schon 2 Universalfernbedienungen mit den verschiedensten 
Codes von Philips probiert und bekomme keinen einzigen code. Könnt ihr 
mir irgendwie weiterhelfen? An der Form kann man sicher noch arbeiten 
aber es sollte lesbar sein.

Vielen Dank für eure Hilfe.
Gast #3166929
Lesenswert?

Max W. schrieb:

> Ich habe jetzt schon 2 Universalfernbedienungen mit den verschiedensten
> Codes von Philips probiert und bekomme keinen einzigen code.

Ähem...

Wackelt denn überhaupt irgendwas am Pin, wenn du einen Knopf auf der FB 
drückst?

Weil: ohne Signal kannst du nix decodieren. Es macht also überhaupt 
keinen Sinn, bei der Fehlersuche mit dem Decoderprgramm anzufangen. 
Erstmal muß geklärt sein, ob es überhaupt ein Signal zum Decodieren 
gibt.

Und nein: längst nicht jede RC5-FB (auch nicht die von Philips) sendet 
mit 36kHz Träger! Und dein TSSOP kann nur 36kHz empfangen.
Gast #3167017
Lesenswert?

Auch wenn RC5 überall bei den Mikrocontroller-Beispielen das am 
weitesten verbreitetste Sendeformat zu sein scheint, in realen 
Fernbedienungen kam das wohl nur äußerst selten vor. Deine 
Universalfernbedienung kann also duchaus auch bei Philips-Emulation was 
ganz anderes senden.

Ansonsten, wie schon gesagt, erst einmal schauen, ob überhaupt ein 
Signal am Pin ankommt.

Oliver
Gast #3167094
Lesenswert?

Oliver schrieb:

> Auch wenn RC5 überall bei den Mikrocontroller-Beispielen das am
> weitesten verbreitetste Sendeformat zu sein scheint, in realen
> Fernbedienungen kam das wohl nur äußerst selten vor.

HEUTE ist das bei Neugeräten tatsächlich so. Vor zehn Jahren sah das 
noch ganz anders aus.

Allerdings: Die Chance, bei Universal-FBs unter Philips-Codes welche mit 
RC5-Codierung zu finden, ist auch heute noch extrem hoch, denn die 
Dinger enthalten naturgemäß ausschließlich die Codes von Geräten der 
Vergangenheit und nicht der Gegenwart oder gar der Zukunft.

Auch Denken will gelernt sein!
OP #3172417
Lesenswert?

So ich konnte erst jetzt am Projekt weiterarbeiten, war über das 
Wochenende verreist. Ein Signal kommt am TSOP an. getestet habe ich das 
Ganze mit der Fernbedienung von meinem Philips BDP7500MKII. Demnach muss 
der Fehler im Code liegen. Wie kann ich jetzt weiter vorgehen?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren