logo
Проектирование микроконтроллера

6. Программное обеспечение

. PROGRAM cooler

#include Mb90V590. h

. EXPORT _main

. SECTION DATA_MAIN, DATA, ALIGN=2

; инициализация начальных значений происходит в _init

isAnyoneInside. RES. B 1; есть ли кто-нибудь в помещении, 1 - да, 0 - нет

timerPeopleIn. RES. W 1; счетчик для таймера вентиляции (для подсчета 30 мин из 2Hz)

timerPeopleOutLight. RES. W 1; счетчик для таймера света (для подсчета 30 сек из 2Hz)

timerPeopleOutCool. RES. W 1; счетчик для таймера вентиляции (для подсчета 15 мин из 2Hz)

isTimerOn. RES. B 1; включен ли таймер

isTimerOnPeopleIn. RES. B 1; включен ли таймер

isTimerOnPeopleOutLight. RES. B 1; включен ли таймер

isTimerOnPeopleOutCool. RES. B 1; включен ли таймер

. SECTION INTR, CODE, ALIGN=2

int2HzTimer:; вызывается при включенном таймере 2 раза в секунду

clrb I: TMCSR0: 2; set UF=0

MOV isAnyoneInside,PDR2

cbne isAnyoneInside, #H01, disableCounterIn

mov timerPeopleOutLight, #H0

mov timerPeopleOutCool, #H0

checkCounterIn:

cbne isTimerPeopleIn, #H01, checkCounterOutLight

cbne timerPeopleIn, #H00, decCounterIn

mov isTimerPeopleIn, #H0

call timerSetOff

call coolerSetOn

jmp endTimer

decCounterIn:

dec timerPeopleIn

jmp checkCounterOutLight

disableCounterIn:

mov isTimerPeopleIn, #H0

// -----------

checkCounterOutLight:

cbne isTimerPeopleOutLight, #H01, checkCounterOutCool

cbne timerPeopleOutLight, #H00, decCounterOutLight

mov isTimerPeopleOutLight, #H0

call timerSetOff

call lightSetOff

jmp checkCounterOutCool

decCounterOutLight:

dec timerPeopleOutLight

// -----------

checkCounterOutCool:

cbne isTimerPeopleOutCool, #H01, endTimer

cbne timerPeopleOutCool, #H00, decCounterOutCool

mov isTimerPeopleOutCool, #H0

call timerSetOff

call coolerSetOff

jmp endTimer

decCounterOutCool:

dec timerPeopleOutCool

endTimer:

reti

externalInterrupt: // прерывание с датчика присутствия

call timerSetOn

call intPresence

reti

// задаем обработчик внешних прерываний

. SECTION INTVEC, CONST, LOCATE=HFFFFCC

. DATA. L externalInterrupt

// задаем обработчик прерывания таймера

. SECTION INTVEC2, CONST, LOCATE=HFFFFA0

. DATA. L int2HzTimer

. SECTION CODE_MAIN, CODE, ALIGN=2

timerSetOn:

cbne isTimerOn, #H0, endTimeSetUp; если таймер активен - ничего не делаем

movw timerPeopleIn, #D3600; 30min = 1800sec = 3600 * 0.5 = 3600 * 2HzTimer

movw timerPeopleOutLight, #D60; 30sec = 60 * 0.5 = 60 * 2HzTimer

movw timerPeopleOutCool, #D1800; 15min = 900sec = 1800 * 0.5 = 1800 * 2HzTimer

mov isTimerOn, #H0; ставим флаг, что таймер включен

movw A, #HF424; start timer counter = 62500

movw TMRLR0, A

; селектор ставим на понижении в 32 раза, включаем таймер

; после того, как счетчик досчитает до нуля вызывается прерывание

; которое обработается в int2HzTimer

movw A, #H81A; selector /32, autoflush, interrupts, enable timer

movw TMCSR0, A

endTimeSetUp:

ret

timerSetOff:

cbne isTimerPeopleIn, #H00, endTimerSetOff

cbne isTimerOnPeopleOutLight, #H00, endTimerSetOff

cbne isTimerOnPeopleOutCool, #H00, endTimerSetOff

movw A, #H00; отключаем таймер

movw TMCSR0, A

endTimerSetOff:

ret

lightSetOn:

setb PDR3: 1 // включаем лампу

ret

lightSetOff:

clrb PDR3: 1 // отключаем лампу

coolerSetOn:

setb PDR3: 0 // включаем вентилятор

ret

coolerSetOff:

clrb PDR3: 0 // отключаем вентилятор

ret

intPresence:; датчик присутствия

cbne PDR2, #H0, presenseAnyone // если никого в помещении нет

mov isTimerPeopleOutLight, #H1

mov isTimerPeopleOutCool, #H1

jmp presenseEnd

presenseAnyone:

call lightSetOn // включаем свет

mov isTimerOnPeopleIn,#H1

jmp presenseEnd

presenseEnd:

ret

_init:

; reset

mov isAnyoneInside, #H0

movw timerPeopleIn, #H0

movw timerPeopleOutLight, #H0

movw timerPeopleOutCool, #H0

mov isTimerPeopleIn, #H0

mov isTimerPeopleOutLight, #H0

mov isTimerPeopleOutCool, #H0

mov isTimerOn, #H0

; разрешаем внешние прерывания:

; INT4 - блок присутствия человека

setb ENIR: 4 // разрешаем прерывание с INT4

mov H000031, #H10 // очищаем значение регистра (EIRR) с INT4

mov H000033, #H2 // ELVR прерывание по нарастающему фронту

mov H0000B0, #H05; priority button/detect interrupts

mov H0000B6, #H06; priority timer interrupts

; разрешаем прерывания с приоритетом <=6

mov ILM, #H07

or CCR, #H40

; используем порты для ввода/вывода

setb DDR3: 0 // вентилятор p30

setb DDR3: 1 // лампа p31

clrb DDR2: 4 // датчик присутствия p24

ret

_main:

call _init

loop: nop; бесконечный цикл, т.к. вся работа основана на прерываниях

jmp loop

. end