Hallo Forumgemeinde,
ich habe mir die RC5 Software von Peter Dannegger
file:///S:/Studienarbeit_Paul/sonstiges/RC5_Code_by%20Peter_Dannegger/IN
DEXG.HTM
ins Atmel Studio6.0 geladen. Nun möchte ich das diese mit meinem
ATMega32 läuft. Leider komme ich garnicht dazu etwas zu testen weil der
Kompiler nichteinmal anfängt. Es kommt folgende Meldung:
C:\Programme\Atmel\Atmel Studio 6.0\make\make.exe all
make: *** No rule to make target `MAIN.o', needed by
`RC5_by_Dannegger.elf'. Stop.
Done executing task "RunCompilerTask" -- FAILED.
Done building target "CoreBuild" in project "RC5_by_Dannegger.cproj" --
FAILED.
Done building project "RC5_by_Dannegger.cproj" -- FAILED.
Build FAILED.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped
==========
Es gibt ja 3 Dateien: MAIN.C; MAIN.H und RC5.C
Ich gehe ja mal davon aus das ich MAIN.C kompelieren muss oder ? Ich
finde es nur komisch das bei der MAIN.C nicht auf die Datei RC5
verwiesen wird, woher soll das Programm wissen das es diese Datei gibt ?
Es beinhaltet schließlich die Interrupt Routine...
OK... Problem vorerst gelöst, ich habe bei den #include Dateien
natürlich den richtigen Pfad angeben müssen.
ABER mit dieser Fehlermeldung quäle ich mich auch schon eine Weile
herum:
Error 5 attempt to use poisoned "SIG_OVERFLOW0"
Ist das das falsche Register, heist das beim ATMega32 anders ?
Viele Grüße
Christian P. schrieb:> Error 5 attempt to use poisoned "SIG_OVERFLOW0">> Ist das das falsche Register, heist das beim ATMega32 anders ?
Heißt anders
ISR(TIMER0_OVF_vect)
Du solltest mal in einem neuen avr-libc-user-manual nachsehen.
Hallo Hubert,
danke erstmal für den Tipp. Kannst du mir denn ein gutes manual
empfehlen ? Jetzt kommt zwar keine Fehlermeldung mehr aber wenn ich es
kompiliere dann passiert leider trotzdem nichts wenn ich auf der
Fernbedienung herumtippe :D Muss ich bei dem Code nochwas verändern ??
Ich habe bei der MAIN.c Datei noch folgende Zeilen verändert:
#define xRC5_IN PINA
#define xRC5 PA0 // IR input low active
Somit kann ich den Ausgang des TSOP 31236 daran anschließen.
Viele Grüße
Ich arbeite immer noch mit AVR-Studio 4.19, da ist so ein Manual in der
Hilfe dabei.
Der TSOP wie im Datenblatt angeschaltet sollte so funktionieren.
Den Code hatte ich vor einiger Zeit mal auf einem Mega8 getestet und hat
funktioniert.
Schon mit einem Oszi geschaut ob aus dem TSOP wirklich was herauskommt?
Hallo Hubert,
im Dateianhang siehst du das da wirklich was rauskommt :) Ich denke so
sollte das aussehen. Es ist auch ein RC5 Code das ist sicher. Aber ich
denke ich muss diesen : TCNT0 Timer anders beim ATMega ansprechen. Das
Register heist glaube ich anders aber ich schaue gleich im Datenblatt.
Dann habe ich noch die PORTs entsprechend konfiguriert:
void init_Portpins (void)
{
DDRB = 0xFF; // pull-ups default
PORTB = 0xFF; // ouputs driven high
DDRA = 0x00; // set as Input
PORTA = 0xFF; // pull-ups active
}
Somit kann ich an PORTA dann den Ausgang vom TSOP anschließen.
hoffentlich blinkt bald mal eine LED :D
Wie funktioniert das eigentlich mit der zweiten c. Datei. Ich meine da
ist doch überhaupt kein Verweis zu der ISR woher weis das Programm das
es das mit Compilieren muss ?
Gruß Christian
Christian P. schrieb:> Wie funktioniert das eigentlich mit der zweiten c. Datei. Ich meine da> ist doch überhaupt kein Verweis zu der ISR woher weis das Programm das> es das mit Compilieren muss ?
Indem du es mit zum Projekt hinzufügst.
Einfach mal über der Projekt-Dateiansicht die rechte Maustaste drücken.
Da wird es wohl einen Menüpunkt 'Add existing File' oder so ähnlich
geben. Das kann auch unterschiedlich sein, je nachdem über welchem Teil
des Projektbaumes die Maus gerade steht. "Source Files" wäre ein guter
Tipp, wenn man Source Files hinzufügen möchte.
(Wenn nicht, gibt es den sicher auch in irgendeinem der normalen Menüs -
"Project" wäre ein guter Anfang.)
Verwende ebenfalls noch das 4-er Studio, daher bin ich beim 6-er ein
wenig blank. Aber das Prinzip ist immer dasselbe. Das AVR-Studio macht
die Projektverwaltung und als solches muss es wissen, welche Files zum
Projekt gehören. Ergo muss man die zum Projekt hinzufügen.
Du kannst ja schliesslich 20-tausend C-Files auf einem Verzeichnis haben
und trotzdem gehören nur 5 davon zu einem Projekt. Das kann aber die
Projektverwaltung nicht von alleine wissen - daher muss man es ihr
zeigen.
Ok das habe ich auch so gemacht,
und wenn ich dann also auf rechter Mausklick auf das Projekt gehe und
auf Build Solution fügt er alles zusammen nachdem ich jede C. Datei
einzeln kompiliert und auf Fehler geprüft habe ?
Christian P. schrieb:> Ok das habe ich auch so gemacht,>> und wenn ich dann also auf rechter Mausklick auf das Projekt gehe und> auf Build Solution fügt er alles zusammen nachdem ich jede C. Datei> einzeln kompiliert und auf Fehler geprüft habe ?
Du musst nicht 'jede' C-Datei einzeln händisch kompilieren. Dazu hat man
ja eine Projektverwaltung, die sich um sowas kümmert. Man ruft einfach
Build auf (oder drückt - ich denke auch im 6-er Studio ist das immer
noch F7) und das Studio kümmert sich darum, dass alle notwendigen
C-Files (daher muss es die auch kennen) kompiliert und gelinkt werden.
Und wenn es Fehler gibt, dann werden die vom AVR-Studio zusammengefasst
und dem geneigten Programmierer präsentiert. Der korrigiert sie und
startet den nächsten Build, woraufhin nur noch die C-Files kompiliert
werden, die dann auch tatsächlich neu gemacht werden müssen (weil der
Programmierer Änderungen im File gemacht hat, oder weil es Änderungen
über den Umweg eines Header Files gibt).
Wenn du das händisch machen müsstest, bräuchtest du ja keine
Projektverwaltung. Da würde ein stink normaler Editor auch reichen.
Wurde früher auch so gemacht, als noch jedes Byte Hauptspeicher mit Gold
zu bezahlen war.
Hallo,
Also ich kriege den Code nicht zum Laufen. Ich verwende den ATMega32 auf
dem STK500 Bord, habe den PORTB mit den LEDs verbunden und versuche nun
schon ewig das da was passiert... Hier mal der von mir leicht angepasste
Code von Peter Dannegger:
Die MAIN.c
if(!(tmp&0x4000)&&tmp&0x2000)// only if 14 bits received
24
rc5_data=tmp;
25
tmp=0;
26
}
27
28
if((rc5_bit^xRC5_IN)&1<<xRC5)// change detect
29
{
30
rc5_bit=~rc5_bit;//--> 0x00 ->0xFF ->0x00
31
32
if(rc5_time<PULSE_MIN)// to short
33
tmp=0;
34
35
if(!tmp||rc5_time>PULSE_1_2)// start or long pulse time
36
{
37
if(!(tmp&0x4000))// not to many bits
38
tmp<<=1;// shift
39
if(!(rc5_bit&1<<xRC5))//inverted bit
40
tmp|=1;//insert new bit
41
rc5_time=0;// count next pulse time
42
}
43
}
44
rc5_tmp=tmp;
45
}
Vielleicht findet ja jemand den Fehler ich habe so oft drüber geschaut
das ich den Wald vor lauter Bäumen nicht mehr erkenne. Das Signal des
TSOP kommt über Pin PA0 rein.
Vielen Dank schonmal im Vorraus
Christian
Christian P. schrieb:> if(i)> {> DDRB = i; //LED output> }> }
Ähm.
Du schaltest den Port auf Output. Schön.
Und weiter?
Nur weil du einen Portpin auf Output schaltest, leuchtet dort ja noch
keine LED.
Wie sieht es mit deinem Empfänger aus?
Brauchst du dort einen Pullup-Widerstand.
Hast du das schon mal probiert?
1
#include<avr/io.h>
2
3
4
intmain()
5
{
6
DDRB|=(1<<PB0);// LED
7
8
DDRA&=(1<<PA0);// TSOP Eingang
9
PORTA|=(1<<PA0);// Pullup ein
10
11
while(1){
12
if(PINA&(1<<PA0))// was sagt der TSOP? 0 oder 1
13
PORTB|=(1<<PB0);// je nachdem: LED ein oder aus
14
else
15
PORTB&=~(1<<PB0);
16
}
17
}
mit deiner Fernbedienung auf den TSOP linsen und die LED an PA0 muss zu
blinzeln anfangen. Eventuell die Polarität der Ausgabe an PORTB
umdrehen, damit sie 'hell blinzelt' und nicht 'dunkel blinzelt'.
Lichtblitze sieht man besser als wenn eine dauerleuchtende LED kurz
ausgeht.
Solange das nicht funktioniert bedeutet das, das was in deiner Hardware
faul ist.
Fang halt erst mal mit kleinen Brötchen an, ehe du aufs Ganze gehst.
Drücke ich nun bei meiner Fernbedienung eine beliebige Taste dann
blinken alle acht LEDs gleichzeitig auf. Die Hardware scheint zu
funktionieren es muss irgendwas anderes sein. Ich habe nochmals die
Register kontrolliert ob die anders heißen oder so aber es sind genau
die wie auch im Datenblatt...
Karl Heinz Buchegger schrieb im Beitrag:
> hat PeDa da das volatile vergessen, oder hast du es rausgenommen?
Ich habe in dieser Zeile nichts verändert, bis auf das PeDa dort die
Abkürzung uint statt unsigned integer verwendet hat. Muss denn da eine
volatile variable rein ?
Christian P. schrieb:> Karl Heinz Buchegger schrieb im Beitrag:>> hat PeDa da das volatile vergessen, oder hast du es rausgenommen?>> Ich habe in dieser Zeile nichts verändert, bis auf das PeDa dort die> Abkürzung uint statt unsigned integer verwendet hat. Muss denn da eine> volatile variable rein ?
Ja, muss es
FAQ: Was hat es mit volatile auf sich
Ok ja genau ich habe gerade was zu volatile gelesen habe ich nicht
gewusst. Und was den Takt angeht, da hast du recht ich weis es nicht
genau aber er läuft auf alle Fälle nicht bei der Eingestellten XTAL. Wie
würdest du den Takt am einfachsten Messen ?
Mit einem INterrupt einen I/O Port an und ausschalten und mit Osszi
messen ?
Viele Grüße
Christian P. schrieb:> Ok ja genau ich habe gerade was zu volatile gelesen habe ich nicht> gewusst. Und was den Takt angeht, da hast du recht ich weis es nicht> genau aber er läuft auf alle Fälle nicht bei der Eingestellten XTAL. Wie> würdest du den Takt am einfachsten Messen ?
#define F_CPU 11059200
#include ...
PORTB = 0xFF;
while( 1 )
{
PORTB = 0x00;
_delay_ms( 1000 );
PORTB = 0xFF;
_delay_ms( 1000 );
}
}
entweder der _delay_ms liefert 1000ms, also 1 Sekunde, oder er liefert
sie nicht. Aufs Hz genau ist es natürlich nicht. Aber darauf kommts ja
auch nicht an, wenn die Alternativen 8Mhz oder 1Mhz lauten. Das eine ist
fast 2/3, das andere 1/11. 0.6 Sekunden kannst du aber mit freiem Auge
von 1 Sekunde unterscheiden.
Ich habe dein Program gerade getestet.
In den Fusebits habe ich die Einstellung INTRCOSC_8MHZ_6CK_64MS gewählt,
also auf 8 MHZ interner Takt. Wenn ich das Programm laufen lasse und für
#define F_CPU 8000000 also meinen Eingestellten Takt eingebe dann
blinken die LEDs im Sekundentakt. Bessergesagt mit einer kleinen
Different bei einer Minute etwa eine Sekunde. Das sollte also OK sein.
Trotz der Änderung bin ich dem funktionieren des Codes mit Sicherheit
näher gerückt aber immernoch nicht am Ziel :(
ja und den Global Interrupt Disable cli() habe ich auch vergessen in der
schleife.Es passiert immernoch nichts ich würde aber mal den aktuellen
Code hochladen weil ja doch schon einiges verbessert wurde:
MAIN.c
Christian P. schrieb:
> if(i)> {> DDRB = i; //LED output> }
Ist das nicht das Falsche Register ? Das ist doch das Data Direction
Register ich müsste wenn ich was an den LEDs ausgeben will doch vielmehr
schrieben :
PORTB = i;
oder ?
Christian P. schrieb:> Christian P. schrieb:>> if(i)>> {>> DDRB = i; //LED output>> }>> Ist das nicht das Falsche Register ? Das ist doch das Data Direction> Register ich müsste wenn ich was an den LEDs ausgeben will doch vielmehr> schrieben :>> PORTB = i;>> oder ?
Na dann scroll mal hoch auf das Posting von 14:06
> ich würde aber mal den aktuellen
Code hochladen weil ja doch schon einiges verbessert wurde:
Dürfte ich vorschlagen, dass du mal deine 8 Zeilen Code etwas intensiver
studierst und korrigierst?
Die generelle Codestruktur ist
1
int main()
2
{
3
4
Initialisierungen
5
6
7
sei();
8
9
while( 1 ) {
10
11
Programmlogik
12
13
}
14
}
Was muss alles initialisierst werden? Welche Hardware Komponenten hast
du im Einsatz? Du benutzt
* den Timer
* einen Eingang
* einen (oder mehrere) Ausgänge für die LED
-------
* Was gibt es beim Timer zu tun?
* Was musst du beim Eingang machen? (Musst du überhaupt beim Eingang was
machen? Der Default für Portpins ist immerhin Eingang)
* Was musst du bei den LED Ausgängen machen.
Auch wenn das fad ist, gehört es nichts desto trotz mit zum Programm
dazu, ehe man sich der eigentlichen Programmlogik widmet, die in deinem
Fall ziemlich trivial ist. Fehler in der Initialisierung, vergessene
Komponenten rächen sich durch seltsame bzw. überhaupt nicht
funktionierende Teile.
und wenn du die Interrupts mittels cli() sperrst, dann musst du sie
mittels sei() auch irgendwann danach wieder mal freigeben. Sonst kommt
nun mal kein Interrupt durch und deine ISR wird auch nie aufgerufen.
Das sollte der gleiche Code wie deiner sein, nur etwas anders
formatiert. Mit UART und LCD-Ausgabe. Wenn du kein LCD anschließt ist es
egal.
Eingabe-Pin und LED-Ausgabe musst du eventuell anpassen.
Hallo,
nach einigen Testprogrammen was das Auslösen von Interrupts usw.
anbelangt habe ich auf Grundlage von Huberts Code eine funktionierende
Lösung gefunden. Eines der trivialsten Fehler von mir war, das beim
STK500 die LEDs invertiert anzusprechen sind also z.b muss ich schreiben
: PORTB = ~i;
Somit werden die Tastencodes über die LEDs korrekt angezeigt.
Danke vielmals für eure schnelle Hilfe. Karl Heinz, ich bin deinem Tipp
gefolgt und habe es auch als sehr hilfreich gefunden das eine gewisse
Ordnung in einem Programm gut ist selbst zum eigenen Verständnis,
vorallem aber wenn man sich dann auf die Fehlersuche begibt.
Viele Grüße Christian