/***************************************************** This program was produced by the CodeWizardAVR V2.05.3 Standard Automatic Program Generator Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Управление освещением Version : 2.1 версия для 2313 Date : 07.01.2013 Author : MAXIOL Company : MAXIOL Comments: свободно для использования Chip type : ATtiny2313A AVR Core Clock frequency: 8.000000 MHz Memory model : Tiny External RAM size : 0 Data Stack size : 32 *****************************************************/ #include #include // максимальное время на рассчет при 8MHz - 100нс // Declare your global variables here bit begin_p; // флаг начала прихожей bit begin_k; // флаг начала коридора bit end_p; // флаг конца прихожей bit end_k; // флаг конца коридора bit lower_p; // флаг уменьшения яркости прихожей bit lower_k; // флаг уменьшения яркости коридора bit zav_k; // флаг зависимости коридора unsigned long max_p; // максимальная яркость прихожей в текущем режиме unsigned long max_k; // максимальная яркость кордидора в текущем режиме unsigned int timer_p; // счетчик таймера прихожей unsigned int timer_k; // счетчик таймера коридора unsigned int timer_akt_p; // счетчик таймера активности прихожей unsigned int timer_akt_k; // счетчик таймера активности коридора unsigned int step_p; // текущий шаг прихожей включение unsigned int step_k; // текущий шаг коридора включение unsigned int step_pe; // текущий шаг прихожей выключение unsigned int step_ke; // текущий шаг коридора выключение unsigned long tim_ocr_p; // текущее значение таймера для записи в шим прихожая *100 unsigned long tim_ocr_k; // текущее значение таймера для записи в шим коридор *100 unsigned char start_cycle; // переменная для цикла стартового таймаута //eeprom unsigned int flag_eerpom_good; // флаг корректности eeprom = 12345 - все ok eeprom unsigned int TP; // длительность горения света в прихожей в тиках. 1тик=10мс eeprom unsigned int TK; // длительность горения света в прихожей в тиках. 1тик=10мс eeprom unsigned int TBBP; // время выхода на рабочий режим в тиках. 1тик=10мс 1с=100тик / прихожая eeprom unsigned int TBBK; // время выхода на рабочий режим в тиках. 1тик=10мс / коридор eeprom unsigned int TBEP; // время выключения в тиках. 1тик=10мс / прихожая eeprom unsigned int TBEK; // время выключения в тиках. 1тик=10мс / коридор eeprom unsigned int LEV_P; // порог активности для выхода из ночного режима в тиках. 1тик=10мс / прихожая eeprom unsigned int LEV_K; // порог активности для выхода из ночного режима в тиках. 1тик=10мс / коридиор // яркости eeprom unsigned long day_p; // значение дня прихожей eeprom unsigned long day_k; // значение дня коридора eeprom unsigned long night_p; // значение ночи прихожей eeprom unsigned long night_k; // значение ночи коридора //eeprom unsigned char kmid; // коэффициент для вычисления яркости промежуточного режима относительного ночного // яркости в % #define L_day_p 100 // значение дня прихожей #define L_day_k 100 // значение дня коридора #define L_night_p 30 // значение ночи прихожей #define L_night_k 10 // значение ночи коридора // времена #define L_TP 90 // длительность горения света в прихожей в секундах #define L_TK 90 // длительность горения света в прихожей в секундах #define L_TBBP 3 // время выхода на рабочий режим в секундах / прихожая #define L_TBBK 3 // время выхода на рабочий режим секундах / коридор #define L_TBEP 50 // время выключения в секундах / прихожая #define L_TBEK 50 // время выключения в секундах / коридор #define L_LEV_P 50 // порог активности для выхода из ночного режима секундах / прихожая #define L_LEV_K 100 // порог активности для выхода из ночного режима секундах / коридиор // базовые константы аппаратного решения #define OCR_CLOCK 128 // реальная частота таймера в герцах #define MAX_LIGHT 1023 // максимальное значение шим-а // порты входных сигналов #define DAY PIND.4 // PIND.4 день/ночь ==0 ночь #define KOR PIND.3 // PIND.3 коридор ==1 активно (датчики нз на землю) #define PRI PIND.2 // PIND.2 прихожая ==1 активно (датчики нз на землю) #define DOR PINA.1 // PINA.1 дверь ==1 активно (датчики нз на землю) // порт выхода #define LED PORTD.6 // светодиод которым мигаем #define LED2 PORTD.0 // светодиод которым мигаем // таймеры #define OCR_PRI OCR1A #define OCR_KOR OCR1B void init_eerpom(void) // ф-я инициализации переменных в eeprom для первого пуска { //if (flag_eerpom_good!=12345) // { // яркости day_p=MAX_LIGHT*OCR_CLOCK*L_day_p/100; // значение дня прихожей day_k=MAX_LIGHT*OCR_CLOCK*L_day_k/100; // значение дня коридора night_p=MAX_LIGHT*OCR_CLOCK*L_night_p/100; // значение ночи прихожей night_k=MAX_LIGHT*OCR_CLOCK*L_night_k/100; // значение ночи коридора // kmid=2; // коэффициент для вычисления яркости промежуточного режима относительного ночного // времена TP=L_TP*OCR_CLOCK; // длительность горения света в прихожей в тиках. TK=L_TK*OCR_CLOCK; // длительность горения света в прихожей в тиках. TBBP=L_TBBP*OCR_CLOCK; // время выхода на рабочий режим в тиках. / прихожая TBBK=L_TBBK*OCR_CLOCK; // время выхода на рабочий режим в тиках. / коридор TBEP=L_TBEP*OCR_CLOCK; // время выключения в тиках. / прихожая TBEK=L_TBEK*OCR_CLOCK; // время выключения в тиках. / коридор LEV_P=L_LEV_P*OCR_CLOCK; // порог активности для выхода из ночного режима в тиках. / прихожая LEV_K=L_LEV_K*OCR_CLOCK; // порог активности для выхода из ночного режима в тиках. / коридиор // } } // прихожая void tim_write_p(void) // запись в таймер значения tim_ocr_p/OCR_CLOCK { //OCR_PRI=tim_ocr_p/OCR_CLOCK; OCR_PRI=tim_ocr_p>>7; // :128 } //коридор void tim_write_k(void) // запись в таймер значения tim_ocr_k/OCR_CLOCK { //OCR_KOR=tim_ocr_k/OCR_CLOCK; OCR_KOR=tim_ocr_k>>7; // :128 } void recalc_p(void) // ф-я пересчетов шагов и констант сравнения - прихожая { step_p=max_p/TBBP; // пересчет шага - включение прихожая step_pe=max_p/TBEP; //пересчет шага - выключение прихожая } void recalc_k(void) // ф-я пересчетов шагов и констант сравнения - коридор { step_k=max_k/TBBK; // пересчет шага - включение коридор step_ke=max_k/TBEK; // пересчет шага - выключение коридор } // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Reinitialize Timer 0 value //TCNT0=0xB1; // для~100Hz TCNT0=0x0B; // для ~128Hz // Place your code here LED=1; // мигаем светодиодом работы // опрос // установка флагов начала - проход есть только при первом пуске! if ((PRI==1 || DOR==1) && timer_p==0) // прихожая - реагируем и на дверь и на датчик движения { begin_p=1; end_p=0; // устанавливаем флаг начала и сбрасываем флаг конца асинхронно if (DAY==0 && PRI==1 ) // день/ночь {max_p=day_p; } else {max_p=night_p; } if (DOR==1 ) {max_p=day_p; } // на дверь - всегда дневной режим recalc_p(); // отработаем зависимость if (begin_k==0 && timer_k==0) // включим 50% от режима в коридоре если там все выключено {begin_k=1 ; end_k=0; timer_k=TK/2; zav_k=1; if (DAY==0) // день/ночь { max_k=day_k/2; } else { max_k=night_k/2; } recalc_k(); } } if ( (KOR==1 && timer_k==0) || (KOR==1 && zav_k==1)) // кордидор { begin_k=1 ; end_k=0; // устанавливаем флаг начала и сбрасываем флаг конца асинхронно zav_k=0; if (DAY==0) // день/ночь { max_k=day_k; } else { max_k=night_k; } // зависимость с корридора на прихожую не делаем recalc_k(); } // проход при любом нажатии if (DOR==1 || PRI==1 ) // или датчик в прихожей или дверь в прихожей { timer_p=TP; // взводим счетчик времени горения timer_akt_p++; // инкрементируем активность в прихожей if (DAY==1 && timer_akt_p>LEV_P) // ночь и таймер активности превышает порог { max_p=day_p; recalc_p(); } // активность выше порога } if (KOR==1) // кордидор { timer_k=TK; // взводим счетчик времени горения timer_akt_k++; // инкрементируем активность в коридоре if (DAY==1 && timer_akt_k>LEV_K) // ночь и таймер активности превышает порог {max_k=day_k; recalc_k(); } // активность выше порога } // отработка переключения день/ ночь при включеном свете // есть 2 ситуации - свет включен и происходит переход с дня на ночь и с ночи на день // алгоритм универсальный и рассчитан на любое увеличение-уменьшение if (begin_p==0 && end_p==0 && timer_p>0 && tim_ocr_p0 && tim_ocr_p>max_p ) // переход с дня на ночь { lower_p=1;} if (begin_k==0 && end_k==0 && timer_k>0 && tim_ocr_k0 && tim_ocr_k>max_k ) // переход с дня на ночь { lower_k=1;} // опрос закончен // включаем свет // прихожая // блок плавного включения if (timer_p>0 && begin_p==1 && tim_ocr_p0 && begin_p==1 && tim_ocr_p>=max_p ) // те это конец начала { begin_p=0; // сбрасываем флаг начала tim_ocr_p=max_p; tim_write_p(); } // исправляем ошибки вычислений // основной режим if (timer_p>0 && begin_p==0 && lower_p==0 ) { timer_p--; } // отслеживание конца if (timer_p==0 && tim_ocr_p>0 && end_p==0 ) // таймер кончился, начало конца {end_p=1; // флаг начала конца timer_akt_p=0; }// активность в ноль if ((tim_ocr_p==0 || tim_ocr_p-step_pe>max_p)&& end_p==1) // конец конца {end_p=0; tim_ocr_p=0; tim_write_p(); timer_akt_p=0;} if (tim_ocr_p>0 && end_p==1) // непосредственно отчет конца {tim_ocr_p-=step_pe; tim_write_p(); } // отслеживание уменьшения яркости if (lower_p==1) {tim_ocr_p=tim_ocr_p-step_pe; tim_write_p(); } if (lower_p==1 && tim_ocr_p>max_p ) // конец уменьшения {lower_p=0;} // коридор // блок плавного включения if (timer_k>0 && begin_k==1 && tim_ocr_k0 && begin_k==1 && tim_ocr_k>=max_k ) // те это конец начала { begin_k=0; tim_ocr_k=max_k; tim_write_k(); } // основной режим if (timer_k>0 && begin_k==0 && lower_k==0) { timer_k--; } // отслеживание конца if (timer_k==0 && tim_ocr_k>0 && end_k==0) {end_k=1; timer_akt_k=0; } // активность в 0 if ((tim_ocr_k==0 || tim_ocr_k-step_ke>max_k ) && end_k==1) // конец конца {end_k=0; tim_ocr_k=0; tim_write_k(); timer_akt_k=0;} if (tim_ocr_k>0 && end_k==1) { tim_ocr_k-=step_ke; tim_write_k(); } // отслеживание уменьшения яркости if (lower_k==1) {tim_ocr_k=tim_ocr_k-step_ke; tim_write_k(); } if (lower_k==1 && tim_ocr_k>max_k ) // конец уменьшения {lower_k=0;} LED=0; // мигаем светодиодом работы } void main(void) { // Crystal Oscillator division factor: 1 #pragma optsize- CLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif // Input/Output Ports initialization // Port A initialization // Func2=In Func1=In Func0=Out // State2=T State1=T State0=1 PORTA=0x01; DDRA=0x01; // Port B initialization // Func7=In Func6=In Func5=In Func4=Out Func3=Out Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=0 State3=0 State2=T State1=T State0=T PORTB=0x00; DDRB=0x18; // Port D initialization // Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=0 State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x41; /* // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 7.813 kHz // Mode: Normal top=0xFF // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x00; TCCR0B=0x05; TCNT0=0xB1; OCR0A=0x00; OCR0B=0x00; */ // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 31.250 kHz // Mode: Normal top=0xFF // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x00; TCCR0B=0x04; TCNT0=0x0B; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 8000.000 kHz // Mode: Ph. correct PWM top=0x03FF // OC1A output: Non-Inv. // OC1B output: Non-Inv. // Noise Canceler: Off // Input Capture on Falling Edge // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0xA3; TCCR1B=0x01; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // Interrupt on any change on pins PCINT0-7: Off // Interrupt on any change on pins PCINT8-10: Off // Interrupt on any change on pins PCINT11-17: Off MCUCR=0x00; GIMSK=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x02; // Universal Serial Interface initialization // Mode: Disabled // Clock source: Register & Counter=no clk. // USI Counter Overflow Interrupt: Off USICR=0x00; // USART initialization // USART disabled UCSRB=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; DIDR=0x00; // инициализация переменных begin_p=0; begin_k=0; end_p=0; end_k=0; timer_p=0; timer_k=0; tim_ocr_p=0; tim_ocr_k=0; timer_akt_p=0; timer_akt_k=0; zav_k=0; init_eerpom(); // после включения - таймаут для стабилизации датчиков for (start_cycle = 0; start_cycle < 15; start_cycle ++ ) { LED=1; // мигаем светодиодом работы delay_ms(125); LED=0; delay_ms(125); } // Global enable interrupts #asm("sei") while (1) { }; }