RC5 Decoder mal wieder

OP #1466532
Lesenswert?

Hallo zusammen, ich weiß das wurde schon ausführlich behandelt. Komm 
aber nicht weiter:
Folgendes:
- TSOP1736 an INT0 eines ATmega168 @ 8Mhz(funktioniert 
hardwaretechnisch. Habe es mit Bascom erflgreich getestet.
- Code hiervon: 
http://www.rn-wissen.de/index.php/RC5-Decoder_f%C3%BCr_ATMega

Es gab ein paar Probleme mit den Registern vom TC0. Die waren falsch. 
Die habe ich angeglichen... Deswegen hier nochmal der Code:

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

4
// Für alte avr-gcc Versionen
5
#ifndef SIGNAL
6
#include <avr/signal.h>
7
#endif // SIGNAL
8

9
#include "rc5.h"
10

11
#ifndef RC5_INT
12
#define RC5_INT      RC5_INT0
13
#endif  /* RC5_INT */
14
  
15
#ifndef RC5_PRESCALE
16
#define RC5_PRESCALE 1024
17
#endif  /* RC5_PRESCALE */
18

19
/* ******************************************************************************** */
20

21
rc5_t rc5;
22

23
/* ******************************************************************************** */
24

25
#ifndef F_CPU
26
#error Please define F_CPU
27
#endif /* !F_CPU */
28

29
/* µs for a whole bit of RC5 (first & second part) */
30
#define RC5_BIT_US   (64*27)
31

32
#define RC5_TICKS \
33
        ((uint8_t) ((uint32_t) (F_CPU / 1000 * RC5_BIT_US / 1000 / RC5_PRESCALE)))
34
        
35
#define RC5_DELTA \
36
        (RC5_TICKS / 6)
37
        
38
typedef union 
39
{
40
        uint16_t w;
41
        uint8_t  b[2];
42
} code_t;
43

44
static code_t code;
45
static uint8_t rc5_addr;
46

47
/* Number of Bits received so far */
48
/* Number of Interrupts occured so far */
49
static uint8_t nbits;
50
static uint8_t nint;
51

52
/* ******************************************************************************** */
53
        
54
void rc5_init (uint8_t addr)
55
{
56
        nint  = 0;
57
        nbits = 0;
58
        rc5.flip = -1;
59
        
60
        rc5_addr = addr;
61
        
62
#if (RC5_PRESCALE==1024)
63
        TCCR0B = (1 << CS02) | (1 << CS00);
64
#elif   (RC5_PRESCALE==256)
65
        TCCR0B = (1 << CS02);
66
#elif   (RC5_PRESCALE==64)
67
        TCCR0B = (1 << CS01) | (1 << CS00);
68
#else
69
#error This RC5_PRESCALE is not supported
70
#endif /* RC5_PRESCALE */
71
        
72
        /* INTx on falling edge */
73
        /* clear pending INTx */
74
        /* enable INTx interrupt */
75
#if (RC5_INT == RC5_INT0)               
76
        MCUCR = (MCUCR | (1 << ISC01)) & ~ (1 << ISC00);
77
        EIFR = (1 << INTF0);
78
        EIMSK |= (1 << INT0);
79
#elif (RC5_INT == RC5_INT1)             
80
        MCUCR = (MCUCR | (1 << ISC11)) & ~ (1 << ISC10);
81
        EIFR = (1 << INTF1);
82
        EIMSK |= (1 << INT1);
83
#else
84
#error please define RC5_INT
85
#endif /* RC5_INT */
86
}
87

88
/* ******************************************************************************** */
89

90
SIGNAL (SIG_OVERFLOW0)
91
{
92
        TIMSK0 &= ~(1 << TOIE0);
93
        
94
        uint8_t _nbits = nbits;
95
        code_t _code = code;
96
        
97
        if (26 == _nbits)
98
        {
99
                _nbits++;
100
                _code.w <<= 1;
101
        }
102
        
103
        if (27 == _nbits 
104
                && _code.b[1] >= 0x30 /* AGC == 3 */
105
                && 0 > rc5.flip)
106
        {
107
                uint8_t _rc5_code;
108
                uint8_t _rc5_addr;
109
                /* we do the bit manipulation stuff by hand, because of code size */
110
                _rc5_code = _code.b[0] & 0x3f; /* 0b00111111 : #0..#5 */
111
                _code.w <<= 2;
112
                _rc5_addr = _code.b[1] & 0x1f; /* 0b00011111 : #6..#10 */
113
                
114
                if (rc5_addr & 0x80
115
                        || rc5_addr == _rc5_addr)
116
                {
117
                        rc5.code = _rc5_code;
118
                        rc5.addr = _rc5_addr;
119
                        signed char flip = 0;
120
                        if (_code.b[1] & 0x20) /* 0b00100000 : #11 */
121
                                flip = 1;
122
                        rc5.flip = flip;
123
                }
124
        }
125
        
126
        nint = 0;
127
        nbits = 0;
128
        
129
        /* INTx on falling edge */
130
        /* clear pending INTx */
131
        /* enable INTx interrupt */
132
#if (RC5_INT == RC5_INT0)               
133
        MCUCR = (MCUCR | (1 << ISC01)) & ~ (1 << ISC00);
134
        EIFR = (1 << INTF0);
135
        EIMSK |= (1 << INT0);
136
#elif (RC5_INT == RC5_INT1)             
137
        MCUCR = (MCUCR | (1 << ISC11)) & ~ (1 << ISC10);
138
        EIFR = (1 << INTF1);
139
        EIMSK |= (1 << INT1);
140
#endif
141
}
142

143
/* ******************************************************************************** */
144

145
#if (RC5_INT == RC5_INT0)               
146
SIGNAL (SIG_INTERRUPT0)
147
#elif (RC5_INT == RC5_INT1)             
148
SIGNAL (SIG_INTERRUPT1)
149
#endif /* RC5_INT */
150
{
151
        code_t _code = code;
152
        uint8_t _nint = nint;
153
        
154
        uint8_t tcnt0 = TCNT0;
155
        TCNT0 = 0;
156
        
157
        if (0 == _nint)
158
        {
159
                /* INTx on both edges */
160
#if (RC5_INT == RC5_INT0)               
161
                MCUCR = (MCUCR | (1 << ISC00)) & ~ (1 << ISC01);
162
#elif (RC5_INT == RC5_INT1)             
163
                MCUCR = (MCUCR | (1 << ISC10)) & ~ (1 << ISC11);
164
#endif /* RC5_INT */
165
        
166
                TIFR0 = (1 << TOV0);
167
                TIMSK0 |= (1 << TOIE0);
168
                _code.w = 0;
169
        }
170
        else
171
        {
172
                /* Number of bits of the just elapsed period */
173
                uint8_t n = 1;
174
         
175
                /* Bits received so far */
176
                uint8_t _nbits = nbits;
177
        
178
                /* is TCNT0 close to RC5_TICKS or RC5_TICKS/2 ? */
179
                if (tcnt0 > RC5_TICKS + RC5_DELTA)
180
                        goto invalid;
181
                else if (tcnt0 < RC5_TICKS/2 - RC5_DELTA)
182
                        goto invalid;
183
                else if (tcnt0 > RC5_TICKS - RC5_DELTA)
184
                        n = 2;
185
                else if (tcnt0 > RC5_TICKS/2 + RC5_DELTA)
186
                        goto invalid;
187
                
188
                /* store the just received 1 or 2 bits */
189
                do
190
                {
191
                        _nbits++;
192
                        if (_nbits & 1)
193
                        {
194
                                _code.w <<= 1;
195
                                _code.b[0] |= _nint & 1;
196
                        }
197
                } 
198
                while (--n);
199
                
200
                if (0)
201
                {
202
                        invalid:
203
                        
204
                        /* disable INTx, run into Overflow0 */
205
#if (RC5_INT == RC5_INT0)               
206
                        EIMSK &= ~(1 << INT0);
207
#elif (RC5_INT == RC5_INT1)             
208
                        EIMSK &= ~(1 << INT1);
209
#endif /* RC5_INT */
210

211
                        _nbits = 0;
212
                }
213
                
214
                nbits = _nbits;
215
        }
216

217
        code = _code;
218
        nint = 1+_nint;
219
}

rc5.h
1
#ifndef _RC5_H_
2
#define _RC5_H_
3

4
#include <inttypes.h>
5

6
#define RC5_INT0 0
7
#define RC5_INT1 1
8

9
#define RC5_ALL 0xff
10

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

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

21
#endif /* _RC5_H_ */

Folgendes in der Main:
Init habe ich durchgeführt (alle Adressen). Sei() steht ebenfalls drin.
1
//RC5 Test
2
      disp_string("RC5:",6,1);
3
       /* Gibt's was Neues? */
4
       if (-1 == rc5.flip)
5
       {
6
          /* Nein, dann mach irgendwas (oder nix) */
7
       }
8
       else
9
       {
10
          /* Ja, dann rc5.code merken und evtl. rc5.addr */
11
          /* falls man die braucht und nicht sowieso schon kennt */
12
          uint8_t code = rc5.code;
13
          uint8_t addr = rc5.addr;
14
          
15
            blue(245);
16

17
        disp_char(code,10,1);
18
        
19
        /* und auf naechstes Zeichen warten */
20
          rc5.flip = -1;
21
      
22
          /* code (evtl. addr) auswerten */
23
     }
Es wird aber leider nix angezeigt. Also er springt nichtmal in die 
Routine
uint8_t code = rc5.code;   uint8_t addr = rc5.addr;

Habt ihr ne Idee woran es liegen könnt? Ich weiss nämlich nicht mehr 
weiter (Prescaler = 256 habe ich auch schon probiert).
Danke!!!!

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