Forum: Compiler & IDEs Anfängerfrage


von Toolchaire (Gast)


Lesenswert?

Hallo liebe Community,

bin derzeit dabei einen IR-Empfänger mithilfe eines ATMega8 zu 
programmieren.
Als Protokoll verwende ich das RC5-Protkoll von  Phillips da es recht 
verbreitet ist.

Da ich alles in C schreibe (bzw. versuche :P) benutzte ich den avr-gcc 
Compiler für das AVR-Studio.

Habe etwas im Netz recherchiert und bin auf die Anleitung von 
"Roboternetz" gekommen: 
rn-wissen.de/index.php/RC5-Decoder_f%C3%BCr_ATMega

Da meine Kenntnisse nicht allzu gut sind, ich dies aber als ein Projekt 
zugeteilt bekommen habe möchte ich das natürlich halbwegs fertigstellen. 
Bitte hierfür Verständnis haben, ich gebe mir Mühe! Für alle, die keine 
Interesse haben zu helfen, bitte ich auch hier in den Thread nichts zu 
posten :).


Also, wiegesagt ich habe den  Code von RN und auch abgetippt, versucht 
zu verstehen und compiliert. Leider funktioniert das bis jetzt noch 
nicht, ich habe hier mal meinen Code:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
5
// Für alte avr-gcc Versionen
6
#ifndef SIGNAL
7
#include <avr/signal.h>
8
#endif // SIGNAL
9
10
#include "rc5_decoder.h"
11
12
#ifndef RC5_INT
13
#define RC5_INT      RC5_INT0
14
#endif  /* RC5_INT */
15
  
16
#ifndef RC5_PRESCALE
17
#define RC5_PRESCALE 1024
18
#endif  /* RC5_PRESCALE */
19
20
/* ******************************************************************************** */
21
22
rc5_t rc5;
23
24
/* ******************************************************************************** */
25
26
#define F_CPU 4000000
27
28
/* µs for a whole bit of RC5 (first & second part) */
29
#define RC5_BIT_US   (64*27)
30
31
#define RC5_TICKS \
32
        ((uint8_t) ((uint32_t) (F_CPU / 1000 * RC5_BIT_US / 1000 / RC5_PRESCALE)))
33
        
34
#define RC5_DELTA \
35
        (RC5_TICKS / 6)
36
        
37
typedef union 
38
{
39
        uint16_t w;
40
        uint8_t  b[2];
41
} code_t;
42
43
static code_t code;
44
static uint8_t rc5_addr;
45
46
/* Number of Bits received so far */
47
/* Number of Interrupts occured so far */
48
static uint8_t nbits;
49
static uint8_t nint;
50
51
/* ******************************************************************************** */
52
        
53
void rc5_init (uint8_t addr)
54
{
55
        nint  = 0;
56
        nbits = 0;
57
        rc5.flip = -1;
58
        
59
        rc5_addr = addr;
60
61
#if (RC5_PRESCALE==1024)
62
        TCCR0 = (1 << CS02) | (1 << CS00);
63
#elif   (RC5_PRESCALE==256)
64
        TCCR0 = (1 << CS02);
65
#elif   (RC5_PRESCALE==64)
66
        TCCR0 = (1 << CS01) | (1 << CS00);
67
#else
68
#error This RC5_PRESCALE is not supported
69
#endif /* RC5_PRESCALE */
70
        
71
        /* INTx on falling edge */
72
        /* clear pending INTx */
73
        /* enable INTx interrupt */
74
#if (RC5_INT == RC5_INT0)               
75
        MCUCR = (MCUCR | (1 << ISC01)) & ~ (1 << ISC00);
76
        GIFR = (1 << INTF0);
77
        GICR |= (1 << INT0);
78
#else
79
#error please define RC5_INT
80
#endif /* RC5_INT */
81
}
82
83
/* ******************************************************************************** */
84
85
SIGNAL (SIG_OVERFLOW0)
86
{
87
        TIMSK &= ~(1 << TOIE0);
88
        
89
        uint8_t _nbits = nbits;
90
        code_t _code = code;
91
        
92
        if (26 == _nbits)
93
        {
94
                _nbits++;
95
                _code.w <<= 1;
96
        }
97
        
98
        if (27 == _nbits 
99
                && _code.b[1] >= 0x30 /* AGC == 3 */
100
                && 0 > rc5.flip)
101
        {
102
                uint8_t _rc5_code;
103
                uint8_t _rc5_addr;
104
                /* we do the bit manipulation stuff by hand, because of code size */
105
                _rc5_code = _code.b[0] & 0x3f; /* 0b00111111 : #0..#5 */
106
                _code.w <<= 2;
107
                _rc5_addr = _code.b[1] & 0x1f; /* 0b00011111 : #6..#10 */
108
                
109
                if (rc5_addr & 0x80
110
                        || rc5_addr == _rc5_addr)
111
                {
112
                        rc5.code = _rc5_code;
113
                        rc5.addr = _rc5_addr;
114
                        signed char flip = 0;
115
                        if (_code.b[1] & 0x20) /* 0b00100000 : #11 */
116
                                flip = 1;
117
                        rc5.flip = flip;
118
                }
119
        }
120
        
121
        nint = 0;
122
        nbits = 0;
123
        
124
        /* INTx on falling edge */
125
        /* clear pending INTx */
126
        /* enable INTx interrupt */
127
#if (RC5_INT == RC5_INT0)               
128
        MCUCR = (MCUCR | (1 << ISC01)) & ~ (1 << ISC00);
129
        GIFR = (1 << INTF0);
130
        GICR |= (1 << INT0);
131
#endif
132
}
133
134
/* ******************************************************************************** */
135
136
#if (RC5_INT == RC5_INT0)               
137
SIGNAL (SIG_INTERRUPT0)
138
#endif /* RC5_INT */
139
{
140
        code_t _code = code;
141
        uint8_t _nint = nint;
142
        
143
        uint8_t tcnt0 = TCNT0;
144
        TCNT0 = 0;
145
        
146
        if (0 == _nint)
147
        {
148
                /* INTx on both edges */
149
#if (RC5_INT == RC5_INT0)               
150
                MCUCR = (MCUCR | (1 << ISC00)) & ~ (1 << ISC01);
151
#endif /* RC5_INT */
152
        
153
                TIFR = (1 << TOV0);
154
                TIMSK |= (1 << TOIE0);
155
                _code.w = 0;
156
        }
157
        else
158
        {
159
                /* Number of bits of the just elapsed period */
160
                uint8_t n = 1;
161
         
162
                /* Bits received so far */
163
                uint8_t _nbits = nbits;
164
        
165
                /* is TCNT0 close to RC5_TICKS or RC5_TICKS/2 ? */
166
                if (tcnt0 > RC5_TICKS + RC5_DELTA)
167
                        goto invalid;
168
                else if (tcnt0 < RC5_TICKS/2 - RC5_DELTA)
169
                        goto invalid;
170
                else if (tcnt0 > RC5_TICKS - RC5_DELTA)
171
                        n = 2;
172
                else if (tcnt0 > RC5_TICKS/2 + RC5_DELTA)
173
                        goto invalid;
174
                
175
                /* store the just received 1 or 2 bits */
176
                do
177
                {
178
                        _nbits++;
179
                        if (_nbits & 1)
180
                        {
181
                                _code.w <<= 1;
182
                                _code.b[0] |= _nint & 1;
183
                        }
184
                } 
185
                while (--n);
186
                
187
                if (0)
188
                {
189
                        invalid:
190
                        
191
                        /* disable INTx, run into Overflow0 */
192
#if (RC5_INT == RC5_INT0)               
193
                        GICR &= ~(1 << INT0);
194
#endif /* RC5_INT */
195
196
                        _nbits = 0;
197
                }
198
                
199
                nbits = _nbits;
200
        }
201
202
        code = _code;
203
        nint = 1+_nint;
204
}
205
206
int main()
207
{
208
209
/**************  INITIALISERUNG ***************/
210
211
212
DDRD = 0x00; /* der ensprechende INT-Port muss INPUT sein */
213
DDRB = 0xff;  
214
215
216
rc5_init (RC5_ALL); /* RC5 initialisieren, alle Adressen zulassen */  
217
218
sei();  /* Interrupts zulassen */
219
220
/**************  ANWENDUNG ***************/
221
222
while(1)
223
{
224
 /* Gibt's was Neues? */
225
if (-1 == rc5.flip)
226
{
227
/* Nein, dann mach irgendwas (oder nix) */
228
}
229
else
230
{
231
/* Ja, dann rc5.code merken und evtl. rc5.addr */
232
/* falls man die braucht und nicht sowieso schon kennt */
233
uint8_t code = rc5.code;
234
uint8_t addr = rc5.addr;
235
/* und auf naechstes Zeichen warten */
236
rc5.flip = -1;
237
238
/* code (evtl. addr) auswerten */
239
240
PORTB  = 0x00;
241
PORTB=rc5.code;
242
_delay_ms(2000);
243
}  //off if 
244
245
} //off  while
246
247
  return 0;
248
}

Leider  funktioniert das nicht, ist wahrscheins ein simpler und 
logischer Fehler, aber ich steck eben nicht in der Materie drin.

Also, dnake für alle die mir freundlich helfen!

Gruß Rainer

von Sepp (Gast)


Lesenswert?

Guten morgen!
Was genau funktioniert denn nicht? Das compilieren oder das Programm?
So genau sagst du das nicht :-)

Was mir auch auffällt das Interrupt Schlagwort "SIGNAL" wird nicht mehr 
verwendet, jetzt nennt man das "ISR".
Welche Version des GCC verwendest du denn? Die aktuellste?

Gruß Sepp

von Toolchaire (Gast)


Lesenswert?

Hi Sepp,

ok also das Compilieren funkt einwandfrei, aber die Funktion des 
Programmes nicht.

Benutze AVR Studio 4.15, ist hier auf dem Schulrechner drauf. Wo kann 
ich die gcc Version einsehen?

Gruß Rainer

von Stryker (Gast)


Lesenswert?

1
#define F_CPU 4000000

Dein µC läuft auch auf 4 Mhz?

von Toolchaire (Gast)


Lesenswert?

Also der ATMega8 läuft ja mit 4Mhz und bei "Tools" --> "AVRProg" -->
"Advanced" ist "ExtXTAL, High frequency" eingestellt...

von Peter D. (peda)


Lesenswert?

Toolchaire schrieb:
> Als Protokoll verwende ich das RC5-Protkoll von  Phillips da es recht
> verbreitet ist.

Es ist nur gut dokumentiert.
Kommerziell benutzt wird es aber nur sehr selten.
Ich habe kein einziges Gerät, das es verwendet.
Selbst Phillips-Geräte benutzen es nicht.

von Toolchaire (Gast)


Lesenswert?

Ok gut zu wissen. Naja, aber das  Problem besteht weiterhin...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hast Du überhaupt noch eine (uralte) Fernbedienung, die RC5 sendet? 
Sonst empfehle ich Dir die Lektüre von IRMP.

von Toolchaire (Gast)


Lesenswert?

Die UR s2 von vivanco. Es geht ja jetzt um  das Programmiertechnsiche 
Problem

von Oliver (Gast)


Lesenswert?

Toolchaire schrieb:
> Es geht ja jetzt um  das Programmiertechnsiche
> Problem

Ganz ehrlich: Threads, in denen jemand von anderen Seiten kopierten 
Sourcecode einstellt, und dann als Fehlerbeschreibung lediglich ein 
"funktzioniert nicht" dazugibt, sind selten zielführend (un im 
allgemeinen in Programmierforen auch nicht gerne gesehen).

Der oben gezeigte Code ist schlicht und einfach absolut grausam. Das ist 
ein Beispiel, wie man Code NICHT schreiben sollte.

Such dir einen anderen.

Schau dir mal das hier an:
http://homepage.hispeed.ch/peterfleury/avr-software.html

oder kurz und knackig, aber auch nicht einfach zu verstehen:
Beitrag "Fernbedien RC5 Empfänger"

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Toolchaire schrieb:

> Leider  funktioniert das nicht, ist wahrscheins ein simpler und
> logischer Fehler,

Kann sein. Muss aber nicht sein.

> aber ich steck eben nicht in der Materie drin.

Das tun die wenigsten hier. Ich denke mal, die meisten müssten sich da 
erst mal einarbeiten.

Da musst du dann eben mal etwas analysieren, welche Codeteile 
funktionieren und welche nicht.
Mein erster Ansatz wäre mal die Fragestellung: Werden die ISR überhaupt 
aufgerufen? Das lässt sich zb mit ein paar LED, die in der jeweilige ISR 
eingeschaltet werde leicht überprüfen.

Da das ganze darauf beruht, dass ein Zähler als Stoppuhr verwendet wird, 
würde mich als nächstes mal interessieren, welche Zählerstände (aka 
welche Zeiten) denn festgestellt werden. Und dann hilft alles nichts, 
dann muss man sich eben mal das RC5 Protokoll etwas genauer ansehen, 
welche Zeiten es eigentlich sein sollten.

von Karl H. (kbuchegg)


Lesenswert?

> Code von RN und auch abgetippt, versucht zu verstehen


Das ist ja schon mal ein Ansatz.
Wenn du denkst du hast seine Funktionsweise so einigermassen verstanden, 
dann überleg dir, welche Werte besonders relevant sind, überleg dir, wie 
du sie dir im laufenden Betrieb ansehen kannst und überprüf
* ob die tatsächlichen Werte dein Verständnis des Codes stützen
* ob sie plausibel sind
* ob sie sich mit der Protokolldefinition decken.


So funktioniert das nun mal als Softwareentwickler.

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.