Code:
// nibobee mit RC5 steuern 17.1.01 mic
// RC5-Funktion aus: https://www.roboternetz.de/phpBB2/ze...=287750#287750
#define ddr_acs_led_l DDRA // Anoden der IR-LEDs links
#define port_acs_led_l PORTA
#define pin_acs_led_l (1<<PA2)
#define ddr_acs_led_r DDRA // rechts
#define port_acs_led_r PORTA
#define pin_acs_led_r (1<<PA3)
#define ddr_acs_36kHz DDRC // Kathoden der IR-LEDS mit 36kHz getaktet
#define port_acs_36kHz PORTC
#define pin_acs_36kHz (1<<PC2)
#define ddr_acs_tsop DDRC // Eingang IR-Empfänger
#define port_acs_tsop PINC // Achtung, das ist ein Eingang!
#define pin_acs_tsop (1<<PC3)
#include <nibobee/iodefs.h>
#include <nibobee/led.h>
volatile uint8_t count36kHz;
volatile uint8_t acs=0;
void Sleep(uint8_t pause);
void Msleep(uint16_t pause);
void ACSData(uint16_t *data);
void ACS_init(void);
int main(void)
{
//uint16_t data[2]; // Speicher für ACS-Werte
led_init();
ACS_init();
led_set(0,1);
Msleep(2000); // wait4programmer
led_set(0,0);
//port_acs_led_l |= pin_acs_led_l;
//while(1);
unsigned int count, temp; // Zaehler, IR-Kommando
unsigned char daten[14], ir_status; // IR-Datenspeicher, IR-Eingangspegel
while(1)
{
temp=0;
while (port_acs_tsop & pin_acs_tsop); //warten auf die Flanke des Startbits
led_set(2,1); // Alarmstufe ROT: ein Zeichen ist im Anflug
led_set(0,0);
for (count=0; count<14; count++) { // im Gesamten warten wir auf 14 RC5-Bits
// Die RC5-Bitlaenge beträgt 1,778 ms. Bei 36 Takten pro Millisekunde ergibt das 36*1,778 = 64
Sleep(48); // Information einlesen nach 3/4 der Bitlaenge
ir_status=(port_acs_tsop & pin_acs_tsop); // Pegel Speichern
if (ir_status) daten[count]='1'; else daten[count]='0'; // und merken
if (ir_status) temp |= (1 << (13-count)); // das MSB(=mostsuefikantbit) zuerst
while (ir_status == (port_acs_tsop & pin_acs_tsop)); // Bit gelesen, warten auf naechste Flanke
}
temp=temp/2 & 0xf; // Die Info steht in den Bits 1-4
led_set(2,0); // Daten gelesen
/*
#define pow1 150 // Langsame Geschwindigkeit
#define pow2 200 // Schnelle Geschwindigkeit
switch (temp) {
case 1: MotorDir(FWD,FWD); MotorSpeed(pow1,pow2); break;
case 2: MotorDir(FWD,FWD); MotorSpeed(pow2,pow2); break;
case 3: MotorDir(FWD,FWD); MotorSpeed(pow2,pow1); break;
case 4: MotorDir(BREAK,FWD); MotorSpeed(0,pow1); break;
case 5: MotorDir(BREAK,BREAK); MotorSpeed(0,0); break;
case 6: MotorDir(FWD,BREAK); MotorSpeed(pow1,0); break;
case 7: MotorDir(RWD,BREAK); MotorSpeed(pow1,0); break;
case 8: MotorDir(RWD,RWD); MotorSpeed(pow1,pow1); break;
case 9: MotorDir(BREAK,RWD); MotorSpeed(0,pow1); break;
default: MotorDir(BREAK,BREAK); MotorSpeed(0,0); break;
}
*/
while(temp--) // temp mal blinken
{
Msleep(500);
led_set(3,1);
Msleep(200);
led_set(3,0);
}
led_set(0,1);
}
return(0);
}
ISR (TIMER2_COMP_vect)
{
port_acs_36kHz ^= pin_acs_36kHz; // IR-LEDs togglen
}
// Frequenzkorrektur für 36kHz (512-416 plus 3 Takte fürs Laden von TCNT2?)
ISR (TIMER2_OVF_vect)
{
TCNT2 += 99; // += bewirkt, dass schon erfolgte Zähltakte nicht ignoriert werden!
port_acs_36kHz &= ~pin_acs_36kHz; // bei Nulldurchgang soll die IR-LED aus sein!
//port_acs_36kHz |= pin_acs_36kHz; // seltamerweise funktioniert das auch?
if(count36kHz) count36kHz--;
if(acs) acs--;
}
void Sleep(uint8_t pause) // 1/36000 Pause blockierend
{
count36kHz=pause;
while(count36kHz);
}
void Msleep(uint16_t pause) // 1/1000 Pause blockierend
{
while(pause--) Sleep(36);
}
void ACSData(uint16_t *data)
{
OCR2=253;
port_acs_led_l |= pin_acs_led_l; // ACS LED left on
while((port_acs_tsop & pin_acs_tsop) && (OCR2 > 151))
{
acs=8; // Impulse senden, acs wird in OVF-ISR runtergezählt
while(acs);
OCR2--;
}
port_acs_led_l &= ~pin_acs_led_l; // ACS LED left off
data[0]=OCR2;
while(!(port_acs_tsop & pin_acs_tsop)); // warten bis keine Echo mehr
OCR2=253;
port_acs_led_r |= pin_acs_led_r; // ACS LED right on
while((port_acs_tsop & pin_acs_tsop) && (OCR2 > 151))
{
acs=8;
while(acs);
OCR2--;
}
port_acs_led_r &= ~pin_acs_led_r; // ACS LED right off
data[1]=OCR2;
while(!(port_acs_tsop & pin_acs_tsop));
}
void ACS_init(void)
{
// Setup Timer2
TCCR2 = (1 << WGM20)|(1 << CS20); // PhaseCorrect-PWM, no prescaling, no OC2-Pin!
TCNT2 = 96; // (512-416) 36kHz @15MHz
OCR2 = 151; // (255-(208/2)) 151 ist 50:50 Compare Match für symetrische Halbwellen
TIMSK |= (1 << OCIE2)|(1 << TOIE2); // Comp und OVF-ISR enable, Overflow bei Bottum!
enable_interrupts();
ddr_acs_led_l |= pin_acs_led_l; // die Anoden der IR-LEDs
port_acs_led_l &= ~pin_acs_led_l;
ddr_acs_led_r |= pin_acs_led_r;
port_acs_led_r &= ~pin_acs_led_r;
ddr_acs_36kHz |= pin_acs_36kHz; // die Kathoden der IR-LEDs
}
Das funktioniert dann so:
Lesezeichen