/***************************************************** This program was produced by the CodeWizardAVR V1.24.2 Standard Automatic Program Generator © Copyright 1998-2004 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.ro e-mail:office@hpinfotech.ro Project : Version : Date : 9/23/2004 Author : Theodore Johnson Company : NY, USA Comments: Chip type : ATmega8 Program type : Application Clock frequency : 8.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *****************************************************/ #include // Standard Input/Output functions #include #include #define IRIN PINC.1 // IR reader using timer 0. #define IR_DETECT_LED PORTB.0 #define IR_MSG_LED PORTD.7 // out-of-band processing #define MOTOR_RELAY PORTB.1 #define IRSTART 1 #define IRINIT 2 #define IRDIG0 3 #define IRDIGLO 4 #define IRDIGHI 5 #define IRbytes 6 unsigned char IRstate = IRSTART; // state machine unsigned char IRcnt = 0; // time in state char IRresult[IRbytes]; // store result unsigned char IRbit; // next bit position. // Output vars char IRvalue[IRbytes]; // output value unsigned char IRlen; // # bits in output. unsigned char IRnew = 0; // signal a new output. char irerr = 0; char err_cnt = 0; // 8 us per clock tick // Params for General Instruments INRC-42 #define SAMPLE_RATE 231 // (256-231)*8us = .20 ms per interrupt. // Units are # of interrupts. // min, max length of initial zero pulse #define MIN_IR_START_LO 20 #define MAX_IR_START_LO 30 // min, max length of subsequent 1 pulse #define MIN_IR_START_HI 7 #define MAX_IR_START_HI 15 // Max len of inter-digit zero pulse #define MAX_IR_LOW_DIG 10 // min, threshold, and max length of 1 pulse // (if larger than max, transmission is complete). #define MIN_IR_DIGHI 1 #define IR_DETECT0_CNT 8 #define MAX_IR_DIGHI 20 interrupt [TIM0_OVF] void timer0_ovf_isr(void){ char IRval; char bitpos, bytepos; IRval = IRIN; switch(IRstate){ case IRSTART: // nothing happening. IRcnt = 0; if(!IRval) IRstate = IRINIT; break; case IRINIT: // try to detect initial 0 pulse IRcnt++; if(IRval){ if(IRcnt >= MIN_IR_START_LO){ IRstate = IRDIG0; }else{ IRstate = IRSTART; irerr = 1; err_cnt = IRcnt; } IRcnt = 0; }else{ if(IRcnt > MAX_IR_START_LO){ IRcnt = 0; IRstate = IRSTART; irerr = 2; err_cnt = IRcnt; } } break; case IRDIG0: // initial zero detected, look for initial 1. IRcnt++; if(!IRval){ if(IRcnt MAX_IR_START_HI){ IRcnt = 0; IRstate = IRSTART; irerr = 4; err_cnt = IRcnt; } } break; case IRDIGLO: IRcnt++; if(IRval){ IRcnt = 0; IRstate = IRDIGHI; }else{ if(IRcnt > MAX_IR_LOW_DIG){ IRcnt = 0; IRstate = IRSTART; irerr = 5; err_cnt = IRcnt; IRlen = IRbit; } } break; case IRDIGHI: IRcnt++; if(! IRval){ if(IRcnt >= MIN_IR_DIGHI && IRcnt <= IR_DETECT0_CNT){ IRbit++; IRstate = IRDIGLO; } else if(IRcnt > IR_DETECT0_CNT && IRcnt <= MAX_IR_DIGHI){ bitpos = IRbit & 0x07; bytepos = IRbit >> 3; IRresult[bytepos] |= (1 << bitpos); IRbit++; IRstate = IRDIGLO; } else{ IRstate = IRSTART; irerr = 6; err_cnt = IRcnt; IRlen = IRbit; } IRcnt = 0; // Out of space : end detection. if(IRbit > 8*IRbytes){ if(! IRnew){ IRnew = 1; for(bytepos=0;bytepos= MAX_IR_DIGHI){ if(! IRnew){ IRnew = 1; for(bytepos=0;bytepos