Исходник (таблица опережения вырезана для уменьшения текста).
Вот печатный вариант для удобства http://rusfolder.com/39767674
Спойлер
; Контроллер --------------------------------------------------------------------------------------LIST p=16f628
#define PIC16F628
;--------------------------------------------------------------------------------------------------
; Register Definitions
;--------------------------------------------------------------------------------------------------
W EQU H'0000'
F EQU H'0001'
;----- Register Files------------------------------------------------------------------------------
INDF EQU H'0000'
TMR0 EQU H'0001'
PCL EQU H'0002'
STATUS EQU H'0003'
FSR EQU H'0004'
PORTA EQU H'0005'
PORTB EQU H'0006'
PCLATH EQU H'000A'
INTCON EQU H'000B'
PIR1 EQU H'000C'
TMR1L EQU H'000E'
TMR1H EQU H'000F'
T1CON EQU H'0010'
TMR2 EQU H'0011'
T2CON EQU H'0012'
CCPR1L EQU H'0015'
CCPR1H EQU H'0016'
CCP1CON EQU H'0017'
RCSTA EQU H'0018'
TXREG EQU H'0019'
RCREG EQU H'001A'
CMCON EQU H'001F'
OPTION_REG EQU H'0081'
TRISA EQU H'0085'
TRISB EQU H'0086'
PIE1 EQU H'008C'
PCON EQU H'008E'
PR2 EQU H'0092'
TXSTA EQU H'0098'
SPBRG EQU H'0099'
EEDATA EQU H'009A'
EEADR EQU H'009B'
EECON1 EQU H'009C'
EECON2 EQU H'009D'
VRCON EQU H'009F'
;----- STATUS Bits --------------------------------------------------------------------------------
IRP EQU H'0007'
RP1 EQU H'0006'
RP0 EQU H'0005'
NOT_TO EQU H'0004'
NOT_PD EQU H'0003'
Z EQU H'0002'
DC EQU H'0001'
C EQU H'0000'
;----- INTCON Bits --------------------------------------------------------------------------------
GIE EQU H'0007'
PEIE EQU H'0006'
T0IE EQU H'0005'
INTE EQU H'0004'
RBIE EQU H'0003'
T0IF EQU H'0002'
INTF EQU H'0001'
RBIF EQU H'0000'
;----- PIR1 Bits ----------------------------------------------------------------------------------
EEIF EQU H'0007'
CMIF EQU H'0006'
RCIF EQU H'0005'
TXIF EQU H'0004'
CCP1IF EQU H'0002'
TMR2IF EQU H'0001'
TMR1IF EQU H'0000'
;----- T1CON Bits ---------------------------------------------------------------------------------
T1CKPS1 EQU H'0005'
T1CKPS0 EQU H'0004'
T1OSCEN EQU H'0003'
NOT_T1SYNC EQU H'0002'
TMR1CS EQU H'0001'
TMR1ON EQU H'0000'
;----- T2CON Bits ---------------------------------------------------------------------------------
TOUTPS3 EQU H'0006'
TOUTPS2 EQU H'0005'
TOUTPS1 EQU H'0004'
TOUTPS0 EQU H'0003'
TMR2ON EQU H'0002'
T2CKPS1 EQU H'0001'
T2CKPS0 EQU H'0000'
;----- CCP1CON Bits -------------------------------------------------------------------------------
CCP1X EQU H'0005'
CCP1Y EQU H'0004'
CCP1M3 EQU H'0003'
CCP1M2 EQU H'0002'
CCP1M1 EQU H'0001'
CCP1M0 EQU H'0000'
;----- RCSTA Bits ---------------------------------------------------------------------------------
SPEN EQU H'0007'
RX9 EQU H'0006'
SREN EQU H'0005'
CREN EQU H'0004'
ADEN EQU H'0003'
FERR EQU H'0002'
OERR EQU H'0001'
RX9D EQU H'0000'
;----- CMCON Bits ---------------------------------------------------------------------------------
C2OUT EQU H'0007'
C1OUT EQU H'0006'
C2INV EQU H'0005'
C1INV EQU H'0004'
CIS EQU H'0003'
CM2 EQU H'0002'
CM1 EQU H'0001'
CM0 EQU H'0000'
;----- OPTION Bits --------------------------------------------------------------------------------
NOT_RBPU EQU H'0007'
INTEDG EQU H'0006'
T0CS EQU H'0005'
T0SE EQU H'0004'
PSA EQU H'0003'
PS2 EQU H'0002'
PS1 EQU H'0001'
PS0 EQU H'0000'
;----- PIE1 Bits ----------------------------------------------------------------------------------
EEIE EQU H'0007'
CMIE EQU H'0006'
RCIE EQU H'0005'
TXIE EQU H'0004'
CCP1IE EQU H'0002'
TMR2IE EQU H'0001'
TMR1IE EQU H'0000'
;----- PCON Bits ----------------------------------------------------------------------------------
OSCF EQU H'0003'
NOT_POR EQU H'0001'
NOT_BO EQU H'0000'
NOT_BOR EQU H'0000'
NOT_BOD EQU H'0000'
;----- TXSTA Bits ---------------------------------------------------------------------------------
CSRC EQU H'0007'
TX9 EQU H'0006'
TXEN EQU H'0005'
SYNC EQU H'0004'
BRGH EQU H'0002'
TRMT EQU H'0001'
TX9D EQU H'0000'
;----- EECON1 Bits --------------------------------------------------------------------------------
WRERR EQU H'0003'
WREN EQU H'0002'
WR EQU H'0001'
RD EQU H'0000'
;----- VRCON Bits ---------------------------------------------------------------------------------
VREN EQU H'0007'
VROE EQU H'0006'
VRR EQU H'0005'
VR3 EQU H'0003'
VR2 EQU H'0002'
VR1 EQU H'0001'
VR0 EQU H'0000'
;--------------------------------------------------------------------------------------------------
; RAM Definition
;--------------------------------------------------------------------------------------------------
__MAXRAM H'01FF'
__BADRAM H'07'-H'09', H'0D', H'13'-H'14', H'1B'-H'1E'
__BADRAM H'87'-H'89', H'8D', H'8F'-H'91', H'93'-H'97', H'9E'
__BADRAM H'105', H'107'-H'109', H'10C'-H'11F', H'150'-H'16F'
__BADRAM H'185', H'187'-H'189', H'18C'-H'1EF'
;--------------------------------------------------------------------------------------------------
; Configuration Bits
;--------------------------------------------------------------------------------------------------
_BODEN_ON EQU H'3FFF'
_BODEN_OFF EQU H'3FBF'
_CP_ALL EQU H'03FF'
_CP_75 EQU H'17FF'
_CP_50 EQU H'2BFF'
_CP_OFF EQU H'3FFF'
_DATA_CP_ON EQU H'3EFF'
_DATA_CP_OFF EQU H'3FFF'
_PWRTE_OFF EQU H'3FFF'
_PWRTE_ON EQU H'3FF7'
_WDT_ON EQU H'3FFF'
_WDT_OFF EQU H'3FFB'
_LVP_ON EQU H'3FFF'
_LVP_OFF EQU H'3F7F'
_MCLRE_ON EQU H'3FFF'
_MCLRE_OFF EQU H'3FDF'
_ER_OSC_CLKOUT EQU H'3FFF'
_ER_OSC_NOCLKOUT EQU H'3FFE'
_INTRC_OSC_CLKOUT EQU H'3FFD'
_INTRC_OSC_NOCLKOUT EQU H'3FFC'
_EXTCLK_OSC EQU H'3FEF'
_LP_OSC EQU H'3FEC'
_XT_OSC EQU H'3FED'
_HS_OSC EQU H'3FEE'
; Конфигурация ------------------------------------------------------------------------------------
__CONFIG _CP_OFF & _WDT_ON & _PWRTE_ON & _XT_OSC & _MCLRE_OFF & _LVP_OFF & _DATA_CP_OFF & _BODEN_OFF
; Параметры ---------------------------------------------------------------------------------------
#define TMR_VALUE 0xCE ; Квантование таймера 60 мкс
#define COIL_OFF_VALUE 0x60 ; Отключение катушки через 4 секунды
#define MODUL_CONFIG_METAL ; Конфигурация шторки-модулятора: МЕТАЛЛ
#define FUNC1_WARMING_SPARK ; Дополнительная функция 1: ПРОГРЕВ СВЕЧЕЙ
#define WARMING_COIL_TIME 0x32 ; Таймер включения катушки при прогреве свечей
#define FUNC2_OVERRUN ; Дополнительная функция 2: ОГРАНИЧЕНИЕ ОБОРОТОВ
#define FUNC2_OVERRUN_LIMIT .33 ; Частота вращения вала для ораничения оборотов 5000об/мин
; Назначение портов ввода/вывода ------------------------------------------------------------------
#define pLED_N PORTA,2 ; Выход на светодиод
#define pSENSOR PORTB,1 ; Вход датчика Холла
#define pCOIL PORTB,2 ; Выход управления коммутатором
#define pCOIL_N PORTB,3 ; Инвертированный выход управления коммутатором
#define pFUNC1_N PORTB,4 ; Вход дополнительной функции 1
#define pFUNC2_N PORTB,5 ; Вход дополнительной функции 2
#define pSELECT1_N PORTB,6 ; Выбор таблицы УОЗ 1
#define pSELECT2_N PORTB,7 ; Выбор таблицы УОЗ 2
; Маски портов ------------------------------------------------------------------------------------
#define SENSOR_MASK 0x02 ; Вход датчика Холла
#define FUNC1_MASK 0x10 ; Вход дополнительной функции 1
#define FUNC2_MASK 0x20 ; Вход дополнительной функции 2
#define SELECT1_MASK 0x40 ; Выбор таблицы УОЗ 1
#define SELECT2_MASK 0x80 ; Выбор таблицы УОЗ 2
; Направление работы портов ввода/вывода (0 - вывод, 1 - ввод) ------------------------------------
#define PORTA_IO 0x00 ; Порт A
#define PORTB_IO 0xF2 ; Порт B
; Сбросовые состояния портов ----------------------------------------------------------------------
#define PORTA_RESET 0x04 ; Порт A
#define PORTB_RESET 0x08 ; Порт B
; Память данных -----------------------------------------------------------------------------------
TmpW EQU 0x20 ; Состояние W
TmpSTATUS EQU 0x21 ; Состояние STATUS
Flags EQU 0x22 ; Флаги состояния
Ports EQU 0x23 ; Состояние входных портов
SensCnt EQU 0x24 ; Счетчик фильтра датчика Холла
SectorCnt EQU 0x25 ; Счетчик сектора
LastSectorCnt EQU 0x26 ; Сохраненное значение счетчика сектора
SparkTime EQU 0x27 ; Определяет момент искрообразования
CoilCnt_0 EQU 0x28 ; Двухбайтный счетчик включения катушки
CoilCnt_1 EQU 0x29
CoilOffCnt_0 EQU 0x2A ; Двухбайтный счетчик отключения катушки при простое
CoilOffCnt_1 EQU 0x2B
Func1Cnt EQU 0x2C ; Счетчик фильтра на входе FUNC1
Func2Cnt EQU 0x2D ; Счетчик фильтра на входе FUNC2
Select1Cnt EQU 0x2E ; Счетчик фильтра на входе SELECT1
Select2Cnt EQU 0x2F ; Счетчик фильтра на входе SELECT2
WarmingCnt EQU 0x30 ; Счетчик прогрева свечей
; Битовые переменные ------------------------------------------------------------------------------
#define bLastState Flags,0 ; Последнее состояние сигнала датчика Холла
#define bOverflow Flags,1 ; Переполнение счетчика
#define bCoilOff Flags,2 ; Отключение катушки при простое
#define bEngineStop Flags,3 ; Отключение двигателя
#define bOverrun1 Flags,4 ; Срабатывание ограничения оборотов по функции 1
#define bOverrun2 Flags,5 ; Срабатывание ограничения оборотов по функции 2
#define bSens Ports,1 ; Состояние сигнала датчика Холла после программного фильтра
#define bFunc1_n Ports,4 ; Включение дополнительной функции 1
#define bFunc2_n Ports,5 ; Включение дополнительной функции 2
#define bSelect1_n Ports,6 ; Выбор характеристики УОЗ 1
#define bSelect2_n Ports,7 ; Выбор характеристики УОЗ 2
; Вектор сброса -----------------------------------------------------------------------------------
ORG 0x0000
clrwdt
clrf INTCON ; Обнуляем регистр прерываний
goto Start ; Переходим к началу программы
; Вектор прерываний -------------------------------------------------------------------------------
ORG 0x0004
; Interrupt ---------------------------------------------------------------------------------------
;
; Описание: Прерывание от TMR0. Измерение времени прохода шторки по сигналу с датчика Холла.
; Своевременное включение и отключение катушки.
;--------------------------------------------------------------------------------------------------
Interrupt;
clrwdt
movwf TmpW ; Сохраняем состояние
swapf STATUS,W
movwf TmpSTATUS
movlw TMR_VALUE ; Квантование таймера
movwf TMR0
bcf INTCON,T0IF ; Сбрасываем флаг прерывания
movf PORTB,W ; Программный фильтр по входу датчика Холла
xorwf Ports,W
andlw SENSOR_MASK
btfsc STATUS,Z
clrf SensCnt ; Сбрасываем байт счетчика
incf SensCnt,F
btfss SensCnt,2 ; Досчитаем до 4
goto $+.4
movlw SENSOR_MASK ; Инвертируем состояние флага
xorwf Ports,F
clrf SensCnt
#ifdef MODUL_CONFIG_METAL
btfss bSens ; Проверяем флаг датчика (1 - шторка в датчике, 0 - вне датчика)
goto _Out
#else ; #ifdef MODUL_CONFIG_SPACE
btfsc bSens ; Проверяем флаг датчика инверсно (0 - шторка в датчике, 1 - вне датчика)
goto _Out
#endif
btfsc bLastState ; Проверяем предидущее состояние датчика
goto _SensorActive
_SensorIn ; Шторка вошла в датчик
btfsc bEngineStop ; Если двигатель не остановлен
goto $+.7
btfsc bOverrun1 ; Нет ограничения оборотов по функции 1
goto $+.5
btfsc bOverrun2 ; Нет ограничения оборотов по функции 2
goto $+.3
bsf pCOIL ; Включаем катушку зажигания
bcf pCOIL_N
movf SectorCnt,W ; Сохраняем счетчик оборотов
movwf LastSectorCnt
bsf bLastState ; Обновляем данные о состоянии датчика
clrf SectorCnt ; Сбрасываем счетчик
bcf bOverflow ; Сбрасываем флаг переполнения
clrf CoilOffCnt_1 ; Обнуляем счетчик отключения катушки, двигатель работает
bcf bCoilOff ; Снимаем флаг отключения катушки, двигатель работает
goto _ExitInterrupt
_SensorActive ; Активный элемент шторки уже в датчике
bcf pLED_N ; Включаем светодиод
btfsc bOverflow ; Если счетчик был переполнен, не проверяем его на момент искрообразования
goto _ExitInterrupt
incf SectorCnt,F ; Продолжаем отсчитывать счетчик
movf SectorCnt,W ; Проверяем счетчик на переполнение (максимум 239)
xorlw .239
btfsc STATUS,Z
bsf bOverflow ; Счетчик переполнен, выставляем флаг
movf SparkTime,W ; Проверяем счетчик на момент искрообразования, если он не равен 0 (т.е. при запуске)
btfsc STATUS,Z
goto _ExitInterrupt ; Происходит запуск, искра будет образована при выходе шторки из датчика
xorwf SectorCnt,W
btfss STATUS,Z
goto _ExitInterrupt
bcf pCOIL ; Инициируем искру
bsf pCOIL_N
goto _ExitInterrupt
_Out ; Шторка вне датчика
btfss bLastState ; Проверяем предидущее состояние датчика
goto _SensorIdle
_SensorOut ; Шторка вышла из датчика
bcf pCOIL ; Инициируем искру, если этого еще не произошло (запуск)
bsf pCOIL_N
bcf bLastState ; Обновляем данные о состоянии датчика
clrf CoilCnt_0 ; Обнуляем время включения катушки
clrf CoilCnt_1
movf SparkTime,W ; Скважность импульсов должна составлять ~70%
btfsc STATUS,Z
movlw .239
addwf SectorCnt,W
movwf CoilCnt_0
rlf CoilCnt_1,F
call CalculateSparkTime ; Вычисляем момент искрообразования
movwf SparkTime
goto _ExitInterrupt
_SensorIdle ; Шторка уже вне датчика
bsf pLED_N ; Отключаем светодиод
decf CoilCnt_0,F ; Обновляем счетчик включения катушки
btfss STATUS,Z
goto _ExitInterrupt
movf CoilCnt_1,W
btfsc STATUS,Z
goto $+.3
decf CoilCnt_1,F
goto _ExitInterrupt
btfsc bEngineStop ; Если двигатель не остановлен
goto $+.9
btfsc bCoilOff ; Катушка не отключена при простое
goto $+.7
btfsc bOverrun1 ; Нет ограничения оборотов по функции 1
goto $+.5
btfsc bOverrun2 ; Нет ограничения оборотов по функции 2
goto $+.3
bsf pCOIL ; Включаем катушку зажигания
bcf pCOIL_N
_ExitInterrupt
swapf TmpSTATUS,W ; Восстанавливаем состояние
movwf STATUS
swapf TmpW,F
swapf TmpW,W
retfie
; Start -------------------------------------------------------------------------------------------
;
; Описание: Начало программы, инициализация контроллера и установка в начальное состояние,
; главный цикл программы.
;--------------------------------------------------------------------------------------------------
Start;
#ifdef PIC16F628
movlw 0x07 ; Отключаем компаратор (только PIC16F628)
movwf CMCON
#endif
bsf STATUS,RP0 ; Выбор банка памяти 1
clrf EECON1 ; Очищаем регистр записи/чтения ЭППЗУ
movlw PORTA_IO ; Устанавливаем направление портов (1 - ввод, 0 - вывод)
movwf TRISA
movlw PORTB_IO
movwf TRISB
movlw 0x88 ; Резисторы на PB ВЫКЛючены, делитель на WDT
movwf OPTION_REG
bcf STATUS,RP0 ; Выбор банка памяти 0
movlw PORTA_RESET ; Порты в сброс
movwf PORTA
movlw PORTB_RESET
movwf PORTB
clrf Flags ; Сбрасываем регистры
clrf SectorCnt
clrf LastSectorCnt
clrf SparkTime
clrf CoilCnt_0
clrf CoilCnt_1
clrf CoilOffCnt_0
clrf CoilOffCnt_1
movf PORTB,W ; Выставляем биты состояния портов
andlw SENSOR_MASK | FUNC1_MASK | FUNC2_MASK | SELECT1_MASK | SELECT2_MASK
movwf Ports
#ifdef FUNC1_ENGINE_STOP ; Функция отключения двигателя
btfsc bFunc1_n ; Включена дополнительная функция
goto $+.3
bsf bEngineStop ; Отключаем двигатель
goto $+.2
bcf bEngineStop ; Включаем двигатель
#endif
#ifdef FUNC2_ENGINE_STOP ; Функция отключения двигателя
btfsc bFunc2_n ; Включена дополнительная функция
goto $+.3
bsf bEngineStop ; Отключаем двигатель
goto $+.2
bcf bEngineStop ; Включаем двигатель
#endif
#ifdef MODUL_CONFIG_METAL
btfss pSENSOR ; Проверяем текущее состояние датчика
goto $+.8
#else ; #ifdef MODUL_CONFIG_SPACE
btfsc pSENSOR ; Проверяем текущее состояние датчика инверсно (fix 1.51)
goto $+.8
#endif
; Шторка в датчике
bcf pLED_N ; Включаем светодиод
bsf bLastState ; Обновляем флаг состояния датчика
btfsc bEngineStop ; Если двигатель не остановлен
goto $+.3
bsf pCOIL ; Включаем катушку зажигания
bcf pCOIL_N
goto $+.5
; Шторка вне датчика
bsf pLED_N ; Отключаем светодиод
bcf bLastState ; Обновляем флаг состояния датчика
bcf pCOIL ; Отключаем катушку зажигания
bsf pCOIL_N
movlw TMR_VALUE ; Квантование таймера
movwf TMR0
movlw 0xA0 ; Разрешаем прерывания от TMR0, и прерывания глобально, сбрасываем флаги прерываний
movwf INTCON
_MainLoop
bsf INTCON,T0IE ; Разрешаем прерывания от TMR0
bsf INTCON,GIE ; Разрешаем прерывания глобально
; Счетчик отключения катушки при простое двигателя
incf CoilOffCnt_0,F
btfsc STATUS,Z
incf CoilOffCnt_1,F
movf CoilOffCnt_1,W ; Проверяем счетчик и отключаем катушку
xorlw COIL_OFF_VALUE
btfss STATUS,Z
goto $+.6
bcf INTCON,GIE ; Запрещаем прерывания
bcf pCOIL ; Отключаем катушку (fix 1.51)
bsf pCOIL_N
clrf CoilOffCnt_1 ; Сбрасываем счетчик отключения катушки
bsf bCoilOff ; Выставляем флаг отключения катушки
; Проверяем кнопку дополнительной функции 1
movf PORTB,W
xorwf Ports,W
andlw FUNC1_MASK
btfsc STATUS,Z
clrf Func1Cnt ; Сбрасываем счетчик
incf Func1Cnt,F
btfss STATUS,Z ; Досчитаем до 0
goto $+.3
movlw FUNC1_MASK ; Инвертируем состояние флага
xorwf Ports,F
; Проверяем кнопку дополнительной функции 2
movf PORTB,W
xorwf Ports,W
andlw FUNC2_MASK
btfsc STATUS,Z
clrf Func2Cnt ; Сбрасываем счетчик
incf Func2Cnt,F
btfss STATUS,Z ; Досчитаем до 0
goto $+.3
movlw FUNC2_MASK ; Инвертируем состояние флага
xorwf Ports,F
; Проверяем кнопку выбора УОЗ 1
movf PORTB,W
xorwf Ports,W
andlw SELECT1_MASK
btfsc STATUS,Z
clrf Select1Cnt ; Сбрасываем счетчик
incf Select1Cnt,F
btfss STATUS,Z ; Досчитаем до 0
goto $+.3
movlw SELECT1_MASK ; Инвертируем состояние флага
xorwf Ports,F
; Проверяем кнопку выбора УОЗ 2
movf PORTB,W
xorwf Ports,W
andlw SELECT2_MASK
btfsc STATUS,Z
clrf Select2Cnt ; Сбрасываем счетчик
incf Select2Cnt,F
btfss STATUS,Z ; Досчитаем до 0
goto $+.3
movlw SELECT2_MASK ; Инвертируем состояние флага
xorwf Ports,F
#ifdef FUNC1_ENGINE_STOP ; Функция отключения двигателя
btfsc bFunc1_n ; Включена дополнительная функция
goto $+.3
bsf bEngineStop ; Отключаем двигатель
goto $+.2
bcf bEngineStop ; Включаем двигатель
#endif
#ifdef FUNC1_PROTECT ; Функция защиты
btfsc bFunc1_n ; Включена дополнительная функция
goto $+.11
movf LastSectorCnt,W ; Проверяем обороты вала, если LastSectorCnt > 0
btfsc STATUS,Z
goto $+.8
sublw FUNC1_PROTECT_LIMIT ; При превышении предела оборотов
btfss STATUS,C ; Результат положительный, С = 1 при W < FUNC1_PROTECT_LIMIT
goto $+.5
clrwdt ; Мёртвый цикл, ничего не обслуживаем
bcf INTCON,GIE ; Запрещаем прерывания
bcf pLED_N ; Включаем светодиод
goto $-.3
#endif
#ifdef FUNC1_OVERRUN ; Функция ограничения оборотов
btfsc bFunc1_n ; Включена дополнительная функция
goto $+.9
movf LastSectorCnt,W ; Проверяем обороты вала, если LastSectorCnt > 0
btfsc STATUS,Z
goto $+.7
sublw FUNC1_OVERRUN_LIMIT ; При превышении предела оборотов
btfss STATUS,C ; Результат положительный, С = 1 при W < FUNC1_OVERRUN_LIMIT
goto $+.3
bsf bOverrun1 ; Выставляем флаг превышения оборотов
goto $+.2
bcf bOverrun1 ; Снимаем флаг превышения оборотов
#endif
#ifdef FUNC1_WARMING_SPARK ; Функция прогрева свечей (1.6)
btfss bFunc1_n ; Включена дополнительная функция
btfss bCoilOff ; Этот режим может работать только когда отключена катушка (двигатель остановлен)
goto $+.13
clrf CoilOffCnt_1 ; Сбрасываем счетчик отключения катушки
incf WarmingCnt,F ; Обновляем счётчик
btfss STATUS,Z ; При 0 включаем катушку
goto $+.3
bsf pCOIL ; Включаем катушку зажигания
bcf pCOIL_N
movf WarmingCnt,W ; Проверяем счётчик на отключение катушки
sublw WARMING_COIL_TIME
btfss STATUS,Z
goto $+.3
bcf pCOIL ; Отключаем катушку зажигания
bsf pCOIL_N
; При завершении работы функции катушка будет автоматически отключена
#endif
#ifdef FUNC2_ENGINE_STOP ; Функция отключения двигателя
btfsc bFunc2_n ; Включена дополнительная функция
goto $+.3
bsf bEngineStop ; Отключаем двигатель
goto $+.2
bcf bEngineStop ; Включаем двигатель
#endif
#ifdef FUNC2_PROTECT ; Функция защиты
btfsc bFunc2_n ; Включена дополнительная функция
goto $+.11
movf LastSectorCnt,W ; Проверяем обороты вала, если LastSectorCnt > 0
btfsc STATUS,Z
goto $+.8
sublw FUNC2_PROTECT_LIMIT ; При превышении предела оборотов
btfss STATUS,C ; Результат положительный, С = 1 при W < FUNC2_PROTECT_LIMIT
goto $+.5
clrwdt ; Мёртвый цикл, ничего не обслуживаем
bcf INTCON,GIE ; Запрещаем прерывания
bcf pLED_N ; Включаем светодиод
goto $-.3
#endif
#ifdef FUNC2_OVERRUN ; Функция ограничения оборотов
btfsc bFunc2_n ; Включена дополнительная функция
goto $+.9
movf LastSectorCnt,W ; Проверяем обороты вала, если LastSectorCnt > 0
btfsc STATUS,Z
goto $+.7
sublw FUNC2_OVERRUN_LIMIT ; При превышении предела оборотов
btfss STATUS,C ; Результат положительный, С = 1 при W < FUNC2_OVERRUN_LIMIT
goto $+.3
bsf bOverrun2 ; Выставляем флаг превышения оборотов
goto $+.2
bcf bOverrun2 ; Снимаем флаг превышения оборотов
#endif
#ifdef FUNC2_WARMING_SPARK ; Функция прогрева свечей (1.6)
btfss bFunc2_n ; Включена дополнительная функция
btfss bCoilOff ; Этот режим может работать только когда отключена катушка (двигатель остановлен)
goto $+.13
clrf CoilOffCnt_1 ; Сбрасываем счетчик отключения катушки
incf WarmingCnt,F ; Обновляем счётчик
btfss STATUS,Z ; При 0 включаем катушку
goto $+.3
bsf pCOIL ; Включаем катушку зажигания
bcf pCOIL_N
movf WarmingCnt,W ; Проверяем счётчик на отключение катушки
sublw WARMING_COIL_TIME
btfss STATUS,Z
goto $+.3
bcf pCOIL ; Отключаем катушку зажигания
bsf pCOIL_N
; При завершении работы функции катушка будет автоматически отключена
#endif
goto _MainLoop
; CalculateSparkTime ------------------------------------------------------------------------------
;
; Описание: Вычисление момента искрообразования по таблице в соответствии с измеренным временем
; оборота распредвала.
; Входные параметры: SectorCnt - величина импульса от датчика Холла.
; Выходные параметры: W - момент зажигания от начала импульса в квантах времени.
;--------------------------------------------------------------------------------------------------
CalculateSparkTime;
movf SectorCnt,W ; Проверяем счетчик на допустимые пределы (0 - 239)
sublw .239
btfss STATUS,C
retlw .0 ; Счетчик больше 239, поздним зажигание (0 - не проверяем зажигание)
; Теперь переходим к таблице с вычисляемым переходом
btfsc bSelect1_n
goto $+.8
movlw HIGH Table1 ; Выбрана характеристика 1
movwf PCLATH
movf SectorCnt,W
call Table1
nop
clrf PCLATH
return
btfsc bSelect2_n
goto $+.8
movlw HIGH Table2 ; Выбрана характеристика 2
movwf PCLATH
movf SectorCnt,W
call Table2
nop
clrf PCLATH
return
movlw HIGH TableDefault ; Выбрана характеристика по умолчанию
movwf PCLATH
movf SectorCnt,W
call TableDefault
nop
clrf PCLATH
return
; Таблица 1 ---------------------------------------------------------------------------------------
;
; Характеристика УОЗ 1. Выбирается при SELECT1 = 0 и SELECT2 = 1.
;--------------------------------------------------------------------------------------------------
ORG 0x0100




