PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RC5 AT90S8515 STK500



STK500begin
24.04.2007, 01:16
Hallo,

habe ein Problem mit der Auswertung der RC5 Signale. Zuerst möchte ich meine Hardware beschreiben:

Ein STK500 Board von Atmel mit einem AT90S8515 Mikrocontroller. PORTB ist mit den LEDS verbunden und PORTD mit dem SWITCHES->Standardaufbau. An Port A ist ein Vishay RC5Empfänger korrekt angeschlossen, die INPUT Signale kommen auf PIN7 an. Ich kann sicher davon ausgehen, dass die von der RC5 Fernbedienung Signale am Bord ankommen-> mittels Osziloskop getestet, somit scheidet dies als Fehlerquelle aus.

Jetzt komme ich zum Problem.
Habe im Netz diese schöne Anleitung gefunden :

http://www.asurowiki.de/pmwiki/pmwiki.php/Main/RC5DemoC.

Ich möchte keinen Asuro steuern, sondern vorerst möchte ich wenn ich die Taste 2 drücke, dass die erste LED auf dem Atmel Board aufleuchtet.
Habe das rc5.c File für meine Verwendung wie folgt angepasst:





// ================================================== ======================
// RC5 Infrarot-Empfaenger
// ================================================== ======================
#include <avr/io.h>
#include "rc5.h"


// -----------------------------------------------------------------------------
// Timing
// -----------------------------------------------------------------------------
#define IR_SAMPLES_PER_BIT 8 /*!< 8 Samples per Bit */
#define IR_SAMPLES_PER_BIT_EARLY 6 /*!< Flanke fruehestens nach 7 Samples */
#define IR_SAMPLES_PER_BIT_LATE 10 /*!< Flanke spaetestens nach 9 Samples */
#define IR_SAMPLES_PER_BIT_MIN 3 /*!< Flanke vor 3 Samples -> paket verwerfen */
#define IR_PAUSE_SAMPLES 250 /*!< Startbit ist erst nach 200 Samples ohne */
// Pegelaenderung gueltig -- eigentlich muesste
// man rund 500 Samples abwarten (50 x
// Bitzeit), doch weil der Samplezaehler ein
// Byte ist, beschraenken wir uns hier auf ein
// Minimum von 250 Samples


//Meine Anpassungen an PORT A
#define IR_PORT PORTA /*!< Port A */
#define IR_DDR DDRA /*!< DDR of Port A */
#define IR_PINR PINA /*!< Port A input */
#define IR_PIN PA7 /*!< Pin 7 */


//Hier habe ich die den Code für 2 als Konstante definiert
#define TWO 0x1002

static uint8_t RC5lastsample = 0; /*!< zuletzt gelesenes Sample */
static uint8_t RC5bittimer = 0; /*!< zaehlt die Aufrufe von ir_isr() */

static uint16_t RC5data_tmp = 0; /*!< RC5-Bitstream */
static uint8_t RC5bitcount = 0; /*!< anzahl gelesener bits */

volatile uint16_t RC5data = 0; /*!< letztes komplett gelesenes RC5-paket */
volatile uint8_t enableRC5 = 0; /*!< schaltet die RC5 Abfrage ein/aus */

/*!
* Interrupt Serviceroutine
* wird alle 222.2us aufgerufen
*/
void IsrRC5 (void)
{
// sample lesen
uint8_t sample = 1;

if ((IR_PINR & (1<<IR_PIN)) != 0)
{
sample = 0;
}

// bittimer erhoehen (bleibt bei 255 stehen)
if (RC5bittimer<255)
{
RC5bittimer++;
}

// flankenerkennung
if ( RC5lastsample != sample)
{
if (RC5bittimer<=IR_SAMPLES_PER_BIT_MIN)
{
// flanke kommt zu frueh: paket verwerfen
RC5bitcount=0;
}
else
{
// Startbit
if (RC5bitcount==0)
{
if ( (sample==1) && (RC5bittimer>IR_PAUSE_SAMPLES) )
{
// Startbit speichern
RC5data_tmp = 1;
RC5bitcount++;
}
else
{
// error
RC5data_tmp = 0;
}

// bittimer-reset
RC5bittimer = 0;

// Bits 2..14: nur Flanken innerhalb des Bits beruecksichtigen
}
else
{
if (RC5bittimer >= IR_SAMPLES_PER_BIT_EARLY)
{
if (RC5bittimer<=IR_SAMPLES_PER_BIT_LATE)
{
// Bit speichern
RC5data_tmp = (RC5data_tmp<<1) | sample;
RC5bitcount++;
}
else
{
// zu spaet: paket verwerfen
RC5bitcount = 0;
}

// bittimer-reset
RC5bittimer = 0;
}
}
}

}
else
{
// keine flanke innerhalb bitzeit?
if (RC5bittimer > IR_SAMPLES_PER_BIT_LATE)
{
// 14 bits gelesen?
if (RC5bitcount==14)
{
RC5data = RC5data_tmp;
}
// paket verwerfen
RC5bitcount = 0;
}
}

// sample im samplepuffer ablegen
RC5lastsample = sample;


}


/*!
* IR-Daten lesen
* @return wert von ir_data, loescht anschliessend ir_data
*/
uint16_t ReadRC5 (void)
{
uint16_t retvalue = RC5data;
RC5data = 0;

return retvalue;
}

/*!
* Init IR-System
*/
void InitRC5 (void)
{
IR_DDR &= ~IR_PIN; // Pin auf Input
IR_PORT |= IR_PIN; // Pullup an
enableRC5 = 1;


}

//Habe eine main Methode hinzugefügt
int main(void)
{

DDRB=0xFF; // Port B auf Ausgang
PORTB=0xFF; // Alle Ausgänge auf 1
InitRC5();
static unsigned int cmd;

while(1)
{
cmd = ReadRC5();

switch(cmd)
{
//Wenn die 2 auf der Fenbedienung gedrückt ist, soll die erste LED auf dem Board aufleuchten
case TWO:
PORTB=~1;
break;
default:
PORTB=~32;
break;
}//ende switch


}//ende while

}


Meine Veränderungen beziehen sich auf die folgenden Codestellen:

Definieren des Ports A als Eingang für die RC5 Signale:




//Meine Anpassungen an PORT A
#define IR_PORT PORTA /*!< Port A */
#define IR_DDR DDRA /*!< DDR of Port A */
#define IR_PINR PINA /*!< Port A input */
#define IR_PIN PA7 /*!< Pin 7 */



-definieren des RC5 Signals für die Taste2 als Konstante



#define TWO 0x1002


-Einfügen der main-Methode


int main(void)
{

DDRB=0xFF; // Port B auf Ausgang
PORTB=0xFF; // Alle Ausgänge auf 1
InitRC5();
static unsigned int cmd;

while(1)
{
cmd = ReadRC5();

switch(cmd)
{
//Wenn die 2 auf der Fenbedienung gedrückt ist, soll die erste LED auf dem Board aufleuchten
case TWO:
PORTB=~1;
break;
default:
PORTB=~32;
break;
}//ende switch


}//ende while

}


Da der PORT B mit den LEDs verbunden ist , müssen diese über PORT B
angesteuert werden. Das Signal von der Fernbedieunung kommt ja über PORT A. An dieser stelle möchte ich das Lämpchen 1 aufleuchten lassen wenn das Signal für die 2 auf der Ferbedienung hereinkommt:



switch(cmd)
{
//Wenn die 2 auf der Fenbedienung gedrückt ist, soll die erste LED auf dem Board aufleuchten
case TWO:
PORTB=~1;
break;
default:
PORTB=~32;
break;
}//ende switch


Stattdessen leuchtet immer das Lämpchen 5 auf, also der Defaultwert.
Also es kommt anscheinend nicht das Signal für die 2 an.
Ich komme an dieser Stelle nicht weiter. Bin froh über jeden Tipp.

Gruß

Hubert.G
24.04.2007, 11:00
Schau dir mal diesen Code an, ich habe ihn auf einem Mega8 laufen und weis aber nicht ob er für einen 8515 auch geht. Du musst nur noch die Ports definierten dann leuchten auch die LEDs auf.

Hubert.G
24.04.2007, 11:04
Das war nur ein Teil, jetzt das ganze nocheinmal.

STK500begin
24.04.2007, 21:41
Danke, werde den Code von dir ausprobieren.

Gruß

Hubert.G
24.04.2007, 22:18
Der Code ist übrigens nicht von mir sondern, wie es auch im Header steht, von Peter Dannegger danni@specs.de .
Das nur der Ordnung halber.
Hubert

STK500begin
25.04.2007, 00:52
Hi,

ich möchte deine Gutmütigkeit nicht ausnützen, als Anfänger hätte ich aber noch paar Fragen:

- Für den "Betrieb" benötigt man doch nur Main.c und Main.h, da der Code aus RC5.c in Main.c schon enthalten ist ?!
-Die Header in Main.h muß man von


#include <io.h>
#include <interrupt.h>
#include <signal.h>
#include <stdlib.h>


nach



#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <stdlib.h>


ändern?!

-An der Stelle muß ich doch auch Werte setzen und warum sind diese Variablen nirgends deklariert ? :


UBRRL = bauddivider; //set baud rate
UBRRH = bauddivider >> 8;
UCSRA = 0; //no U2X, MPCM
UCSRC = 1<<URSEL^1<<UCSZ1^1<<UCSZ0; //8 Bit
UCSRB = 1<<RXEN^1<<TXEN; //enable RX, TX


Wenn du Zeit hast würde ich mich über eine Antwort freuen. Ich will dich weder ausnützen noch bin ich zu faul selber zu suchen. Trotz langer Suche sind meine Fortschritte sehr langsam, deshalb frage ich.

Hubert.G
25.04.2007, 13:44
Das rc5.c brauchst du schon, da ist die ISR-Routine drinnen.
Die Header Änderung ist OK, der Code ist mit einem älteren GCC geschrieben worden.
Das sind keine Variablen sondern Register des UART. Das war das was ich gemeint habe mit dem ob es für den 8515 auch geht, da dieser sicher andere Registerbezeichnungen hat.
Hubert

STK500begin
25.04.2007, 14:44
Danke für die Informationen, die bringen mich auf alle Fälle weiter.

Gruß