Смекни!
smekni.com

Разработка устройства автоматического регулирования света на микроконтроллере (стр. 17 из 18)

{

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