#define bDECBPortB,6; Флаг нажатия кнопки "Уменьшить В"
#define bINCXPortB,5; Флаг нажатия кнопки "Увеличить Х"
#define bDECXPortB,4; Флаг нажатия кнопки "Уменьшить Х"
#defineTmpFlags,2; Флаг арифметических операций
; Вектор сброса
ORG0x0000
goto Start; Переходим к началу программы
; Вектор прерываний
ORG0x0004
; Interrupt
; Описание: Прерывание от TMR0. Измерение времени прохода шторки по сигналу с датчика Холла.
Interrupt;
movwfTmpW; Сохраняем состояние W и Status в регистры TmpW и TmpStatus
swapfStatus,W
movwfTmpStatus
movlwTMR_VALUE; Квантование таймера
movwfTmr0
bcfIntCon,T0IF; Сбрасываем флаг прерывания от таймера
movfPortB,W; Программный фильтр по входу датчика Холла
xorwfFlags,W
btfssbSens; Проверяем флаг датчика (1 шторка в датчике, 0 вне датчика)
goto _Low; Если 0 преходим
btfscbLastState; Проверяем предидущее состояние датчика
goto _HighToHigh; Если 1 преходим
_LowToHigh; Шторка вошла в датчик bSens=1 bLastState=0
bsfbLastState; Обновляем данные о состоянии датчика bLastState=1
bsfpCOIL; Включаем комутатор (Выставляем бит в RB2)
PLUS00 incf TimerL,F ; Начинаем отсчёт времени (TimerL(H,M) + 1)
btfss Status,Z
goto YES00
incf TimerM,F
btfss Status,Z
goto YES00
incf TimerH,F
YES00
goto _ExitInterrupt; Завершаем прерывание
_HighToHigh; Шторка уже в датчике bSens=1 bLastState=1
PLUS01 incf TimerL,F ; Продолжаем отсчёт времени (TimerL(H,M) + 1)
btfss Status,Z
goto YES01
incf TimerM,F
btfss Status,Z
goto YES01
incf TimerH,F
YES01
goto _ExitInterrupt
_Low; Шторка вне датчика bSens=0
btfssbLastState; Проверяем предидущее состояние датчика
goto _LowToLow
_HighToLow; Шторка вышла из датчика
bSens=0 bLastState=1
bcfbLastState; Обновляем данные о состоянии датчика bLastState=0
call CalculateSparkTime; Переходим к вычислению функции Y=f(T)
goto _ExitInterrupt
_LowToLow; Шторка уже вне датчика
_ExitInterrupt
DecWrt
DEC002
incf WrtH,W ; Проверяем было ли изменение констант, если было (WrtH<>0xFF), то осчитываем время до записи в память (2 сек)
btfss Status,Z
goto DEC003
goto OK00
DEC003
decf WrtL,F
movlw0xFF
subwfWrtL,W
btfss Status,Z
goto OK00
decf WrtH,F
movlw0xFF
subwfWrtH,W
btfss Status,Z
goto OK00
movlw0xFF; Выставляем 0хFF в WrtH (признак изменения констант)
movwfWrtH
clrfWrtL
call WriteC; Истекло время до записи изменённых переменных в память, переход на подпрограмму записи
OK00
swapfTmpStatus,W; Восстанавливаем соотояние W и Status и выходим из прерывания
movwfStatus
swapfTmpW,F
swapfTmpW,W
retfie
; Start
; Описание: Начало программы, инициализация контроллера и установка в начальное состояние
Start;
clrwdt
clrfIntCon; Обнуляем регистр прерываний
bsfStatus,RP0; Выбор банка памяти 1
movlwPORTB_IO
movwfTrisB
movlw0x88
movwfOptionR
bcfStatus,RP0; Выбор банка памяти 0
movlwPORTB_RESET
movwfPortB
clrf TimerH
clrf TimerM
clrf TimerL
movlw0xFF
movwfWrtH
clrfWrtL
movfPortB,W; Выставляем флаги в начальное состояние
andlw0xF2
movwfFlags
movlwTMR_VALUE; Квантование таймера
movwfTmr0
; Чтение констант из памяти
; movlw 0 ; Записать в регистр W константу 0 (адрес ячейки в памяти).
movwf EEAdr ; Скопировать 0h из регистра W в регистр EEAdr.
bsf Status,RP0 ; Переход в первый банк.
bsf EECon1,0 ; Инициализировать чтение.
bcf Status,RP0 ; Переход в нулевой банк.
movf EEData,W ; Скопировать число из ячейки EEPROM с адресом 0h в регистр W.
movwf MXH ; Скопировать число из регистра W в регистр MXH.
nop; Пустой оператор (ожидание)
movlw 1
movwf EEAdr
bsf Status,RP0
bsf EECon1,0
bcf Status,RP0
movf EEData,W
movwf MXL
nop
movlw 2
movwf EEAdr
bsf Status,RP0
bsf EECon1,0
bcf Status,RP0
movf EEData,W
movwf EX
nop
movlw 3
movwf EEAdr
bsf Status,RP0
bsf EECon1,0
bcf Status,RP0
movf EEData,W
movwf BH
nop
movlw 4
movwf EEAdr
bsf Status,RP0
bsf EECon1,0
bcf Status,RP0
movf EEData,W
movwf BL
movlw0xA0; Разрешаем прерывания от TMR0, и прерывания глобально, сбрасываем флаги прерываний
movwfIntCon
Cycle; Главный цикл программы
bsfIntCon,T0IE; Разрешаем прерывания от TMR0
bsfIntCon,GIE; Разрешаем прерывания глобально
movfPortB,W
xorwfFlags,W
btfsc bINCB;Если RB7 = 1, то переходим к увеличению переменной В
goto IncB
btfsc bDECB;Если RB6 = 1, то переходим к уменьшению переменной В
goto DecB
btfsc bINCX;Если RB5 = 1, то переходим к увеличению переменной Х
goto IncX
btfsc bDECX;Если RB4 = 1, то переходим к уменьшению переменной Х
goto DecX
gotoCycle
IncB; Подпрограмма увеличения переменной В
PLUS02
incf BL,F
btfss Status,Z
goto YES02
incf BH,F
btfss Status,Z
goto YES02
movlw0xFF
movwfBH
movwfBL
YES02
gotoYES07
DecB; Подпрограмма уменьшения переменной В
PLUS03
decf BL,F
movlw0xFF
subwfBL,W
btfss Status,Z
goto YES03
decf BH,F
movlw0xFF
subwfBH,W
btfss Status,Z
goto YES03
clrfBH
clrfBL
YES03
gotoYES07
IncX; Подпрограмма увеличения переменной Х
PLUS04
incf EX,F
movlw0x0A
subwfEX,W
btfss Status,Z
gotoYES05
clrfEX
PLUS05
incf MXL,F
btfss Status,Z
goto YES05
incf MXH,F
btfss Status,Z
goto YES05
movlw0xFF
movwfMXH
movwfMXL
movlw0x09
movwfEX
YES05
gotoYES07
DecX; Подпрограмма уменьшения переменной Х
PLUS06
decf EX,F
movlw0xFF
subwfEX,W
btfss Status,Z
goto YES07
decf MXL,F
movlw0xFF
subwfMXL,W
btfss Status,Z
goto YES06
decf MXH,F
movlw0xFF
subwfMXH,W
btfss Status,Z
goto YES06
clrfMXH
clrfMXL
clrfEX
gotoYES07
YES06
movlw0x09
movwfEX
YES07; Выход из подпрограм изменения переменных, инициализация отсчёта времени для записи в память (2 сек, 0x4E20)
movlw0x4E
movwfWrtH
movlw0x20
movwfWrtL
nop; Ожидание отпускания кнопок изменения переменных и переход на главный цикл программы
nop
nop
nop
gotoCycle
; Сохранение констант в энергонезависимую память
;WriteC
Bcf IntCon,GIE ; Глобальный запрет прерываний.
bcf Status,RP0 ; Переход в нулевой банк.
movlw 0 ; Записать в регистр W константу 0 (адрес ячейки в памяти).
movwf EEAdr ; Скопировать константу 0 из регистра W в регистр EEAdr.
movf MXH,W ; Скопировать число из регистра МХН в регистр W.
movwf EEData ; Скопировать число из регистра W в ячейку EEPROM с адресом 0.
bsf Status,RP0 ; Переход в первый банк.
bsf EECon1,2 ; Разрешить запись.
movlw 0x55 ; Обязательная
movwf EECon2 ; процедура
movlw 0xAA ; при записи.
movwf EECon2 ; "
bsf EECon1,1 ; "
WR0
Btfsc EECon1,1;Ожидание записи
gotoWR0
bcf EECon1,4 ; Сбросить флаг прерывания по окончании записи в EEPROM.
bcf Status,RP0
movlw 1
movwf EEAdr
movf MXL,W
movwf EEData
bsf Status,RP0
bsf EECon1,2
movlw 055h
movwf EECon2
movlw 0AAh
movwf EECon2
bsf EECon1,1
WR1
btfscEECon1,1
gotoWR1
bcf EECon1,4
bcf Status,RP0
movlw 2
movwf EEAdr
movf EX,W
movwf EEData
bsf Status,RP0
bsf EECon1,2
movlw 055h
movwf EECon2
movlw 0AAh
movwf EECon2
bsf EECon1,1
WR2
btfscEECon1,1
gotoWR2
bcf EECon1,4
bcf Status,RP0
movlw 3
movwf EEAdr
movf BH,W
movwf EEData
bsf Status,RP0
bsf EECon1,2
movlw 055h
movwf EECon2
movlw 0AAh
movwf EECon2
bsf EECon1,1
WR3
btfscEECon1,1
gotoWR3
bcf EECon1,4
bcf Status,RP0
movlw 4
movwf EEAdr
movf BL,W
movwf EEData
bsf Status,RP0
bsf EECon1,2
movlw 055h
movwf EECon2
movlw 0AAh
movwf EECon2
bsf EECon1,1
WR4
btfscEECon1,1
gotoWR4
bcf EECon1,4
return; Выход из подпрограммы записи в память
;Арифметические подпрограммы
SUM00 ; Операция сложения регистров MulL, MulM, MulH и TmpL, TmpM, TmpH, с учётом разряда
movf MulL,W
addwf TmpL,F
btfss Status,C
goto SUM01
incf TmpM,F
btfss Status,Z
goto SUM01
incf TmpH,F
SUM01
movf MulM,W
addwf TmpM,F
btfsc Status,C
incf TmpH,F
movf MulH,W
addwf TmpH,F
return
MIN00; Операция вычитания регистров MulL, MulM, MulH и TmpL, TmpM, TmpH, с учётом разряда
movf MulL,W
subwf TmpL,F
btfsc Status,C
goto MIN01
btfsc Status,Z
goto MIN01
decf TmpM,F
movlw0xFF
subwfTmpM,W
btfss Status,Z
goto MIN01
decf TmpH,F
movlw0xFF
subwfWrtH,W
btfss Status,Z
goto MIN01
clrfTmpH
clrfTmpM
clrfTmpL
MIN01
movf MulM,W
subwf TmpM,F
btfsc Status,C
goto MIN02
btfsc Status,Z
goto MIN02
decf TmpH,F
movlw0xFF
subwfTmpH,W
btfss Status,Z
goto MIN02
clrfTmpH
clrfTmpM
MIN02
movf MulH,W
subwf TmpH,F
btfsc Status,C
goto MIN03
btfsc Status,Z
goto MIN03
clrfTmpH
MIN03 ; Операция умножения регистров MulL, MulH на множитель MulM, с учётом разряда
return
MUL00
movlw0x09
movwfSec
movfMulM,W
clrfMulH
bcfStatus,C
MUL01
rrfMulH,F
rrfMulL,F
btfssStatus,C
gotoMUL02
addwfMulH,F
MUL02
decfszSec,F
gotoMUL01
return
Div24_16 ; Операция деления регистров Mul1L, Mul1H, ResHi на делитель DivLo, DivHi, с учётом разряда
clrf Temp
clrf Temp2
clrf Temp3
clrf Cnt
clrf Res1
clrf Res2
clrf Res3
movlw 0xf0
andwf DivHi,0
btfsc Status,Z
goto chknxt
movf ResHi,0
movwf Temp2
movf Mul1Hi,0
movwf Temp
movlw .2
movwf Sec
goto StartDiv
chknxt
movf DivHi,1
btfsc Status,Z
goto chknxt1
movlw 0xf0
andwf ResHi,0
movwf Temp2
swapf Temp2,1
movlw 0x0f
andwf ResHi,0
movwf Temp
swapf Temp,1
movlw 0xf0
andwf Mul1Hi,0
movwf Temp3
swapf Temp3,0
iorwf Temp,1
clrf Temp3
movlw .3
movwf Sec
goto StartDiv
chknxt1
movlw 0xf0
andwf DivLo,0
btfsc Status,Z
goto chknxt2
movf ResHi,0
movwf Temp
movlw .4
movwf Sec
goto StartDiv
chknxt2
movlw 0xf0
andwf ResHi,0
movwf Temp
swapf Temp,1
movlw .5
movwf Sec
StartDiv
sbagn
call Sub
btfsc Tmp
goto FinSub
incf Cnt,1
goto sbagn
Sub
bcf Tmp
movf DivLo,0
subwf Temp,1
btfsc Status,C
goto sub2nd
decf Temp2,1
movlw 0xff
subwf Temp2,0
btfss Status,Z
goto sub2nd
decf Temp3,1
movlw 0xff
subwf Temp3,0
btfsc Status,Z
bsf Tmp
sub2nd
movf DivHi,0
subwf Temp2,1
btfsc Status,C
return
decf Temp3,1
movlw 0xff
subwf Temp3,0
btfsc Status,Z
bsf Tmp
return
FinSub
movf DivLo,0
addwf Temp,1
btfss Status,C
goto add2nd
incfsz Temp2,1
goto add2nd
incf Temp3,1
add2nd
movf DivHi,0
addwf Temp2,1
btfss Status,C
goto jpqm
incf Temp3,1
jpqm
bcf Status,C
rrf Sec,0
movwf Fsr
movlw Res1
addwf Fsr,1
btfss Sec,0
goto nhjuq
swapf Cnt,0
iorwf Indf,1
goto ffr
nnhjuq
movf Cnt,0
iorwf Indf,1
ffr
decf Sec,1
movlw 0xff
subwf Sec,0
btfss Status,Z
goto notFin
goto FinDiv
notFin
bcf Status,C
rlf Temp,1
rlf Temp2,1
rlf Temp3,1
bcf Status,C
rlf Temp,1
rlf Temp2,1
rlf Temp3,1
bcf Status,C
rlf Temp,1
rlf Temp2,1
rlf Temp3,1
bcf Status,C
rlf Temp,1
rlf Temp2,1
rlf Temp3,1
bcf Status,C
rrf Sec,0
movwf Fsr
movlw Mul1Lo
addwf Fsr,1
btfsc Sec,0
goto nnhq
movlw 0x0f
andwf Indf,0
iorwf Temp,1
goto jjddsak
nnhq
swapf Indf,0
andlw 0x0f
iorwf Temp,1
jjddsak
clrf Cnt
goto sbagn
FinDiv ; Операция округления при делении
bcf Status,C
rrf DivHi,1
rrf DivLo,1
movf DivHi,0
subwf Temp2,0
btfss Status,C
goto dsgfadsg
btfss Status,Z
goto cxv
movf DivLo,0
subwf Temp,0
btfss Status,C
goto dsgfadsg
cxv
incfsz Res1,1
goto dsgfadsg
incfsz Res2,1
goto dsgfadsg
incf Res3,1
dsgfadsg
movf Res1,0
movwf Mul1Lo
movf Res2,0
movwf Mul1Hi
movf Res3,0
movwf ResHi
return
;Подпрограмма расчёта времени удержания сигнала коммутатору Y=f(T) (Y=T*XB)
CalculateSparkTime;
clrfTmpH
clrfTmpM
clrfTmpL
movfTimerL,W ; Множим TimerL(H,M) на MX(L,H)
movwfMulL
movfMXL,W
movwfMulM
callMUL00
movfMulH,W
movwfMulM
clrfMulH
callSUM00
movfTimerM,W
movwfMulL
movfMXL,W
movwfMulM
callMUL00
movfMulL,W
movwfMulM
clrfMulL
callSUM00
movfTimerH,W
movwfMulL
movfMXL,W
movwfMulM
callMUL00
movfMulL,W
movwfMulH
clrfMulL
clrfMulM
callSUM00
movfTimerL,W