#include #include #include #include #include //#include // Berechnungen für F_CPU == 16e6! #define RC5TIME 1.778e-3 // 1.778msec #define PULSE_MIN (uint8_t)(F_CPU / 2048 * RC5TIME * 0.4 +0.5) #define PULSE_1_2 (uint8_t)(F_CPU / 2048 * RC5TIME * 0.8 +0.5) #define PULSE_MAX (uint8_t)(F_CPU / 2048 * RC5TIME * 1.2 +0.5) #define IR_IN PINB // Input Port #define IR_PIN PB0 // Input Pin #define SECTIME (uint16_t)(F_CPU / 2048 * 3) // 3 Sekunden #define LEDTIME (uint16_t)(F_CPU / 2048 / 1000 * 50) // 50 msec uint8_t rc5Bit; // bit value uint8_t rc5Time; // Count Bit Time uint16_t rc5Tmp; // Shift Bits in volatile uint16_t rc5Data; // store result uint16_t codes[15] EEMEM; // Codes im EEPROM uint8_t sicherung; // Sicherungen für die ersten 4 Ausgänge uint16_t seccounter; // Zählt TimerInterrupts für Sicherungen void startAnimation(); void learnMode(uint8_t); void normalMode(); void rc5(); void led(uint8_t); // Timer Interrupt ISR(TIMER0_OVF_vect){ led(0); if(sicherung){ // Sicherung gesetzt? seccounter++; if(seccounter == SECTIME){ // Limit erreicht? sicherung = 0; seccounter = 0; } } rc5(); } // Main Programm int main(){ // Init Stuff DDRD = 0xE3; PORTB = 0x1E; DDRC = 0x3F; startAnimation(); // Set Timer settings TCCR0 = (1 << CS02) | (1 << CS00); TIMSK = 1 << TOIE0; // What mode? if(MCUCSR & (1 << 1)){ // Externel Reset? // Ok, check whether or not dips are set uint8_t dip = 0; dip = PINB; dip >>= 1; dip = ~dip; dip &= 0xF; if(dip != 0){ // Learn! learnMode(dip); } else{ // Normal mode normalMode(); } } else{ // Normal mode normalMode(); } return 0; } // Run trough Leds void startAnimation(){ PORTD |= 1 << 7; _delay_ms(50); PORTD &= ~(1 << 7); PORTD |= 1 << 6; _delay_ms(50); PORTD &= ~(1 << 6); PORTD |= 1 << 5; _delay_ms(50); PORTD &= ~(1 << 5); } // Switching Leds on and automatic off void led(uint8_t l){ static uint16_t counter; switch(l){ case 5: PORTD |= 1 << 5; counter = 0; break; case 6: PORTD |= 1 << 6; counter = 0; break; case 7: PORTD |= 1 << 7; counter = 0; break; default: if(PORTD & ((1 << 5) | (1 << 6) | (1 << 7))){ counter++; if(counter == LEDTIME){ PORTD &= ~((1 << 5) | (1 << 6) | (1 << 7)); counter = 0; } } } } // Learn Mode // Waiting vor IR-signal and save it // or delete all void learnMode(uint8_t dip){ uint16_t data; PORTD |= 1 << 7; // turn red led on if(dip == 15) // Delete all codes { for(uint8_t i = 0; i<15; i++) eeprom_write_word(&codes[i], 0); } else { sei(); for(;;) { cli(); data = rc5Data; rc5Data = 0; sei(); if(data) break; } eeprom_write_word(&codes[dip], data); eeprom_busy_wait(); } PORTD &= ~(1 << 7); // turn red led off PORTD |= 1 << 6; // turn green led on for(;;); } // Normal Mode // Waiting vor IR-signal and process it void normalMode(){ uint16_t codearray[15]; uint16_t data = 0; uint8_t number = 0; eeprom_read_block(codearray, codes, sizeof(uint16_t)*15); sei(); for(;;){ number = 0; cli(); data = rc5Data; rc5Data = 0; sei(); if(data){ for(uint8_t i=0; i<15; i++){ // Get Codenumber if(codearray[i] == data){ number = i; break; } } if(number == 0) continue; // Kein bekannter Code led(5); // Switch receiver Led on if(number > 8){ // Steuercodes sicherung = 1 << (number - 9); seccounter = 0; } else{ // Ausgang schalten switch(number){ case 1: PORTC |= 1 << 5; _delay_ms(10); break; case 2: PORTC |= 1 << 4; _delay_ms(10); break; case 3: PORTC |= 1 << 3; _delay_ms(10); break; case 4: PORTC |= 1 << 2; _delay_ms(10); break; default: led(7); // Switch red led on } } } } } // // Finding RC5 Code void rc5(){ uint16_t tmp = rc5Tmp; // for faster access TCNT0 = -2; // 2 * 256 = 512 cycle if( ++rc5Time > PULSE_MAX ){ // count pulse time if( !(tmp & 0x4000) && tmp & 0x2000 ) rc5Data = tmp; // only if 14 bits received tmp = 0; } if( (rc5Bit ^ IR_IN) & 1 << IR_PIN ){ // change detect rc5Bit = ~rc5Bit; // 0x00 -> 0xFF -> 0x00 if( rc5Time < PULSE_MIN ) tmp = 0; // to short if( !tmp || rc5Time > PULSE_1_2 ){ // start or long pulse time if( !(tmp & 0x4000) ) tmp <<= 1; // not to many bits if( !(rc5Bit & 1 << IR_PIN) ) tmp |= 1; rc5Time = 0; // count next pulse time } } rc5Tmp = tmp; }