(Kategorie) |
|||
| Zeile 1: | Zeile 1: | ||
Dieser Artikel befindet sich möglichrweise im Aufbau. Siehe [[Diskussion:Codesammlung_avr-gcc]] | Dieser Artikel befindet sich möglichrweise im Aufbau. Siehe [[Diskussion:Codesammlung_avr-gcc]] | ||
| + | |||
| + | =IR-Empang= | ||
| + | ==RC5 Decoder für AVR Mega== | ||
| + | ===Beschreibung=== | ||
| + | ====Resourcen==== | ||
| + | {| {{Blauetabelle}} | ||
| + | |'''Resource''' | ||
| + | |'''Verbrauch (mit <code>-Os</code>)''' | ||
| + | |- | ||
| + | |I/O | ||
| + | |Timer0, 1 Pin für extern INT | ||
| + | |- | ||
| + | |Interrupts | ||
| + | |Timer0 Overflow, 1 externer IRQ | ||
| + | |- | ||
| + | |Flash | ||
| + | | ~ 0x180 | ||
| + | |- | ||
| + | |SRAM | ||
| + | | statisch: 8<br>Stack: 0x15 | ||
| + | |- | ||
| + | |Laufzeit | ||
| + | | ? | ||
| + | |} | ||
| + | |||
| + | ====Interface==== | ||
| + | <pre> | ||
| + | #define RC5_INT0 0 | ||
| + | #define RC5_INT1 1 | ||
| + | |||
| + | #define RC5_ALL 0xff | ||
| + | |||
| + | typedef struct | ||
| + | { | ||
| + | uint8_t code; | ||
| + | uint8_t addr; | ||
| + | volatile char flip; | ||
| + | } rc5_t; | ||
| + | |||
| + | extern rc5_t rc5; | ||
| + | extern void rc5_init (uint8_t addr); | ||
| + | </pre> | ||
| + | |||
| + | ;<code>void rc5_init (uint8_t addr)</code>: Initialisiert die Hardware für RC5-Empfang. Akzeptiert wird Code, der an Adresse <code>addr</code> geschickt wird. Falls <code>addr = RC5_ALL</code> bzw Bit 7 von <code>addr</code> gesetzt ist, werden alle Adressen akzeptiert. | ||
| + | ;<code>extern rc5_t rc5</code>: In <code>rc5</code> wird der empangene RC5-Code geliefert. | ||
| + | :;<code>rc5.code</code>: der empfangene RC5-Code, falls <code>rc5.flip != -1</code> | ||
| + | :;<code>rc5.addr</code>: die Adresse, an die gesendet wurde, falls <code>rc5.flip != -1</code> | ||
| + | :;<code>rc5.flip</code>: das Flip-Bit | ||
| + | ::;<code>rc5.flip = 0</code>: Flip-Bit ist 0, RC5-Empfang inaktiv | ||
| + | ::;<code>rc5.flip = 1</code>: Flip-Bit ist 1, RC5-Empfang inaktiv | ||
| + | ::;<code>rc5.flip = -1</code>: RC5-Empfang aktiv, wartet auf nächste Übertragung | ||
| + | |||
| + | {| {{Blauetabelle}} | ||
| + | |'''Define''' | ||
| + | |'''default''' | ||
| + | |'''Werte''' | ||
| + | |'''Beschreibung''' | ||
| + | |- | ||
| + | |<code>RC5_INT</code> | ||
| + | |<code>RC5_INT0</code> | ||
| + | |<code>RC5_INT0</code>, <code>RC5_INT1</code> | ||
| + | |Code wird generiert für INT0 resp. INT1, zB gcc-Aufruf mit <code>-DRC5_INT=RC5_INT1</code> erzeugt Code für INT1 | ||
| + | |- | ||
| + | |<code>RC5_PRESCALE</code> | ||
| + | |<code>1024</code> | ||
| + | |<code>64, 256, 1024</code> | ||
| + | |Legt den Prescaler für Timer0 fest. Standardeinstellung auf 1024, was zu F_CPU=16000000 passt. Für kleinere CPU-Frequenzen muss evtl ein kleinerer PRESCALE gewählt werden; das geht noch nicht automatisch. | ||
| + | |- | ||
| + | |<code>F_CPU</code> | ||
| + | | | ||
| + | | | ||
| + | |Gibt die CPU-Frequenz in Hz an | ||
| + | |} | ||
| + | |||
| + | ===Code=== | ||
| + | |||
| + | ====rc5.c==== | ||
| + | |||
| + | <pre> | ||
| + | #include <avr/io.h> | ||
| + | #include <avr/signal.h> | ||
| + | |||
| + | #include "rc5.h" | ||
| + | |||
| + | #ifndef RC5_INT | ||
| + | #define RC5_INT RC5_INT0 | ||
| + | #endif // RC5_INT | ||
| + | |||
| + | #ifndef RC5_PRESCALE | ||
| + | #define RC5_PRESCALE 1024 | ||
| + | #endif // RC5_PRESCALE | ||
| + | |||
| + | ////////////////////////////////////////////////////////////////////////////// | ||
| + | |||
| + | rc5_t rc5; | ||
| + | |||
| + | ////////////////////////////////////////////////////////////////////////////// | ||
| + | |||
| + | // µ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]; | ||
| + | |||
| + | struct | ||
| + | { | ||
| + | unsigned code:6; | ||
| + | unsigned addr:5; | ||
| + | unsigned flip:1; | ||
| + | unsigned agc:4; | ||
| + | } __attribute__ ((packed)); | ||
| + | |||
| + | } code_t; | ||
| + | |||
| + | static code_t code; | ||
| + | static uint8_t rc5_addr; | ||
| + | |||
| + | // Number of Bits received so far | ||
| + | // Number of Interrupts occured so far; | ||
| + | #ifndef RC5_DEBUG | ||
| + | static uint8_t nbits; | ||
| + | static uint8_t nint; | ||
| + | #else | ||
| + | uint8_t nbits; | ||
| + | uint8_t nint; | ||
| + | uint16_t * const prc5_code = &code.w; | ||
| + | #endif // !RC5_DEBUG | ||
| + | |||
| + | ////////////////////////////////////////////////////////////////////////////// | ||
| + | |||
| + | 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 |= (1 << ISC01); | ||
| + | MCUCR &= ~ (1 << ISC00); | ||
| + | GIFR = (1 << INTF0); | ||
| + | GICR |= (1 << INT0); | ||
| + | #elif (RC5_INT == RC5_INT1) | ||
| + | MCUCR |= (1 << ISC11); | ||
| + | MCUCR &= ~ (1 << ISC10); | ||
| + | GIFR = (1 << INTF1); | ||
| + | GICR |= (1 << INT1); | ||
| + | #else | ||
| + | #error please define RC5_INT | ||
| + | #endif // RC5_INT | ||
| + | } | ||
| + | |||
| + | ////////////////////////////////////////////////////////////////////////////// | ||
| + | |||
| + | SIGNAL (SIG_OVERFLOW0) | ||
| + | { | ||
| + | TIMSK &= ~(1 << TOIE0); | ||
| + | |||
| + | uint8_t _nbits = nbits; | ||
| + | code_t _code = code; | ||
| + | |||
| + | if (26 == _nbits) | ||
| + | { | ||
| + | _nbits++; | ||
| + | _code.w <<= 1; | ||
| + | } | ||
| + | |||
| + | if (27 == _nbits | ||
| + | && 3 == _code.agc | ||
| + | && 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; | ||
| + | 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 |= (1 << ISC01); | ||
| + | MCUCR &= ~ (1 << ISC00); | ||
| + | GIFR = (1 << INTF0); | ||
| + | GICR |= (1 << INT0); | ||
| + | #elif (RC5_INT == RC5_INT1) | ||
| + | MCUCR |= (1 << ISC11); | ||
| + | MCUCR &= ~ (1 << ISC10); | ||
| + | GIFR = (1 << INTF1); | ||
| + | GICR |= (1 << INT1); | ||
| + | #endif | ||
| + | } | ||
| + | |||
| + | ////////////////////////////////////////////////////////////////////////////// | ||
| + | |||
| + | #if (RC5_INT == RC5_INT0) | ||
| + | SIGNAL (SIG_INTERRUPT0) | ||
| + | #elif (RC5_INT == RC5_INT1) | ||
| + | SIGNAL (SIG_INTERRUPT1) | ||
| + | #endif // RC5_INT | ||
| + | { | ||
| + | code_t _code = code; | ||
| + | uint8_t _nint = nint; | ||
| + | |||
| + | if (0 == _nint) | ||
| + | { | ||
| + | // INTx on both edges | ||
| + | // clear pending INTx | ||
| + | #if (RC5_INT == RC5_INT0) | ||
| + | MCUCR &= ~ (1 << ISC01); | ||
| + | MCUCR |= (1 << ISC00); | ||
| + | GIFR = (1 << INTF0); | ||
| + | #elif (RC5_INT == RC5_INT1) | ||
| + | MCUCR &= ~ (1 << ISC11); | ||
| + | MCUCR |= (1 << ISC10); | ||
| + | GIFR = (1 << INTF1); | ||
| + | #endif // RC5_INT | ||
| + | |||
| + | TCNT0 = 0; | ||
| + | TIFR = (1 << TOV0); | ||
| + | TIMSK |= (1 << TOIE0); | ||
| + | _code.w = 0; | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | uint8_t tcnt0 = TCNT0; | ||
| + | |||
| + | TCNT0 = 0; | ||
| + | |||
| + | // 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; | ||
| + | } | ||
| + | </pre> | ||
| + | |||
| + | ====rc5.h==== | ||
| + | <pre> | ||
| + | #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 char flip; | ||
| + | } rc5_t; | ||
| + | |||
| + | extern rc5_t rc5; | ||
| + | extern void rc5_init (uint8_t addr); | ||
| + | |||
| + | #ifdef RC5_DEBUG | ||
| + | extern uint16_t * const prc5_code; | ||
| + | extern uint8_t nbits; | ||
| + | extern uint8_t nint; | ||
| + | #endif // RC5_DEBUG | ||
| + | |||
| + | #endif /* _RC5_H_ */ | ||
| + | </pre> | ||
| + | |||
| + | ====Beispiele==== | ||
| + | |||
| + | '''<code>Beispiel: Anwendung</code>''' | ||
| + | <pre> | ||
| + | #include <avr/io.h> | ||
| + | #include <avr/interrupt.h> | ||
| + | |||
| + | #include "rc5.h" | ||
| + | |||
| + | ... | ||
| + | // Code atomar machen | ||
| + | uint8_t sreg = SREG; | ||
| + | cli(); | ||
| + | // Gibt's was Neues? | ||
| + | if (-1 == rc5.flip) | ||
| + | { | ||
| + | // Nein, dann zurück | ||
| + | SREG = sreg; | ||
| + | return; | ||
| + | } | ||
| + | // Ja, dann code merken | ||
| + | uint8_t code = rc5.code; | ||
| + | // und auf nächstes Zeichen warten | ||
| + | rc5.flip = -1; | ||
| + | SREG = sreg; | ||
| + | ... | ||
| + | </pre> | ||
| + | |||
| + | '''<code>Beispiel: Initialisierung</code>''' | ||
| + | <pre> | ||
| + | #include <avr/io.h> | ||
| + | #include <avr/interrupt.h> | ||
| + | |||
| + | #include "rc5.h" | ||
| + | |||
| + | ... | ||
| + | // RC5 initialisieren, alle Adressen zulassen | ||
| + | rc5_init (RC5_ALL); | ||
| + | |||
| + | // Interrupts zulassen | ||
| + | sei(); | ||
| + | ... | ||
| + | </pre> | ||
[[Kategorie:Software]] | [[Kategorie:Software]] | ||
Version vom 3. Dezember 2005, 15:38 Uhr
Dieser Artikel befindet sich möglichrweise im Aufbau. Siehe Diskussion:Codesammlung_avr-gcc
Inhaltsverzeichnis
IR-Empang
RC5 Decoder für AVR Mega
Beschreibung
Resourcen
| Resource | Verbrauch (mit -Os)
|
| I/O | Timer0, 1 Pin für extern INT |
| Interrupts | Timer0 Overflow, 1 externer IRQ |
| Flash | ~ 0x180 |
| SRAM | statisch: 8 Stack: 0x15 |
| Laufzeit | ? |
Interface
#define RC5_INT0 0
#define RC5_INT1 1
#define RC5_ALL 0xff
typedef struct
{
uint8_t code;
uint8_t addr;
volatile char flip;
} rc5_t;
extern rc5_t rc5;
extern void rc5_init (uint8_t addr);
void rc5_init (uint8_t addr)- Initialisiert die Hardware für RC5-Empfang. Akzeptiert wird Code, der an Adresse
addrgeschickt wird. Fallsaddr = RC5_ALLbzw Bit 7 vonaddrgesetzt ist, werden alle Adressen akzeptiert. extern rc5_t rc5- In
rc5wird der empangene RC5-Code geliefert.rc5.code- der empfangene RC5-Code, falls
rc5.flip != -1 rc5.addr- die Adresse, an die gesendet wurde, falls
rc5.flip != -1 rc5.flip- das Flip-Bit
rc5.flip = 0- Flip-Bit ist 0, RC5-Empfang inaktiv
rc5.flip = 1- Flip-Bit ist 1, RC5-Empfang inaktiv
rc5.flip = -1- RC5-Empfang aktiv, wartet auf nächste Übertragung
| Define | default | Werte | Beschreibung |
RC5_INT
|
RC5_INT0
|
RC5_INT0, RC5_INT1
|
Code wird generiert für INT0 resp. INT1, zB gcc-Aufruf mit -DRC5_INT=RC5_INT1 erzeugt Code für INT1
|
RC5_PRESCALE
|
1024
|
64, 256, 1024
|
Legt den Prescaler für Timer0 fest. Standardeinstellung auf 1024, was zu F_CPU=16000000 passt. Für kleinere CPU-Frequenzen muss evtl ein kleinerer PRESCALE gewählt werden; das geht noch nicht automatisch. |
F_CPU
|
Gibt die CPU-Frequenz in Hz an |
Code
rc5.c
#include <avr/io.h>
#include <avr/signal.h>
#include "rc5.h"
#ifndef RC5_INT
#define RC5_INT RC5_INT0
#endif // RC5_INT
#ifndef RC5_PRESCALE
#define RC5_PRESCALE 1024
#endif // RC5_PRESCALE
//////////////////////////////////////////////////////////////////////////////
rc5_t rc5;
//////////////////////////////////////////////////////////////////////////////
// µ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];
struct
{
unsigned code:6;
unsigned addr:5;
unsigned flip:1;
unsigned agc:4;
} __attribute__ ((packed));
} code_t;
static code_t code;
static uint8_t rc5_addr;
// Number of Bits received so far
// Number of Interrupts occured so far;
#ifndef RC5_DEBUG
static uint8_t nbits;
static uint8_t nint;
#else
uint8_t nbits;
uint8_t nint;
uint16_t * const prc5_code = &code.w;
#endif // !RC5_DEBUG
//////////////////////////////////////////////////////////////////////////////
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 |= (1 << ISC01);
MCUCR &= ~ (1 << ISC00);
GIFR = (1 << INTF0);
GICR |= (1 << INT0);
#elif (RC5_INT == RC5_INT1)
MCUCR |= (1 << ISC11);
MCUCR &= ~ (1 << ISC10);
GIFR = (1 << INTF1);
GICR |= (1 << INT1);
#else
#error please define RC5_INT
#endif // RC5_INT
}
//////////////////////////////////////////////////////////////////////////////
SIGNAL (SIG_OVERFLOW0)
{
TIMSK &= ~(1 << TOIE0);
uint8_t _nbits = nbits;
code_t _code = code;
if (26 == _nbits)
{
_nbits++;
_code.w <<= 1;
}
if (27 == _nbits
&& 3 == _code.agc
&& 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;
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 |= (1 << ISC01);
MCUCR &= ~ (1 << ISC00);
GIFR = (1 << INTF0);
GICR |= (1 << INT0);
#elif (RC5_INT == RC5_INT1)
MCUCR |= (1 << ISC11);
MCUCR &= ~ (1 << ISC10);
GIFR = (1 << INTF1);
GICR |= (1 << INT1);
#endif
}
//////////////////////////////////////////////////////////////////////////////
#if (RC5_INT == RC5_INT0)
SIGNAL (SIG_INTERRUPT0)
#elif (RC5_INT == RC5_INT1)
SIGNAL (SIG_INTERRUPT1)
#endif // RC5_INT
{
code_t _code = code;
uint8_t _nint = nint;
if (0 == _nint)
{
// INTx on both edges
// clear pending INTx
#if (RC5_INT == RC5_INT0)
MCUCR &= ~ (1 << ISC01);
MCUCR |= (1 << ISC00);
GIFR = (1 << INTF0);
#elif (RC5_INT == RC5_INT1)
MCUCR &= ~ (1 << ISC11);
MCUCR |= (1 << ISC10);
GIFR = (1 << INTF1);
#endif // RC5_INT
TCNT0 = 0;
TIFR = (1 << TOV0);
TIMSK |= (1 << TOIE0);
_code.w = 0;
}
else
{
uint8_t tcnt0 = TCNT0;
TCNT0 = 0;
// 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;
}
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 char flip;
} rc5_t;
extern rc5_t rc5;
extern void rc5_init (uint8_t addr);
#ifdef RC5_DEBUG
extern uint16_t * const prc5_code;
extern uint8_t nbits;
extern uint8_t nint;
#endif // RC5_DEBUG
#endif /* _RC5_H_ */
Beispiele
Beispiel: Anwendung
#include <avr/io.h>
#include <avr/interrupt.h>
#include "rc5.h"
...
// Code atomar machen
uint8_t sreg = SREG;
cli();
// Gibt's was Neues?
if (-1 == rc5.flip)
{
// Nein, dann zurück
SREG = sreg;
return;
}
// Ja, dann code merken
uint8_t code = rc5.code;
// und auf nächstes Zeichen warten
rc5.flip = -1;
SREG = sreg;
...
Beispiel: Initialisierung
#include <avr/io.h> #include <avr/interrupt.h> #include "rc5.h" ... // RC5 initialisieren, alle Adressen zulassen rc5_init (RC5_ALL); // Interrupts zulassen sei(); ...