Forum: Mikrocontroller und Digitale Elektronik Probleme mit RC5 C- Code


von Hendrik X. (wolf77)


Lesenswert?

Hallo, ich habe ebenso Probleme mit dem RC5 Code vom RoboterNetz -> 
http://www.rn-wissen.de/index.php/RC...%C3%BCr_ATMega . Ich habe ihn 
erfolgreich compilieren können und übertragen auf einen Atmega8 mit 
einem TSOP31236 (36 Khz) IR empänger und einer Loewe Fernbediehnung ( 
Control 150 TV (RC5 Standart)).

Jeddoch reagiert der Kontroller auf keinen einizgen Tastendruck! Das 
Signal am TSOP ausgang habe ich mit einem D-Oscillsoscope nachgemessen, 
da sollte eigendltich alles stimmig sein.
Ich lasse in der Mainschleife ein paar Flanken erzeugen, um überhaupt zu 
gucken ob der uC reagiert, doch leider tut sich an den Ausgängen nichts.

FCPU habe ich auch in der RC5 schon definiert!
Muss ich den Pin PD2 noch als eingang setzten? Im Original Thread steht 
" der INT port wird nicht als IN gesetzt" jetzt bin ich verwirrt.

Hier mal meine Datei:
1
/*
2
* GccApplication2.c
3
*
4
* Created: 29.08.2013 19:25:02
5
* Author: Hendrik
6
*/
7
8
9
#define F_CPU 16000000UL
10
#include <util/delay.h>
11
#include <avr/io.h>
12
#include <avr/interrupt.h>
13
#include <stdint.h>
14
#include "rc5.h" //NEU
15
16
17
18
void rechtsdrehen(int schritte) {
19
int s;
20
for(s=schritte; s>0; s--){
21
PORTD=0b00000111;
22
_delay_ms(0.1);
23
PORTD=0b00000101;
24
_delay_ms(0.1);
25
}
26
PORTD=0b00000000;
27
return;
28
}
29
30
void linksdrehen(int schritte) {
31
int s;
32
for(s=schritte; s>0; s--) {
33
PORTD=0b00000110;
34
_delay_ms(0.1);
35
PORTD=0b00000100;
36
_delay_ms(0.1);
37
}
38
PORTD=0b00000000;
39
return;
40
}
41
42
int main(void)
43
{ //Eingangsport Init
44
45
//DDRD &= ~(1<<PD2); // eingang fuer TSOP-DATA
46
//PORTD |= (1<<PD2); // Pull Up
47
48
DDRB = 0b00000001;
49
DDRC = 0b00100000;
50
51
//uint8_t code = 0;
52
//uint8_t addr = 0;
53
54
55
56
/* der ensprechende INT-Port muss INPUT sein */
57
/* RC5 initialisieren, alle Adressen zulassen */
58
rc5_init (RC5_ALL);
59
60
/* Interrupts zulassen */
61
sei();
62
63
while(1)
64
{
65
/* Gibt's was Neues? */
66
if (-1 == rc5.flip)
67
{
68
/* Nein, dann mach irgendwas (oder nix) */
69
PORTB = 0b00010000;
70
_delay_ms(10);
71
PORTB = 0b00000000;
72
_delay_ms(10);
73
PORTB = 0b00010000;
74
_delay_ms(10);
75
}
76
else
77
{
78
/* Ja, dann rc5.code merken und evtl. rc5.addr */
79
/* falls man die braucht und nicht sowieso schon kennt */
80
/*code = rc5.code;
81
addr = rc5.addr;*/
82
83
uint8_t code = rc5.code;
84
uint8_t addr = rc5.addr;
85
86
87
//Reaktion auf Tastendruck
88
89
PORTB = 0b00000001;
90
_delay_ms(10);
91
PORTB = 0b00000000;
92
_delay_ms(10);
93
PORTB = 0b00000001;
94
_delay_ms(10);
95
96
97
/* und auf naechstes Zeichen warten */
98
rc5.flip = -1;
99
100
/* code (evtl. addr) auswerten */
101
102
}
103
}
104
return 0;
105
}

von leluno (Gast)


Lesenswert?

Dein Programm arbeitet offenbar mit Interrupt, ohne dass du die 
Interruptroutine darstellst.

Du müsstest deine Kontrollabfrage LED an/aus am Anfang der 
Interruptroutine einbauen, um festzustellen ob die Interruptroutine 
überhaupt angesprungen wird. Am besten mit längerem delay als 10ms, weil 
dies kaum wahrnehmbar ist.

Sollte der Interrupt gar nicht ausgelöst werden, würde ich den ir-pin 
zunächst als normalen Eingang mit pullup schalten und über die 
Kontrollabfrage LED an/aus überprüfen,ob am pin überhaupt ein Signal 
ankommt.

von Hendrik X. (wolf77)


Lesenswert?

Also ich habe jetzt mal versucht das so schier wie möglich zu gestalten, 
würde mich sehr freuen wenn jemand die zeit finden könnte mal drüber zu 
gucken ob ich einen fehler drinn habe, denn ich weiß beim besten willen 
nicht mehr was es sein könnte :( (sitze schon seit 2 Tagen daran)

Ich musste in der RC5.c noch SIGNAL (SIG_OVERFLOW0) in 
ISR(TIMER0_OVF_vect) außerdem
SIGNAL (SIG_INTERRUPT0) in ISR(INT0_vect) und SIGNAL (SIG_INTERRUPT1) in 
ISR(INT0_vect) umwandeln- damit der compiler nicht mehr meckert ( habe 
nachgelesen das die befehle veraltet waren)

application.c :
1
#define F_CPU 16000000UL
2
   
3
#include <util/delay.h>
4
#include <avr/io.h>
5
#include <avr/interrupt.h>
6
#include <stdint.h>
7
#include "rc5.h"      
8
9
10
int main(void)
11
{  //Eingangsport Init
12
  DDRB = 0b11111111;
13
  
14
  
15
  DDRD &= ~(1<<PD2);  // eingang fuer TSOP-DATA
16
  //PORTD |= (1<<PD2); // Pull Up
17
  
18
19
    /* der ensprechende INT-Port muss INPUT sein */
20
    /* RC5 initialisieren, alle Adressen zulassen */
21
    rc5_init (RC5_ALL);
22
23
    /* Interrupts zulassen */
24
    sei();
25
26
    while(1)
27
    {
28
        /* Gibt's was Neues? */
29
           if (-1 == rc5.flip)
30
           {
31
              /* Nein, dann mach irgendwas (oder nix) */
32
       
33
           }
34
           else
35
           {
36
              /* Ja, dann rc5.code merken und evtl. rc5.addr */
37
              /* falls man die braucht und nicht sowieso schon kennt */
38
              /*code = rc5.code;
39
              addr = rc5.addr;*/
40
41
            uint8_t code = rc5.code;
42
            uint8_t addr = rc5.addr;
43
44
45
            //Reaktion auf Tastendruck
46
      
47
          
48
         PORTB = 0b11111111;
49
         _delay_ms(10);
50
          PORTB = 0b00000000;
51
         _delay_ms(10);
52
         PORTB = 0b11111111;
53
         _delay_ms(10);
54
        
55
      
56
         /* und auf naechstes Zeichen warten */
57
        rc5.flip = -1;
58
      
59
        /* code (evtl. addr) auswerten */
60
      
61
           }
62
    }
63
    return 0;
64
}

rc5.h:
1
[c]#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_ */ [/c]
rc5.c:
1
[c]#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include "rc5.h"
4
5
#define F_CPU 16000000UL
6
7
#ifndef RC5_INT
8
#define RC5_INT      RC5_INT0
9
#endif  /* RC5_INT */
10
11
#ifndef RC5_PRESCALE
12
#define RC5_PRESCALE 1024
13
#endif  /* RC5_PRESCALE */
14
15
/* ******************************************************************************** */
16
17
rc5_t rc5;
18
19
/* ******************************************************************************** */
20
21
#ifndef F_CPU
22
#error Please define F_CPU
23
#endif /* !F_CPU */
24
25
/* µs for a whole bit of RC5 (first & second part) */
26
#define RC5_BIT_US   (64*27)
27
28
#define RC5_TICKS \
29
((uint8_t) ((uint32_t) (F_CPU / 1000 * RC5_BIT_US / 1000 / RC5_PRESCALE)))
30
31
#define RC5_DELTA \
32
(RC5_TICKS / 6)
33
34
typedef union
35
{
36
  uint16_t w;
37
  uint8_t  b[2];
38
} code_t;
39
40
static code_t code;
41
static uint8_t rc5_addr;
42
43
/* Number of Bits received so far */
44
/* Number of Interrupts occured so far */
45
static uint8_t nbits;
46
static uint8_t nint;
47
48
/* ******************************************************************************** */
49
50
void rc5_init (uint8_t addr)
51
{
52
  nint  = 0;
53
  nbits = 0;
54
  rc5.flip = -1;
55
  
56
  rc5_addr = addr;
57
  
58
  #if (RC5_PRESCALE==1024)
59
  TCCR0 = (1 << CS02) | (1 << CS00);
60
  #elif   (RC5_PRESCALE==256)
61
  TCCR0 = (1 << CS02);
62
  #elif   (RC5_PRESCALE==64)
63
  TCCR0 = (1 << CS01) | (1 << CS00);
64
  #else
65
  #error This RC5_PRESCALE is not supported
66
  #endif /* RC5_PRESCALE */
67
  
68
  /* INTx on falling edge */
69
  /* clear pending INTx */
70
  /* enable INTx interrupt */
71
  #if (RC5_INT == RC5_INT0)
72
  MCUCR = (MCUCR | (1 << ISC01)) & ~ (1 << ISC00);
73
  GIFR = (1 << INTF0);
74
  GICR |= (1 << INT0);
75
  #elif (RC5_INT == RC5_INT1)
76
  MCUCR = (MCUCR | (1 << ISC11)) & ~ (1 << ISC10);
77
  GIFR = (1 << INTF1);
78
  GICR |= (1 << INT1);
79
  #else
80
  #error please define RC5_INT
81
  #endif /* RC5_INT */
82
}
83
84
/* ******************************************************************************** */
85
86
ISR(TIMER0_OVF_vect)
87
{
88
  TIMSK &= ~(1 << TOIE0);
89
  
90
  uint8_t _nbits = nbits;
91
  code_t _code = code;
92
  
93
  if (26 == _nbits)
94
  {
95
    _nbits++;
96
    _code.w <<= 1;
97
  }
98
  
99
  if (27 == _nbits
100
  && _code.b[1] >= 0x30 /* AGC == 3 */
101
  && 0 > rc5.flip)
102
  {
103
    uint8_t _rc5_code;
104
    uint8_t _rc5_addr;
105
    /* we do the bit manipulation stuff by hand, because of code size */
106
    _rc5_code = _code.b[0] & 0x3f; /* 0b00111111 : #0..#5 */
107
    _code.w <<= 2;
108
    _rc5_addr = _code.b[1] & 0x1f; /* 0b00011111 : #6..#10 */
109
    
110
    if (rc5_addr & 0x80
111
    || rc5_addr == _rc5_addr)
112
    {
113
      rc5.code = _rc5_code;
114
      rc5.addr = _rc5_addr;
115
      signed char flip = 0;
116
      if (_code.b[1] & 0x20) /* 0b00100000 : #11 */
117
      flip = 1;
118
      rc5.flip = flip;
119
    }
120
  }
121
  
122
  nint = 0;
123
  nbits = 0;
124
  
125
  /* INTx on falling edge */
126
  /* clear pending INTx */
127
  /* enable INTx interrupt */
128
  #if (RC5_INT == RC5_INT0)
129
  MCUCR = (MCUCR | (1 << ISC01)) & ~ (1 << ISC00);
130
  GIFR = (1 << INTF0);
131
  GICR |= (1 << INT0);
132
  #elif (RC5_INT == RC5_INT1)
133
  MCUCR = (MCUCR | (1 << ISC11)) & ~ (1 << ISC10);
134
  GIFR = (1 << INTF1);
135
  GICR |= (1 << INT1);
136
  #endif
137
}
138
139
/* ******************************************************************************** */
140
141
#if (RC5_INT == RC5_INT0)
142
ISR(INT0_vect)
143
#elif (RC5_INT == RC5_INT1)
144
ISR(INT1_vect)
145
#endif /* RC5_INT */
146
{
147
  code_t _code = code;
148
  uint8_t _nint = nint;
149
  
150
  uint8_t tcnt0 = TCNT0;
151
  TCNT0 = 0;
152
  
153
  if (0 == _nint)
154
  {
155
    /* INTx on both edges */
156
    #if (RC5_INT == RC5_INT0)
157
    MCUCR = (MCUCR | (1 << ISC00)) & ~ (1 << ISC01);
158
    #elif (RC5_INT == RC5_INT1)
159
    MCUCR = (MCUCR | (1 << ISC10)) & ~ (1 << ISC11);
160
    #endif /* RC5_INT */
161
    
162
    TIFR = (1 << TOV0);
163
    TIMSK |= (1 << TOIE0);
164
    _code.w = 0;
165
  }
166
  else
167
  {
168
    /* Number of bits of the just elapsed period */
169
    uint8_t n = 1;
170
    
171
    /* Bits received so far */
172
    uint8_t _nbits = nbits;
173
    
174
    /* is TCNT0 close to RC5_TICKS or RC5_TICKS/2 ? */
175
    if (tcnt0 > RC5_TICKS + RC5_DELTA)
176
    goto invalid;
177
    else if (tcnt0 < RC5_TICKS/2 - RC5_DELTA)
178
    goto invalid;
179
    else if (tcnt0 > RC5_TICKS - RC5_DELTA)
180
    n = 2;
181
    else if (tcnt0 > RC5_TICKS/2 + RC5_DELTA)
182
    goto invalid;
183
    
184
    /* store the just received 1 or 2 bits */
185
    do
186
    {
187
      _nbits++;
188
      if (_nbits & 1)
189
      {
190
        _code.w <<= 1;
191
        _code.b[0] |= _nint & 1;
192
      }
193
    }
194
    while (--n);
195
    
196
    if (0)
197
    {
198
      invalid:
199
      
200
      /* disable INTx, run into Overflow0 */
201
      #if (RC5_INT == RC5_INT0)
202
      GICR &= ~(1 << INT0);
203
      #elif (RC5_INT == RC5_INT1)
204
      GICR &= ~(1 << INT1);
205
      #endif /* RC5_INT */
206
207
      _nbits = 0;
208
    }
209
    
210
    nbits = _nbits;
211
  }
212
213
  code = _code;
214
  nint = 1+_nint;
215
}

Ich habe auch via If anweisung versucht den code 12 (PWR Taste) 
abzufragen.. klappt auch nicht.
Was allerding funktioniert ist wenn ich den Port INT0 (PD2) einfach auf 
LOW abfrage, dann bekomme ich Flanken angezeigt auf dem Oscilloscope 
beim Tastendruck.

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.