{
case 5:
write(plus);
break;
case 6:
write(minus);
break;
default:
error=0;
for(num=0; num<number_of_impuls-1; num++)
{
temp=plus[num];
if(temp==0xFF) break;
verify(temp);
}
if(!error)
{
ir_plus=1;
ir_minus=0;
}
error=0;
for(num=0; num<number_of_impuls-1; num++)
{
temp=minus[num];
if(temp==0xFF) break;
verify(temp);
}
if(!error)
{
ir_plus=0;
ir_minus=1;
}
if(ir_plus || ir_minus) zader=udervanie;
//очистка массива и переменной num
num=number_of_impuls;
while(num) serial[--num]=0;
break;
}
}
}
#include "keyboard.c"
//==========================================================
//обработка кнопок.
//==========================================================
void keyboard(void)
{
#define press_time 10
static unsigned int counter;//счетчик для снижения частоты вызова опроса клавиатуры.
static unsigned char press_plus;//счетчик последовательных нажатий на кнопку "+"
static unsigned char press_minus;//счетчик последовательных нажатий на кнопку "-"
static unsigned char press_key;//отсчет лимита времени на вход в mode=5 или 6.
static unsigned int zader;//счетчик времени нажатия на кнопку.
if(++counter<2000) return;
//обнуляем счетчик
counter=0;
//опрашиваем кнопки.
on_old=on_new;
off_old=off_new;
on_new=kn_plus;
off_new=kn_minus;
//удерживаем "+" и "-"
if(!on_old && !off_old && !on_new && !off_new)
{
if(zader > press_time*3)
{
mode=0;//хозяин дома
in_home=1;
clock=0;
}
else zader++;
return;
}
//удерживаем "-"
if(on_old && !off_old && on_new && !off_new || (ir_minus && !in_home))
{
if(zader>=press_time)
{
mode=1;//медленно снижать яркость
in_home=0;
}
else zader++;
return;
}
//удерживаем "+"
if(!on_old && off_old && !on_new && off_new || (ir_plus && !in_home))
{
if(zader>=press_time)
{
mode=2;//медленно повышать яркость
in_home=0;
}
else zader++;
return;
}
//отпускаем "-"
if(on_old && !off_old && on_new && off_new && (mode!=5) && (mode!=6) || ir_m_otp)
{
ir_m_otp=0;
if(zader<press_time)
{
mode=3;//быстро выключить
in_home=0;
ofa=ofa - (ofa - ofa_min)/4;
}
return;
}
//отпускаем "+"
if(!on_old && off_old && on_new && off_new && (mode!=5) && (mode!=6) || ir_p_otp)
{
ir_p_otp=0;
if(zader<press_time)
{
mode=4;//быстро включить
in_home=0;
}
return;
}
//нажатие "+"
if(on_old && off_old && !on_new && off_new)
{
enable_count=1;
if(++press_plus>7)
{
mode=5;//режим запоминания посылки ДУ "+"
goto l1;
}
return;
}
//нажатие "-"
if(on_old && off_old && on_new && !off_new)
{
enable_count=1;
if(++press_minus>7)
{
mode=6;//режим запоминания посылки ДУ "-"
l1:
clock=0;
}
return;
}
//
if(enable_count) ++press_key;
if(press_key>press_time*2)
{
enable_count=0;
press_key=0;
press_plus=0;
press_minus=0;
}
//если при медленном изменении яркости ничего не нажато, то остановить изменение яркости.
if(mode==1 || mode==2) mode=7;
//обнуляем счетчик
zader=0;
}
#include "faza.c"
//==========================================================
//обработка прерывания от положительного перепада полуволны.
//==========================================================
#pragma savereg-
interrupt [EXT_INT0] void ext_int0_isr(void)
{
s_reg=SREG;
#asm
PUSH R30
#endasm
second_half_period=0;//предустановка на двойную обработку прерывания timer1.
TCNT1H=0xFF;//выдержка timer1
TCNT1L=ofa;
TIMSK=0x82;//разрешение прерывания по переполнению timer1.
#asm
POP R30
#endasm
SREG=s_reg;
}
#pragma savereg+
#include "timer0.c"
//==========================================================
//обработка прерывания таймера0.
//==========================================================
#pragma savereg-
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
if(closed) #asm("RETI");
//сохраняем используемые регистры
#asm
PUSH R24
PUSH R25
PUSH R26
PUSH R27
PUSH R28
PUSH R29
PUSH R30
PUSH R31
IN R30,SREG
ORI R30,0x80
PUSH R30
#endasm
//опросим пульт ДУ
infra_old=infra;
infra=PINB.0;
if(ir_plus_old && !ir_plus && !in_home && (mode!=1) && (mode!=2)) ir_p_otp=1;
if(ir_minus_old && !ir_minus && !in_home && (mode!=1) && (mode!=2)) ir_m_otp=1;
ir_plus_old=ir_plus;
ir_minus_old=ir_minus;
//разрешаем прерывания
#asm("SEI");
//обработаем пульт ДУ
infrared();
//опрашиваем кнопки
keyboard();
if(++tic>=7813)//ждем 0,5сек
{
tic=0;
clock++;//0 to 4294967295
second=~second;
}
//восстанавливаем использованные регистры и возвращаемся.
#asm
POP R30
OUT SREG,R30
POP R31
POP R30
POP R29
POP R28
POP R27
POP R26
POP R25
POP R24
#endasm
closed=0;
#asm
RET
#endasm
}
#pragma savereg+
#include "timer1.c"
//==========================================================
//обработка прерывания таймера1 (включение симистора).
//==========================================================
#pragma savereg-
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
//сохраняем регистры
s_reg=SREG;
#asm
PUSH R30
#endasm
//формируем импульс зажигания.
PORTB=0x00;
//delay_us(7);
#asm
LDI R30,9
__DELAY:
DEC R30
BRNE __DELAY
#endasm
PORTB=0b00011110;
//выдержка 10мсек для второго прохода.
TCNT1H=0xFF;
TCNT1L=0x64;
if(second_half_period) TIMSK=0x02;//запрещаем прерывания таймера1.
second_half_period=1;
//восстанавливаем регистры
#asm
POP R30
#endasm
SREG=s_reg;
}
#pragma savereg+
void main(void)
{
begin:
#asm("cli");
#include "init.c"
// Input/Output Ports initialization
// Port B initialization
// Func0=In Func1=Out Func2=Out Func3=Out Func4=Out Func5=In Func6=In Func7=In
// State0=T State1=1 State2=1 State3=1 State4=1 State5=T State6=T State7=T
DDRB =0b00011110;
PORTB=0b00011110;
// Port D initialization
// Func0=In Func1=In Func2=In Func3=In Func4=Out Func5=Out Func6=In
// State0=P State1=T State2=T State3=T State4=0 State5=1 State6=P
DDRD =0b00110000;
PORTD=0b01000001;
// Timer/Counter 0 initialization
// Clock source: System Clock
TCCR0=0x01;
TCNT0=0x02;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Normal top=FFFFh
// OC1 output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1B=0x04;
TCCR1A=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1H=0x00;
OCR1L=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: Off
GIMSK=0x00;
MCUCR=0x03;
GIFR=0x40;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
//подготовка данных
second_half_period=closed=0;
on_old=off_old=infra=infra_old=in_home=1;
mode=0;
ofa=ofa_min;
#asm("sei");
while (1)
{
switch(mode)
{
case 0: #include "mode_0.c";//хозяин дома
//хозяин дома
red=second;//моргаем красным и зеленым светодиодами
green=second;
//4 часа
if(clock==28800) mode=4;//быстро включить
//еще полчаса
if(clock>32400)
{
mode=3;//быстро погасить
clock=0;
}
break;
case 1: #include "mode_1.c";//медленно снижать яркость
//медленно снижать яркость
if(GIMSK==0x00)
{
mode=7;
break;
}
if(++timer_ofa>7500)
{
timer_ofa=0;
if(ofa>ofa_min) ofa--;
else GIMSK=0x00;
}
break;
case 2: #include "mode_2.c";//медленно повышать яркость
//медленно повышать яркость
if(GIMSK==0x00)
{
ofa=ofa_min;
GIMSK=0x40;
timer_ofa=0;
}
if(++timer_ofa>7500)
{
timer_ofa=0;
if(ofa<ofa_max) ofa++;
else mode=7;
}
break;
case 3: #include "mode_3.c";//быстро погасить
//быстро погасить
if(GIMSK==0x00)
{
if(in_home) mode=0;
else mode=7;
break;
}
if(++timer_ofa>21000)
{
timer_ofa=0;
if(ofa>ofa_min) ofa--;
else GIMSK=0x00;
}
break;
case 4: #include "mode_4.c";//быстро включить
//быстро включить
if(GIMSK==0x00)
{
ofa=ofa_min;
GIMSK=0x40;
timer_ofa=0;
}
if(++timer_ofa>330)
{
timer_ofa=0;
if(ofa<ofa_max) ofa++;
else
{
if(in_home) mode=0;
else mode=7;
}
}
break;
case 5: #include "mode_5.c";//запомнить ДУ "+"
//запомнить ДУ "+"
red=0;
green=second;
//если за 10 сек не приняли сигнал программирования, то выход из программирования
if(clock>20) mode=7;
break;
case 6: #include "mode_6.c";//запомнить ДУ "-"
//запомнить ДУ "-"
green=0;
red=second;
//если за 10 сек не приняли сигнал программирования, то выход из программирования
if(clock>20) mode=7;
break;
case 7: #include "mode_7.c";//просто ждем
//просто ждем
if(GIMSK==0x00) green=1;//зажигаем зеленый светодиод
else green=0;//тушим зеленый светодиод
break;
default:
goto begin;
}
#asm
SBIS 0x16,0
RJMP L1
CBI 0x12,4
RJMP L2
L1:
SBI 0x12,4
L2:
#endasm
}
}
ПРИЛОЖЕНИЕ Б
:1000000011C06DC2FDCFFCCFFBCFCEC274C2F8CF02
:10001000F7CFF6CFF5CF414D415220543032363034
:1000200000000000F894EE27ECBBE5BFF8E1F1BD5D
:10003000E1BD8DE0A2E0ED938A95E9F780E8A0E6C6
:10004000ED938A95E9F7E2E2F0E0C8953196802DCC
:10005000C8953196902D0097B9F0C8953196A02D8E
:10006000C8953196B02DC8953196102CC89531960B
:100070006E2F7F2FF02DE12DC89531960D920197AF
:10008000D9F7E62FF72FE1CFEFEDEDBFC0E8D0E0D5
:10009000A1C28824EFE38E1680F4E82DA881B981EF
:1000A000F0E0EA0FFB1FFF93EF93A0E8A80DEC919F
:1000B000AF91BF9197D38394EDCFE7E07E2E882454
:1000C000E0E0E093800022960895A0E8A80DEC916E
:1000D000EF93E881E695E695A88175D3EA1BAF9189
:1000E000AE1760F0A0E8A80DEC91EF93E881E695DB
:1000F000E695A881EA0FAF91EA1710F4689435F8F5
:10010000219608950A93E091BF00F091C0003097C6
:10011000E1F021FE02C020FC01C010C0E091BF0050
:10012000F091C0003197E093BF00F093C00030978A
:1001300009F0B5C0E89423F824F8B1C0EBE1F6E08B
:10014000E093BF00F093C000AAC0E091C100E0308E
:1001500019F420FE22C0A3C0A091C100A73030F541
:1001600021FE03C020FC03C00EC020FC0CC0A0E890
:10017000EC91EF5FEC93AE2FEAEFEA1718F4E0E0B2
:10018000E093C1008CC0A0918000E4E1EA1728F45C
:10019000E091C100EF5FE093C100E091C100EF5F2B
:1001A000E093C100E0E0E093800079C0E0E021FC52
:1001B000E1E0EF93E0E020FCE1E0AF91EA1731F0FD
:1001C0008394A0E8A80DE0E0EC9369C0EFE38E16FD
:1001D00028F4A0E8A80DAC91AF3F08F006C0A0E855
:1001E000A80DEC91EF5FEC935AC0689427F8E0E01B
:1001F000E093C100E72DE53031F4E1E0F0E0FA935F
:10020000EA9347DF4CC0E63031F4E0E4F0E0FA93E3
:10021000EA933FDF44C0E89435F88824EEE38E1675
:1002200060F4A82DB0E0AF5FBF4FD1D20E2F0F3FCB
:1002300021F00A934ADF8394F1CF35FC04C068941F
:1002400023F8E89424F8E89435F88824EEE38E1631
:1002500060F4A82DB0E0A05CBF4FB9D20E2F0F3FC5
:1002600021F00A9332DF8394F1CF35FC04C0E89487
:1002700023F8689424F823FC02C024FE06C0EBE1B6
:10028000F6E0E093BF00F093C000EFE38E2E8820ED
:1002900031F08A94A0E8A80DE0E0EC93F8CF099142
:1002A0000895A091C200B091C3001196A093C2001E
:1002B000B093C300A03DE7E0BE0708F40895E0E076
:1002C000E093C200E093C30030FA31F832FA33F819
:1002D000E8948099689430F8E8948699689432F8A4
:1002E00031FC06C033FC04C030FC02C032FE01C049
:1002F00019C0A091C700B091C800EEE1F0E0EA1784
:10030000FB0730F47724689441F8DD24EE2409C01B
:10031000E091C700F091C8003196E093C700F093D8
:10032000C800089531FE06C033FC04C030FE02C090
:1003300032FE05C024FE02C041FE01C017C0A091DC
:10034000C700B091C800AA30E0E0BE0728F0E1E0A5
:100350007E2EE89441F809C0E091C700F091C800F2
:100360003196E093C700F093C800089531FC06C0B1
:1003700033FE04C030FC02C032FC05C023FE02C0C4
:1003800041FE01C017C0A091C700B091C800AA30BB
:10039000E0E0BE0728F0E2E07E2EE89441F809C0D4
:1003A000E091C700F091C8003196E093C700F09348
:1003B000C800089531FE0CC033FC0AC030FE08C0EE
:1003C00032FE06C0E5E0E71519F0E6E0E71511F4A6
:1003D00037FE15C0E89437F8A091C700B091C80067
:1003E000AA30E0E0BE0750F4E3E07E2EE89441F846
:1003F000A62DA058EA2FE695E6956E1A089531FCD1
:100400000CC033FE0AC030FE08C032FE06C0E5E074
:10041000E71519F0E6E0E71511F436FE0FC0E89491
:1004200036F8A091C700B091C800AA30E0E0BE073E
:1004300020F4E4E07E2EE89441F8089531FE06C0F1
:1004400033FE04C030FC02C032FC01C00DC0689411
:1004500034F8A091C400AF5FA093C400E7E0EA17AE
:1004600010F4E5E015C0089531FE06C033FE04C067
:1004700030FE02C032FE01C00FC0689434F8A09173
:10048000C500AF5FA093C500E7E0EA1720F4E6E0FF
:100490007E2EDD24EE24089534FE05C0E091C600D2
:1004A000EF5FE093C600A091C600E4E1EA1748F4CC
:1004B000E89434F8E0E0E093C600E093C400E093F1
:1004C000C500E1E0E71519F0E2E0E71511F4E7E017
:1004D0007E2EE0E0E093C700E093C80008955FB689
:1004E000EF93E89422F8EFEFEDBD6CBCE2E8E9BFD2
:1004F000EF915FBE189527FE01C018958F939F93CB
:10050000AF93BF93CF93DF93EF93FF93EFB7E06881
:10051000EF9320FA21F8E894B099689420F825FE2A
:100520000AC023FC08C041FC06C0E1E0E71519F051
:10053000E2E0E71509F402C0689436F826FE0AC026
:1005400024FC08C041FC06C0E1E0E71519F0E2E038