PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RC5 Code von Roboternetz geht nicht



wisler
19.03.2011, 17:06
Hallo Leute,

ich habe mal wieder ein ATMEL AVR Problem. Ich nutze einen ATmega32 @16MHz. Ich habe versucht den RC5 C-Code zum laufen zu

bringen. Ich habe den Code von diesem Artikel http://www.rn-wissen.de/index.php/RC5-Decoder_f%C3%BCr_ATMega. Leider bekomme

ich ihn nicht zum laufen. Es wird zwar ein Interrupt erkannt, aber die Bits der addr und code Variable sind immer Null egal

welche Taste ich auf meiner Fernbedienung drücke. Ich habe auch schon mehrere Fernbedienungen versucht, doch leider ohne

Ergbenis. Ich weiß das mit den Bits, weil ich die Variable über den UART und RS232 an den PC übertragen lasse. An dem RC5

Code habe ich nichts geändert.
Ich verwende das Pollin Evalution Board und das Addon Board. Auf dem Addon Board ist der TSOP 1136. Ich denke es könnten zwei

Fehlerquellen sein. Erstens in dem Artikel steht nichts von meinem IR Empfänger drin und zweitens meine verwendeten

Fernbedienungen verwenden nicht den RC5 Standart. Ich habe auch schon eine Phillips Fernbedienung verwenden, aber da kommt

dann gar kein Interrupt an.
An was kann das liegen? Sollte ich mal den Empfänger tauschen und einen von dem Artikel verwenden?

Vielen dank schon mal fürs lesen. Vielleicht hat jemand schon den Code zum laufen gebracht und könnte mir vielleicht ein

bisschen helfen. Oder sieht hier noch eine Fehlerquelle.

So und hier mein verwendeter Code:



#include "rc5.h"
#include "uart.h"
#include <avr/io.h>
#include <avr/interrupt.h>

int main()
{
//uint8_t code = 0;
//uint8_t addr = 0;

/*UART INIT*/
uart_init();

/* der ensprechende INT-Port muss INPUT sein */
/* RC5 initialisieren, alle Adressen zulassen */
rc5_init (RC5_ALL);

/* Interrupts zulassen */
sei();

while(1)
{
/* Gibt's was Neues? */
if (-1 == rc5.flip)
{
/* Nein, dann mach irgendwas (oder nix) */
}
else
{
/* Ja, dann rc5.code merken und evtl. rc5.addr */
/* falls man die braucht und nicht sowieso schon kennt */
/*code = rc5.code;
addr = rc5.addr;*/

uint8_t code = rc5.code;
uint8_t addr = rc5.addr;


//FB Code senden!
uart_putc(code);
uart_putc(' ');
uart_putc(addr);
/* und auf naechstes Zeichen warten */
rc5.flip = -1;

/* code (evtl. addr) auswerten */
}
}
return 0;
}

Wisler

TobiKa
19.03.2011, 18:17
Erstmal scheint der Code nciht für einen ATmega32 geschrieben zu sein. (Wenn ich den Artikel richtig gelesen hab)
Und bis du Sicher das der Emüfänger an PD2 am µC geht?

steveLB
19.03.2011, 21:58
Wichtig ist nicht die Pin NR, sonder der Pin an dem der INTO oder INT1 ist. // damit es allgemein gehen soll.
du rufst mit der rc5_init (RC5_all) eine funktion aus rc5.c auf.
Wie und wo ist der Datenausgang des TSOP dran, an INTO oder INT1 ?
Beim Mega16 ist INTO an PD2, so wie TobiKa sagt. Am Mega 32 wohl auch, ( im Datenblatt nachschauen)

in dieser Zeile definierst du das :
#ifndef RC5_INT
#define RC5_INT RC5_INT0 // hier ist int0 der pin für den data_out des TSOP oder halt RC5_INT1 für den anderen
#endif /* RC5_INT */

Desweitern, wo definierst du den Tsop-Pin als Eingang ? z.b.
// Into pin auf Eingang stellen, hier PD2
DDRD &= ~(1<<PD2); // eingang

denn: Pin nicht als Eingang => auch kein Empfang am µC

falls du eine RC5 Fernbedienung hast , würde ich folgende Zeilen mal einfügen( und zwar da woe bei dir "FB Code senden! " steht:
// ach ps. wenn wir schon dabei sind, meide sonderzeichen auch im kommentar, gewöhn dir gar nicht erst an Sonderzeichen zu nutzen, also kein -> ! mehr

if(code == 32)
{
PORTB ^= (1<<PB0);
}

und an PB0 eine LED , denn drückst du nun die Program+ taste, so müßte die LED toggeln.

FCPU definiert im rc5.c und auch im makefile ? z.b.:
#define F_CPU 16000000UL

und im Makefile ( mit editor öffnen)

# MCU name
MCU = atmega16
#oder halt atmega32 für den mega 32

# Main Oscillator Frequency
# This is only used to define F_OSC in all assembler and c-sources.
F_OSC = 16000000

# Output format. (can be srec, ihex, binary)
FORMAT = ihex

# Target file name (without extension).
TARGET = mega16
# oder wie deine .c-datei heißt wo die main-Schleife liegt, nur ohne .c drann


# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c rc5.c
# hier werden alle .c-datein aufgelistet, ohne Komma dazwischen, nur eine Leertaste

so was in der Art,
das sind die wichtigsten Einstellungen die vorgenommen werden müßen damit es klappt, bei mir tut es :)

wisler
21.03.2011, 18:36
Erstmal scheint der Code nciht für einen ATmega32 geschrieben zu sein. (Wenn ich den Artikel richtig gelesen hab)
Und bis du Sicher das der Emüfänger an PD2 am µC geht?

weiter unten steht das:
Portierung ATmegaXX: sollte ohne Anpassung laufen
ATtiny, Classic: Anpassungen erforderlich

Ausserdem sind der Atmega16 und Atmega32 sehr ähnlich in den Sachen, die der Code erfordert. Ja der Empfänger geht wird ja auch ein Interrupt ausgelöst. Nur kommen die Bits net richtig an. Ich denke ich muss mir das Signal mal mit einem Oszi anschauen. Nur leider habe ich keins: :-(

@steveLB

Also des mit dem Pin habe ich überprüft. Leider tut es auch nicht. Auch das mit DDRD habe ich getestet tut leider nicht.



Danke schonmal für eure Tipps. Kann es vielleicht doch am Empfänger liegen, weil ich im Internet noch niemanden gefunden habe, der meinen Empfänger verwendet?

steveLB
21.03.2011, 19:51
ich hab bis jetzt auch immer Tsop 17xx verwendet, kanns versuchen so einen her zu bekommen, wenn du alles aus meinem Post gemacht hast und es immernoch nicht tut, weiß ich auch nimmer weiter

oberallgeier
21.03.2011, 21:22
... muss mir das Signal mal mit einem Oszi anschauen. Nur leider habe ich keins ...Brauchst auch keins. Ich hatte mir diese Schaltung aufgebaut (D:\D_pro-fils\compu+MC\C3\COM-Porttest_div\Infrarot am COM Mit TSOP 17xx.mht) und damit meinen Empfänger getestet, einen (nein, mehrere) SFH5110-36, siehe Link unten bei MiniD0. Dazu gibt es dieses compilierte Basic-Programm, (http://www.skilltronics.de:80/versuch/elektronik_pc/ir.html) mit dem kannst Du die Funktion des Empfängers messen - WIRKLICH messen. Du kannst auch damit analysieren, ob die Steuerung RC-5-Code versendet oder etwas anderes. Ich habe mehrere Fernsteuerungen bzw. ihre Codes getestet, die JVC fand ich viel praktischer als dieses RC-5-Gegurke. Trotzdem läuft derzeit als Steuerung für und in meinem MiniD0 eine alte RC-5, (https://www.roboternetz.de/community/showthread.php?36121-Autonom-in-kleinen-Dosen-R2_D03-Nachfolger-R3D01&p=495507&viewfull=1#post495507) die nicht mit der zugehörigen Glotze verschrottet wurde. Ach ja, die Software fürs RC-5 im MiniD0 hatte ich selbst gebaut.

Und, wie Du oben lesen kannst, dürfte es nicht wirklich auf den Empfängerchip ankommen, da auch der SFH RC-5-fähig ist *ggg*.

Viel Erfolg!

wolf7272
30.08.2013, 14:21
Hallo, ich habe ebenso Probleme mit dem RC5 Code vom RoboterNetz -> http://www.rn-wissen.de/index.php/RC5-Decoder_f%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!
SeveLB hat oben geschrieben das ich den Pin PD2 noch als eingang setzten muss, doch im Original Thread steht " der INT port wird nicht als IN gesetzt" jetzt bin ich verwirrt.

Hier mal meine Datei:
/*
* GccApplication2.c
*
* Created: 29.08.2013 19:25:02
* Author: Hendrik
*/


#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include "rc5.h" //NEU



void rechtsdrehen(int schritte) {
int s;
for(s=schritte; s>0; s--){
PORTD=0b00000111;
_delay_ms(0.1);
PORTD=0b00000101;
_delay_ms(0.1);
}
PORTD=0b00000000;
return;
}

void linksdrehen(int schritte) {
int s;
for(s=schritte; s>0; s--) {
PORTD=0b00000110;
_delay_ms(0.1);
PORTD=0b00000100;
_delay_ms(0.1);
}
PORTD=0b00000000;
return;
}

int main(void)
{ //Eingangsport Init

//DDRD &= ~(1<<PD2); // eingang fuer TSOP-DATA
//PORTD |= (1<<PD2); // Pull Up

DDRB = 0b00000001;
DDRC = 0b00100000;

//uint8_t code = 0;
//uint8_t addr = 0;



/* der ensprechende INT-Port muss INPUT sein */
/* RC5 initialisieren, alle Adressen zulassen */
rc5_init (RC5_ALL);

/* Interrupts zulassen */
sei();

while(1)
{
/* Gibt's was Neues? */
if (-1 == rc5.flip)
{
/* Nein, dann mach irgendwas (oder nix) */
PORTB = 0b00010000;
_delay_ms(10);
PORTB = 0b00000000;
_delay_ms(10);
PORTB = 0b00010000;
_delay_ms(10);
}
else
{
/* Ja, dann rc5.code merken und evtl. rc5.addr */
/* falls man die braucht und nicht sowieso schon kennt */
/*code = rc5.code;
addr = rc5.addr;*/

uint8_t code = rc5.code;
uint8_t addr = rc5.addr;


//Reaktion auf Tastendruck

PORTB = 0b00000001;
_delay_ms(10);
PORTB = 0b00000000;
_delay_ms(10);
PORTB = 0b00000001;
_delay_ms(10);


/* und auf naechstes Zeichen warten */
rc5.flip = -1;

/* code (evtl. addr) auswerten */

}
}
return 0;
}

steveLB
31.08.2013, 07:39
Hast du mal gelesen was der Code macht? Hast ihn grob versteanden ?

wegen : " SeveLB hat oben geschrieben das ich den Pin PD2 noch als eingang setzten muss, doch im Original Thread steht " der INT port wird nicht als IN gesetzt" jetzt bin ich verwirrt."

Es steht doch :" /* der ensprechende INT-Port muss INPUT sein */ " wenn du mal den ersten Link, zum Artikel nimmst.
Also setzte den auch auf Input. Und wenn du wieder mal verwirrt bist, dann probiere beide Möglichkeiten aus ;) .

in der Klammer von :
if (-1 == rc5.flip)
{ .. }
kommt nichts rein, es bleibt nur der eine Kommentar (" // Nein, dann mach irgendwas (oder nix)") drinnen.
danach kommt die Klammer der
else {.. } ,
hier wird der Tastendruck ausgewertet. Aber wie ? Ganz einfach es wird in der Variablen "addr" die Adresse und in der Variablen " code" der RC5 Code reingeschrieben, mehr nicht, alles andere passiert von alleine im Interrupt. Also in code ist jetzt der code der Taste gespeichert die du gedrückt hast.
Somit musst du hier so was machen:
if(code == 33)
{ ... // was getan werden soll beim druck der Taste mit dem Code 33 }

33 und 32 sind entweder Volume up/ down oder Channel up/down auf einer Fernbedienung mit RC5.

wolf7272
31.08.2013, 11:35
Ich habe jedenfall den code der Main funktion verstanden. Mir ist auch klar das in die If klammer eigentlich nichts reinkommt und man in else den code auswerten kann.
Das Problem ist nur es Funktioniert nicht. Und ich habe alles erdenkliche ausprobiert, schon bevor ich hier gepostet habe ;)

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 :



#define F_CPU 16000000UL

#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include "rc5.h"


int main(void)
{ //Eingangsport Init
DDRB = 0b11111111;


DDRD &= ~(1<<PD2); // eingang fuer TSOP-DATA
//PORTD |= (1<<PD2); // Pull Up


/* der ensprechende INT-Port muss INPUT sein */
/* RC5 initialisieren, alle Adressen zulassen */
rc5_init (RC5_ALL);

/* Interrupts zulassen */
sei();

while(1)
{
/* Gibt's was Neues? */
if (-1 == rc5.flip)
{
/* Nein, dann mach irgendwas (oder nix) */

}
else
{
/* Ja, dann rc5.code merken und evtl. rc5.addr */
/* falls man die braucht und nicht sowieso schon kennt */
/*code = rc5.code;
addr = rc5.addr;*/

uint8_t code = rc5.code;
uint8_t addr = rc5.addr;


//Reaktion auf Tastendruck


PORTB = 0b11111111;
_delay_ms(10);
PORTB = 0b00000000;
_delay_ms(10);
PORTB = 0b11111111;
_delay_ms(10);


/* und auf naechstes Zeichen warten */
rc5.flip = -1;

/* code (evtl. addr) auswerten */

}
}
return 0;
}

rc5.h:



#ifndef _RC5_H_
#define _RC5_H_

#include <inttypes.h>

#define RC5_INT0 0
#define RC5_INT1 1

#define RC5_ALL 0xff

typedef struct
{
uint8_t code;
uint8_t addr;
volatile signed char flip;
} rc5_t;

extern rc5_t rc5;
extern void rc5_init (uint8_t addr);

#endif /* _RC5_H_ */ [/c]

rc5.c:


#include <avr/io.h>
#include <avr/interrupt.h>
#include "rc5.h"

#define F_CPU 16000000UL

#ifndef RC5_INT
#define RC5_INT RC5_INT0
#endif /* RC5_INT */

#ifndef RC5_PRESCALE
#define RC5_PRESCALE 1024
#endif /* RC5_PRESCALE */

/* ************************************************** ****************************** */

rc5_t rc5;

/* ************************************************** ****************************** */

#ifndef F_CPU
#error Please define F_CPU
#endif /* !F_CPU */

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

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

#define RC5_DELTA \
(RC5_TICKS / 6)

typedef union
{
uint16_t w;
uint8_t b[2];
} code_t;

static code_t code;
static uint8_t rc5_addr;

/* Number of Bits received so far */
/* Number of Interrupts occured so far */
static uint8_t nbits;
static uint8_t nint;

/* ************************************************** ****************************** */

void rc5_init (uint8_t addr)
{
nint = 0;
nbits = 0;
rc5.flip = -1;

rc5_addr = addr;

#if (RC5_PRESCALE==1024)
TCCR0 = (1 << CS02) | (1 << CS00);
#elif (RC5_PRESCALE==256)
TCCR0 = (1 << CS02);
#elif (RC5_PRESCALE==64)
TCCR0 = (1 << CS01) | (1 << CS00);
#else
#error This RC5_PRESCALE is not supported
#endif /* RC5_PRESCALE */

/* INTx on falling edge */
/* clear pending INTx */
/* enable INTx interrupt */
#if (RC5_INT == RC5_INT0)
MCUCR = (MCUCR | (1 << ISC01)) & ~ (1 << ISC00);
GIFR = (1 << INTF0);
GICR |= (1 << INT0);
#elif (RC5_INT == RC5_INT1)
MCUCR = (MCUCR | (1 << ISC11)) & ~ (1 << ISC10);
GIFR = (1 << INTF1);
GICR |= (1 << INT1);
#else
#error please define RC5_INT
#endif /* RC5_INT */
}

/* ************************************************** ****************************** */

ISR(TIMER0_OVF_vect)
{
TIMSK &= ~(1 << TOIE0);

uint8_t _nbits = nbits;
code_t _code = code;

if (26 == _nbits)
{
_nbits++;
_code.w <<= 1;
}

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

if (rc5_addr & 0x80
|| rc5_addr == _rc5_addr)
{
rc5.code = _rc5_code;
rc5.addr = _rc5_addr;
signed char flip = 0;
if (_code.b[1] & 0x20) /* 0b00100000 : #11 */
flip = 1;
rc5.flip = flip;
}
}

nint = 0;
nbits = 0;

/* INTx on falling edge */
/* clear pending INTx */
/* enable INTx interrupt */
#if (RC5_INT == RC5_INT0)
MCUCR = (MCUCR | (1 << ISC01)) & ~ (1 << ISC00);
GIFR = (1 << INTF0);
GICR |= (1 << INT0);
#elif (RC5_INT == RC5_INT1)
MCUCR = (MCUCR | (1 << ISC11)) & ~ (1 << ISC10);
GIFR = (1 << INTF1);
GICR |= (1 << INT1);
#endif
}

/* ************************************************** ****************************** */

#if (RC5_INT == RC5_INT0)
ISR(INT0_vect)
#elif (RC5_INT == RC5_INT1)
ISR(INT1_vect)
#endif /* RC5_INT */
{
code_t _code = code;
uint8_t _nint = nint;

uint8_t tcnt0 = TCNT0;
TCNT0 = 0;

if (0 == _nint)
{
/* INTx on both edges */
#if (RC5_INT == RC5_INT0)
MCUCR = (MCUCR | (1 << ISC00)) & ~ (1 << ISC01);
#elif (RC5_INT == RC5_INT1)
MCUCR = (MCUCR | (1 << ISC10)) & ~ (1 << ISC11);
#endif /* RC5_INT */

TIFR = (1 << TOV0);
TIMSK |= (1 << TOIE0);
_code.w = 0;
}
else
{
/* Number of bits of the just elapsed period */
uint8_t n = 1;

/* Bits received so far */
uint8_t _nbits = nbits;

/* is TCNT0 close to RC5_TICKS or RC5_TICKS/2 ? */
if (tcnt0 > RC5_TICKS + RC5_DELTA)
goto invalid;
else if (tcnt0 < RC5_TICKS/2 - RC5_DELTA)
goto invalid;
else if (tcnt0 > RC5_TICKS - RC5_DELTA)
n = 2;
else if (tcnt0 > RC5_TICKS/2 + RC5_DELTA)
goto invalid;

/* store the just received 1 or 2 bits */
do
{
_nbits++;
if (_nbits & 1)
{
_code.w <<= 1;
_code.b[0] |= _nint & 1;
}
}
while (--n);

if (0)
{
invalid:

/* disable INTx, run into Overflow0 */
#if (RC5_INT == RC5_INT0)
GICR &= ~(1 << INT0);
#elif (RC5_INT == RC5_INT1)
GICR &= ~(1 << INT1);
#endif /* RC5_INT */

_nbits = 0;
}

nbits = _nbits;
}

code = _code;
nint = 1+_nint;
}

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.

steveLB
31.08.2013, 14:23
Der Code scheint ok zu sein. ich benutzte aber SIGNAL und include

// Für alte avr-gcc Versionen
#ifndef SIGNAL
#include <avr/signal.h>
#endif // SIGNAL

Die Schaltung selber könnte es noch sein, oder falls du ein makefile z.B. bei Programmer Notepad [Win avr] benutzt, das du hier dein rc5.c nicht eingefügt hast
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c lcd.c rc5.c

was ich noch gesehen habe in deiner obigen rc5.h steht

#endif /* _RC5_H_ */ [/c]

was soll das [/c] ?

wolf7272
31.08.2013, 18:42
das "// Für alte avr-gcc Versionen
#ifndef SIGNAL
#include <avr/signal.h>
#endif // SIGNAL"
habe ich herausgenommen weils ja nichtmehr benötigt wird.

und das "[/c]" stammt aus dem forum post und gehört nich zum code ;)

Ich arbeite mit dem Atmel Studio der neusten generation, dachte das makefile wird automatisch generiert-sieht auch so aus als währen die Datein geliste im makefile.
Oder muss ich etwa doch noch deine "source file" deklaration mit reinnehmen? Wenn ja in die makefile oder makedept?

steveLB
31.08.2013, 22:02
hm, ich benutzte avr studio nur zum überspielen der hex. Ich hab das AVR Studiu nicht mehr benutzt weil ich damals probleme hatte andere .c und .h datein mit einzubinden, ich glaub sogar mit der rc5 :) wenn ich mich recht erinnere, seit dem benutz ich nur noch programmers notepad win avr.
Kurzzeitig habe ich es gelöst indem ich alles aus der rc5 .c und .h in die main copiert und angepasst habe.

Villeicht hast du auch kein rechtsklick auf "Source Files " gemacht und "add existing sourcefiles" ausgewählt, um das rc5.c einzufügen.

Lies auch mal folgende Beiträge:
http://www.mikrocontroller.net/topic/263951
http://www.mikrocontroller.net/topic/137661
http://www.mikrocontroller.net/articles/FAQ#Ich_hab_da_mehrere_.2A.c_und_.2A.h_Dateien._Wa s_mache_ich_damit.3F

wolf7272
01.09.2013, 16:14
Ich denke eingebunden habe ich die dateien richtig. Es werden auch im debugg ordner makefile / rc5.o und GccApllication.o und natürlich die GccApllication.hex erzeugt.
Allerdings wenn ich mir die Grafik auf der seite deines letzten Links angucke, glaube ich das da eine *.a datei fehlt? Muss von der rc5.h eine rc5.a datei durchs compilieren erstellt werden?

Und ob ich noch etwas ins makefile eintrage muss ist mir auch unschlüssig. habe diesbezüglich 2 dateien:

makefile:



################################################## ##############################
# Automatically-generated file. Do not edit!
################################################## ##############################

SHELL := cmd.exe
RM := rm -rf

USER_OBJS :=

LIBS :=
PROJ :=

O_SRCS :=
C_SRCS :=
S_SRCS :=
S_UPPER_SRCS :=
OBJ_SRCS :=
ASM_SRCS :=
PREPROCESSING_SRCS :=
OBJS :=
OBJS_AS_ARGS :=
C_DEPS :=
C_DEPS_AS_ARGS :=
EXECUTABLES :=
OUTPUT_FILE_PATH :=
OUTPUT_FILE_PATH_AS_ARGS :=
AVR_APP_PATH :=$$$AVR_APP_PATH$$$
QUOTE := "
ADDITIONAL_DEPENDENCIES:=
OUTPUT_FILE_DEP:=
LIB_DEP:=

# Every subdirectory with source files must be described here
SUBDIRS :=


# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../GccApplication2.c \
../rc5.c


PREPROCESSING_SRCS +=


ASM_SRCS +=


OBJS += \
GccApplication2.o \
rc5.o

OBJS_AS_ARGS += \
GccApplication2.o \
rc5.o

C_DEPS += \
GccApplication2.d \
rc5.d

C_DEPS_AS_ARGS += \
GccApplication2.d \
rc5.d

OUTPUT_FILE_PATH +=GccApplication2.elf

OUTPUT_FILE_PATH_AS_ARGS +=GccApplication2.elf

ADDITIONAL_DEPENDENCIES:=

OUTPUT_FILE_DEP:= ./makedep.mk

LIB_DEP+=

# AVR32/GNU C Compiler





./%.o: .././%.c
@echo Building file: $<
@echo Invoking: AVR/GNU C Compiler : 3.4.2
$(QUOTE)D:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.2.1002\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -funsigned-char -funsigned-bitfields -DDEBUG -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega8 -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -o "$@" "$<"
@echo Finished building: $<




# AVR32/GNU Preprocessing Assembler



# AVR32/GNU Assembler




ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
endif

# Add inputs and outputs from these tool invocations to the build variables

# All Target
all: $(OUTPUT_FILE_PATH) $(ADDITIONAL_DEPENDENCIES)

$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP) $(LIB_DEP)
@echo Building target: $@
@echo Invoking: AVR/GNU Linker : 3.4.2
$(QUOTE)D:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.2.1002\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="GccApplication2.map" -Wl,--start-group -Wl,-lm -Wl,--end-group -Wl,--gc-sections -mmcu=atmega8
@echo Finished building target: $@
"D:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.2.1002\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature "GccApplication2.elf" "GccApplication2.hex"
"D:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.2.1002\avr8-gnu-toolchain\bin\avr-objcopy.exe" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "GccApplication2.elf" "GccApplication2.eep" || exit 0
"D:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.2.1002\avr8-gnu-toolchain\bin\avr-objdump.exe" -h -S "GccApplication2.elf" > "GccApplication2.lss"
"D:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.2.1002\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O srec -R .eeprom -R .fuse -R .lock -R .signature "GccApplication2.elf" "GccApplication2.srec"
"D:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.2.1002\avr8-gnu-toolchain\bin\avr-size.exe" "GccApplication2.elf"







# Other Targets
clean:
-$(RM) $(OBJS_AS_ARGS) $(EXECUTABLES)
-$(RM) $(C_DEPS_AS_ARGS)
rm -rf "GccApplication2.elf" "GccApplication2.a" "GccApplication2.hex" "GccApplication2.lss" "GccApplication2.eep" "GccApplication2.map" "GccApplication2.srec"


und eine makedep.mk mit folgendem inhalt:



################################################## ##############################
# Automatically-generated file. Do not edit or delete the file
################################################## ##############################

GccApplication2.c

rc5.c

Wsk8
01.09.2013, 18:42
Der Code scheint ok zu sein. ich benutzte aber SIGNAL und include

// Für alte avr-gcc Versionen
#ifndef SIGNAL
#include <avr/signal.h>
#endif // SIGNAL
Das hat man nicht grundlos entfernt. Dieses Signal war unpassend von der Namensgebung und andere Compiler verwenden auch ISR. Dadurch ergibt sich bessere portabilität. Also Signal bitte nicht mehr nutzen!!


dachte das makefile wird automatisch generiert-sieht auch so aus als währen die Datein geliste im makefile.
Wird auch automatisch erstellt. An den Dateien nichts ändern!! Dadurch machst du es nur noch schlimmer!


Wie siehts denn aktuell aus? Kurzes Update, da die letzten Posts doch etwas wirr waren.

mfg

wolf7272
01.09.2013, 22:27
Akueller Status:

Ich kann alles compilieren und passende dateien wurden erstellt.
Doch nach überspielen des .hex file, reagiert der Atmega8 auf keinen Tastendruck der fernbediehnung.

Kann es sein das die rc5.h nicht richtig eingebuden ist wenn sie nirgend im makefile erwähnt wird? Die andern beiden Dateien stehen drinn!
Ich hab die rc5.h zwar im solution exporer und im selbigen ordner wie die .c dateien, jeddoch nichts im release ordner wo die fertig compilierten sachen stehen, bzw auch nichts im makefile von der .h zu sehen...

Wsk8
02.09.2013, 13:47
Kann es sein das die rc5.h nicht richtig eingebuden ist wenn sie nirgend im makefile erwähnt wird?
Da in einem Headerfile kein Quellcode zum kompilieren steht, gibts auch kein Kompilat.

Schließ mal ne LED am Port B an und in der INT0 ISR setzt du dann den Port auf Output. Wenn die LED nach einem Tastendruck leuchtet, dann funktionieren schon mal die Interrupts korrekt und der Fehler liegt wo anders.

mfg

wolf7272
02.09.2013, 22:06
So ich habe im Interrupt "ISR(TIMER0_OVF_vect)" einen 10ms langen puls eingebaut.
Dieser wird erfolgreich nach jedem Tastendruck auf den Ausgang gegeben!

Ich habe diesen Puls auch einmal testweise in die If Anweisung in der Main gelegt und festgestellt, dass immer nur die If-Anweisung "WAHR" ist, das programm aber nie in "else" springt.

Wsk8
02.09.2013, 22:45
#endif /* RC5_INT */
{ code_t _code = code; uint8_t _nint = nint; uint8_t tcnt0 = TCNT0; TCNT0 = 0; if (0 == _nint) { /* INTx on both edges */ #if (RC5_INT == RC5_INT0) MCUCR = (MCUCR | (1 << ISC00)) & ~ (1 << ISC01); #elif (RC5_INT == RC5_INT1) MCUCR = (MCUCR | (1 << ISC10)) & ~ (1 << ISC11); #endif /* RC5_INT */ TIFR = (1 << TOV0); TIMSK |= (1 << TOIE0); _code.w = 0; } else { /* Number of bits of the just elapsed period */ uint8_t n = 1; /* Bits received so far */ uint8_t _nbits = nbits; /* is TCNT0 close to RC5_TICKS or RC5_TICKS/2 ? */ if (tcnt0 > RC5_TICKS + RC5_DELTA) goto invalid; else if (tcnt0 < RC5_TICKS/2 - RC5_DELTA) goto invalid; else if (tcnt0 > RC5_TICKS - RC5_DELTA) n = 2; else if (tcnt0 > RC5_TICKS/2 + RC5_DELTA) goto invalid; /* store the just received 1 or 2 bits */ do { _nbits++; if (_nbits & 1) { _code.w <<= 1; _code.b[0] |= _nint & 1; } } while (--n); if (0) { invalid: /* disable INTx, run into Overflow0 */ #if (RC5_INT == RC5_INT0) GICR &= ~(1 << INT0); #elif (RC5_INT == RC5_INT1) GICR &= ~(1 << INT1); #endif /* RC5_INT */ _nbits = 0; } nbits = _nbits; } code = _code; nint = 1+_nint; }
Bei den ganzen if's wird geprüft, ob der Impuls falsch ist. Wenn alles korrekt ist wird die do-while ausgeführt. Prüfe da mal was angesprungen wird.

EDIT: SCH****ß Formatierung -.-
Die if-else abfragen in der INT0 ISR mit der darauffolgenden do-while-schleife

mfg

Hubert.G
03.09.2013, 08:49
Was das timing anbelangt dürfte das Programm ziemlich heikel sein.
Hab das mal auf meinem Pollin-Board aufgebaut und getestet. In der uart-Ausgabe springt der Cursor, zeigt aber nichts an.
Ein anderes RC5-Programm läuft einwandfrei.

wolf7272
03.09.2013, 09:30
So ich hab nun alle möglichkeiten durchgetestet und im Code dokumentiert, ich würde mich sehr freuen wenn du mir anhand dieser Information Näheres sagen könntest:



#if (RC5_INT == RC5_INT0)
ISR(INT0_vect)
#elif (RC5_INT == RC5_INT1)
ISR(INT1_vect)
#endif /* RC5_INT */
{

// Hier impuls sync mit tastendruck

code_t _code = code;
uint8_t _nint = nint;

uint8_t tcnt0 = TCNT0;
TCNT0 = 0;

if (0 == _nint)
{

// Hier impulse mit erster fallender Flanke

/* INTx on both edges */
#if (RC5_INT == RC5_INT0)

// Hier impulse mit erster fallender Flanke

MCUCR = (MCUCR | (1 << ISC00)) & ~ (1 << ISC01);
#elif (RC5_INT == RC5_INT1)

//Hier geht er nicht rein, wegen nutzung von INT0

MCUCR = (MCUCR | (1 << ISC10)) & ~ (1 << ISC11);
#endif /* RC5_INT */

TIFR = (1 << TOV0);
TIMSK |= (1 << TOIE0);
_code.w = 0;

// Hier impulse mit erster fallender Flanke

}
else
{
// Hier impulse mit erster steigender Flanke

/* Number of bits of the just elapsed period */
uint8_t n = 1;

/* Bits received so far */
uint8_t _nbits = nbits;

/* is TCNT0 close to RC5_TICKS or RC5_TICKS/2 ? */
if (tcnt0 > RC5_TICKS + RC5_DELTA)

goto invalid;
else if (tcnt0 < RC5_TICKS/2 - RC5_DELTA){
// Hier impulse mit erster steigender Flanke

goto invalid;}
else if (tcnt0 > RC5_TICKS - RC5_DELTA){
// Hier geht er nicht rein!!

n = 2;}
else if (tcnt0 > RC5_TICKS/2 + RC5_DELTA){
// Hier geht er nicht rein!!

goto invalid;}

/* store the just received 1 or 2 bits */
do
{
// Hier geht er nicht rein!!!

_nbits++;
if (_nbits & 1)
{
_code.w <<= 1;
_code.b[0] |= _nint & 1;
}
}
while (--n);

if (0)
{
// Hier geht er nicht rein!!


invalid:

/* disable INTx, run into Overflow0 */
#if (RC5_INT == RC5_INT0)

// Hier geht er mit erster steigenden Flanke rein

GICR &= ~(1 << INT0);
#elif (RC5_INT == RC5_INT1)

GICR &= ~(1 << INT1);
#endif /* RC5_INT */

// Hier geht er mit erster steigenden Flanke rein

_nbits = 0;
}

// Hier geht er mit erster steigenden Flanke rein

nbits = _nbits;
}

// Hier geht er mit erster fallenden Flanke rein

code = _code;
nint = 1+_nint;
}

Wsk8
03.09.2013, 11:27
Hier liegt ein Timingfehler vor, entweder ist dein Prozessor falsch getaktet oder deine Fernbedienung sendet kein RC5. Im Code springst du nämlich nur die Zeilen für einen ungültigen RC5 Code an.

mfg

Hubert.G
03.09.2013, 14:07
Also der Code funktioniert ohne Änderungen, von SIGNAL abgesehen.
Ich hatte einen Fehler in der UART-Ausgabe.
In der UART-Ausgabe ist natürlich auch noch die Konvertierung auf ASCII mit itoa notwendig.

wolf7272
03.09.2013, 14:26
Die Fernbediehnung müsste eigentlich alles richtig machen, hab eine Loewe Control 150 TV die folgenden Frame aussendet bei der Power Taste: (14 Bit ) 26299

- - - Aktualisiert - - -


In der UART-Ausgabe ist natürlich auch noch die Konvertierung auf ASCII mit itoa notwendig.
Was bedeutet das ( für einen Anfänger)? ;)

Ich habe leider keinen schimmer wie ich dem besagten Timingfehler auf die Spur kommen sollen.. Mehr als den CPU takt mit F_CPU vorgeben kann man doch nicht, oder?

Hubert.G
03.09.2013, 14:39
Auf deinem Terminal möchtest du ja das ASCII-Zeichen sehen und nicht das binäre.

uint8_t code = rc5.code;
uint8_t addr = rc5.addr;
char codea[2];
char addra[2];
//FB Code senden!

itoa(code,codea,10);
itoa(addr,addra,10);
uart_puts(codea);
uart_putc(' ');
uart_puts(addra);
uart_puts( "\n\r" );
/* und auf naechstes Zeichen warten */
rc5.flip = -1;

Das habe ich mal auf die schnelle dazugepfriemelt.
Vor dem while(1) habe ich noch uart_puts("Start"); eingefügt, damit man sieht ob die UART-Ausgabe überhaupt funktioniert.

Wsk8
03.09.2013, 14:39
Was bedeutet das ( für einen Anfänger)? :wink:
Für dich uninteressant solange der Empfang nicht mal funktioniert.


Ich habe leider keinen schimmer wie ich dem besagten Timingfehler auf die Spur kommen sollen.. Mehr als den CPU takt mit F_CPU vorgeben kann man doch nicht, oder?
Doch, du musst die Fuses im Controller so setzen wenn du eine externe Clock verwendest!! F_CPU sagt dem Compiler nur, wie schnell der Controller getaktet ist, setzt aber nicht den Wert selbst im Controller.

mfg

021aet04
03.09.2013, 19:20
Wie schon geschrieben gibst du mit FCPU nur dem Compiler vor wie schnell der µC in der Schaltung takten wird damit dieser das Programm richtig übersetzen kann (wird u.A. bei "wait_ms()" benötigt).

Wenn du im Programm 1MHz vorgibst musst du dem Controller auch eine Takt von 1MHz vorgeben. Die µC haben meist einen internen 8MHz RC Oszillator und einen eingestellten Teiler durch 8, dadurch läuft der µC im Urzustand mit 1MHz.

Du hast dem Compiler vorgegeben das du einen 16MHz Takt verwendest. Du musst also einen 16MHz Takt irgendwie dem µC zur verfügung stellen (entweder Takt oder Quarz) und die Fuses dementsprechend einstellen. Eventuell funktioniert es auch wenn du FCPU auf 8MHz stellst (Interner RC-Oszillator).

MfG Hannes

wolf7272
03.09.2013, 22:52
SO!! Dank euer Unterstützung habe ich das Problem nun endlich gelöst. Wie 021aet04 schon sagt, das Fuse Bit für den internen Takt muss auf F_CPU abgelichen werden!
Habe nun das Fusebit auf 8 MHz intern, und F_CPU dementsprechend auf 8000000 angeglichen, nun funktioniert der Code so wie er soll ;)

Viele Dank an Euch!
gruß wolf7272

021aet04
04.09.2013, 15:46
Herzlichen Glückwunsch, schön das es jetzt funktioniert.

MfG Hannes