;****************************************************************************** ; Filename: Interrupt.Asm * ; Date: * ; File Version: 000.001 * ; Author: PSW.RU * ; Company: Labs * ;****************************************************************************** #include Define.h ;Определения Констант и переменных для модуля global LowInt ;Extern InitAll,HighInt ;****************************************************************************** ;Reset vector ; This code will start executing when a reset occurs. RST code 0x0000 ; RST ; Всего 4 слова до следующего вектора bsf OSCCON,IRCF2,ACCESS ; Тактовая от Внутренний RC до 4 МГц поднять ; Ниже места есть лишь на 2 команды + BRA #ifdef PCPWM_Present ; Глушение IRAMY максимально оперативное для НЕ срабатывания реле зарядки ; Начиная с экземпляра №2А термистр на выводе RA0/An0 вместо RA1/AN1 #ifdef PCPWM_IRAMY ;; Для IRAMX IRAMY разные методы глушения модуля bcf LATA,0,ACCESS ;Чистим выход термистора для отключения реле bcf TRISA,0,ACCESS ;делаем ногу термистора выходом #else ; IRAMX bsf LATA,0,ACCESS ;Ставим выход термистора для отключения реле bcf TRISA,0,ACCESS ;делаем ногу термистора выходом #endif; #ifdef PCPWM_IRAMY ; #endif; #ifdef PCPWM_Present bra AfterIntVectors ;Промежуточный кусочек с командами требующими наиболее быстрого выполнения ; при сбросе ; goto InitAll ;go to start of main code HiInt code 0x0008 ; Всего 8 слов до след вектора ; самое капризное по изохронности btfsc INTCON,TMR0IF,ACCESS; Таймер0 - используется для задержек 1-Wire модуля bra IntTimer0 ; Только 2 высоко приоритетных прерывания - доп экономия сверхкороткого кода bcf PIR3,PTIF,ACCESS ; PCPWM #ifdef PCPWM_Present ; ; btfsc W_1_Flg,5,ACCESS;5=Промежуточный флаг запроса времени проца основного цикла - синхро с ШИМ ; bsf W_1_Flg,0,ACCESS; Модуль 1-Wire требует проца, цепка прерываний завершена, очередь фона 1-W, #endif ; #ifdef PCPWM_Present ; retfie FAST; ; Между 0x18 и 0x08 помещается 8 однословных команд ; Сейчас иcпользовано 5, 3 в запасе. ; Можно добавить ещё 1 обработчик и расширение таймера до 32 бит либо ; переход на опрос других флагов bra 0x0 ; Проверка bra 0x0 ; вычисления bra 0x0 ; запаса bra 0x0 ; команд LowInt code 0x0018 ; #ifdef DelayCuriosityTest ; 07/03/2020 сделал общую опцию bcf PIR1,ADIF,ACCESS ; ADC Flag Clear максимально шустро #endif ; #ifdef DelayCuriosityTest bra IntAdc ; global AfterIntVectors ; Сюда Bra после ресета Extern InitAll AfterIntVectors clrwdt ; Собака 4 мс - покусывает, реально 4+ мс movlf b'01110000',OSCCON,ACCESS ; Тактовую до 8 МГц поднять #ifdef PCPWM_Present ITRIP_Stop ; Вывод ITRIP в состояние отключения модуля PWM #endif ; #ifdef PCPWM_Present goto InitAll ;go to start of main code IntTimer0: bcf INTCON,TMR0IF,ACCESS; Сбрасываем флаг Таймера0 ; bcf T0CON,TMR0ON,ACCESS ; Гасим таймер #ifdef Timer0_Present #include Proj_Dir\1W\Int_1W.inc ;обработка во включаемом файле. #endif ;#ifdef Timer0_Present retfie FAST ;; Затычка #ifdef Beeper_Present Beeper_Sub #ifdef Beeper_Tone ; Усовершенствованный бипер тут должен быть tstfsz Beep,ACCESS ; Быстрая Beeper_Toggle ; и синхронная tstfsz Beep,ACCESS ; последовательность decf Beep,F,ACCESS; бипера #endif ;#ifdef Beeper_Tone return ; #endif ;#ifdef Beeper_Present ; Low priority interrupt vector and routine ; This code will start executing when a low priority interrupt occurs. ; This code can be removed if low priority interrupts are not used. LowInt: ;Единственное - АЦП, длинное и непредсказуемое IntAdc: ; Вобрало в себя АЦП, РТК и вращение счётчика PCPWM movff WREG,WREG_TEMP ;save working register movff STATUS,STATUS_TEMP ;save STATUS register movff BSR,BSR_TEMP ;save BSR register ; movff FSR0L,FSR0L_Temp ;Пока не используется ; movff FSR0H,FSR0H_Temp ;Пока не используется movff TBLPTRL,TBLPTRL_Temp ; movff TBLPTRH,TBLPTRH_Temp ; ; movff TBLPTRU,TBLPTRU_Temp ;Пока не используется ; movff EECON1,EECON1_Temp ; Проверяю Глюку с сохранением movff TABLAT,TABLAT_Temp ; movff PRODH,PRODH_Temp ; movff PRODL,PRODL_Temp ; AdcIntNest ; Повторная обработка без потерь времени на сохранение контекста ; примерно 0,6 МИПС уходит на сохранение/восстановление контекста с частотой 18 750 Гц. ; примерно 0,8 МИПС уходит на сохранение/восстановление контекста с частотой 24 414 Гц. ; Однако ~2 МИПСа мы получаем от "разгона" до 12 - 12.5 МГц. #ifndef DelayCuriosityTest ; 07/03/2020 сделал общую опцию bcf PIR1,ADIF,ACCESS ; ADC Flag Clear здесь если без теста для общего убыстрения #endif ; #ifndef DelayCuriosityTest #ifdef ADC_Present #ifdef Beeper_Tone tstfsz Beep,ACCESS ; Количество телепаний - завершено ? rcall Beeper_Sub; Быстрая изохронная сабпрога #endif ; #ifdef Beeper_Tone #ifndef __DEBUG_;******* Разгрузка отладчика #include Proj_Dir\ADC\Int_ADC.inc ; пересылка буферов во включаемом файле. #endif ;#ifndef __DEBUG_; #ifdef RTK_ADC_Source #include Proj_Dir\RTK\Int_RTK_Tmr.inc ; прерывания АЦП - Источник реального времени #endif ; #ifdef RTK_ADC_Source #ifdef PCPWM_Present PDC_Int_Begin #include Proj_Dir\PCPWM_3F\Int_PCPWM_3F_4431.inc ; Эмулятор вращения короткий dcfsnz PCPWM_AccelCounter,F,ACCESS; Счетчик Делителя частоты для плавного пуска/останова bsf PCPWM_Flag,5,ACCESS ;;5= Запрос на обработку из 9 375 прерывания АЦП, при обнулении делителя BSF EECON1, EEPGD,ACCESS ; Point to PROGRAM memory #ifndef __DEBUG;******* Разгрузка отладчика ; Extern PCPWM_Task ; call PCPWM_Task ; сабпрога, длинная и долгая. #ifdef PCPWM_3H ; 07/03/2020 добавил опцию #include Proj_Dir\PCPWM_3F\Int_PCPWM_3H_x431.inc ; фазные вычислители с 3 гармоникой проба на зуб. #else ;#ifdef PCPWM_3H ; #include Proj_Dir\PCPWM_3F\Int_PCPWM_3F_x431.inc ; фазные вычислители прежние для отладки. #endif;#ifdef PCPWM_3H ; #ifdef DelayCuriosityTest ; 07/03/2020 сделал общую опцию Extern DelayCuriosity ; отключаемую перед внедрением call DelayCuriosity ; Исследование запаса по быстродействию обработчика #endif ; #ifdef DelayCuriosityTest #endif ; #ifndef __DEBUG_;******* Разгрузка отладчика PDC_Int_End #endif ; #ifdef PCPWM_Present #endif ; #ifdef ADC_Present #ifdef DelayCuriosityTest ; 07/03/2020 сделал общую опцию btfss PIR1,ADIF,ACCESS; ADC bra ExitLoInt bcf PIR1,ADIF,ACCESS ; ADC Flag Clear #ifdef PCPWM_Present incf PCPWM_Err,F,ACCESS ; Счетчик ошибок увеличиваем #endif ; #ifdef PCPWM_Present #else ; #ifdef DelayCuriosityTest ; btfsc PIR1,ADIF,ACCESS; ADC ; Флаг чистится в начале прерывания #endif ; #ifdef DelayCuriosityTest ; goto AdcIntNest ; Повторный вход в прерывание с экономией времени на сохранение контекста ;; rcall IntAdc ExitLoInt ; Малозначимые вещи которые можно пропустить при повторном входе в прерывание #ifdef PCPWM_Present btfss PCPWM_Flag2,0,ACCESS;;0= Признак необходимости синхронизации частоты ШИМ rcall PDC_TableLoad ; Суммарные потери времени меньше от сабпроги btfss PCPWM_Flag2,1,ACCESS;1= Признак необходимости синхронизации слагаемых угла смещения фазы rcall Angle_TableLoad ; Суммарные потери времени меньше от сабпроги #endif ; #ifdef PCPWM_Present ; movff FSR0L_Temp,FSR0L ;variable used for context saving ; movff FSR0H_Temp,FSR0H ;variable used for context saving movff TBLPTRL_Temp,TBLPTRL ; movff TBLPTRH_Temp,TBLPTRH ; ; movff TBLPTRU_Temp,TBLPTRU ; ; movff EECON1_Temp,EECON1 ; Проверяю Глюку с сохранением movff TABLAT_Temp,TABLAT ; movff PRODH_Temp,PRODH ; movff PRODL_Temp,PRODL ; movff BSR_TEMP,BSR ;restore BSR register movff WREG_TEMP,WREG ;restore working register movff STATUS_TEMP,STATUS ;restore STATUS register retfie global PDC_TableLoad PDC_TableLoad ; Загрузка множителей частоты ШИМ bsf PCPWM_Flag2,0,ACCESS;;0= Признак необходимости синхронизации частоты ШИМ #include Proj_Dir\PCPWM_3F\PDC_TableLoad.inc;Загрузка таблиц вынес для удобства return Angle_TableLoad ; bsf PCPWM_Flag2,1,ACCESS;1= Признак необходимости синхронизации слагаемых угла смещения фазы #include Proj_Dir\PCPWM_3F\Angle_TableLoad.inc;Загрузка углов смещения вынес для удобства return ; ; #ifdef Timer1_Present ; btfss PIR1,TMR1IF,ACCESS ; 1-10 КГц ШИМ модулятор DC мотора ; bra NextInt1 ; btfsc PIE1,TMR1IE,ACCESS ; Прерывания разрешены ? ; rcall IntTmr1 ; #endif ;NextInt1 ; ; #ifdef IntPortB_Present ; btfss INTCON,RBIF,ACCESS ; ПортБ - надо опрашивать по Таймеру1 10 раз в сек ; bra NextInt2 ; btfsc INTCON,RBIE,ACCESS ;; Прерывания разрешены ? ; rcall IntPortB ; #endif ;NextInt2 ; ; #ifdef Timer5_Present ; btfss PIR3,TMR5IF,ACCESS ; флаг TMR5 есть ? ; bra NextInt3 ; ; btfsc PIE3,TMR5IE,ACCESS ; Прерывания разрешены ? ; rcall IntTmr5 ;bra Int_Timer2 ; ; #endif ;NextInt3 ; ;; #ifdef ADC_Present ;; btfss PIR1,ADIF,ACCESS ; ADC ;; bra NextInt4 ;; btfsc PIE1,ADIE,ACCESS ; Прерывания разрешены ? ;; rcall IntAdc ;; #endif ;;NextInt4 ;; ;; #ifdef PCPWM_Present ;; btfss PIR3,PTIF,ACCESS ; PCPWM ;; bra NextInt5 ;; btfsc PIE3,PTIE,ACCESS ; Прерывания разрешены ? ;; rcall IntPWM ;; #endif ;;NextInt5 ;; ;; #ifdef Timer0_Present ;; btfss INTCON,TMR0IF,ACCESS ; Таймер0 - используется для задержек 1-Wire модуля ;; bra NextInt0 ;; btfsc INTCON,TMR0IE,ACCESS ; Прерывания разрешены ? ;; rcall IntTmr0 ;; #endif ;;NextInt0 ;; ; ;IntPWM ; Заглушка случайно возникшего прерывания ; bcf PIR3,PTIF,ACCESS ; PWM Flag Clear ; #ifdef PCPWM_Present ;;FAST #include Proj_Dir\PCPWM_3F\Int_PCPWM_3F_4431.inc ;; Обработчик во включаемом файле. ; #endif ; return ; ;IntAdc ; Заглушка случайно возникшего прерывания ; bcf PIR1,ADIF,ACCESS ; ADC Flag Clear ; #ifdef ADC_Present ; #ifdef RTK_ADC_Source ;;FAST #include Proj_Dir\RTK\Int_RTK_Tmr.inc ; прерывания АЦП - Источник реального времени ; #endif ;;FAST #include Proj_Dir\ADC\Int_ADC.inc ; перекачка буферов во включаемом файле. ; #endif ; return ;IntTmr0 ; bcf INTCON,TMR0IF,ACCESS ;; Сбрасываем флаг Таймера0 ;; bcf T0CON,TMR0ON,ACCESS ; Гасим таймер ; #ifdef Timer0_Present ;; FAST #include Proj_Dir\1W\Int_1W.inc ;обработка во включаемом файле. ; #endif ; return ;IntTmr1 ; Таймер-1 - источник реального времени 1 КГц. ; bcf PIR1,TMR1IF,ACCESS ; Timer1 Flag Clear ; #ifndef RTK_ADC_Source ; #include Proj_Dir\RTK\Int_RTK_Tmr.inc ; Источник реального времени в таймере-1 ; #endif ; return ;IntTmr5: ; bcf PIR3,TMR5IF,ACCESS ; Прерывание флаг сброс ; #ifdef Timer5_Present ; #include Proj_Dir\Int_Tmr5.inc ;обработка во включаемом файле. ; #endif ; return ;IntPortB ; ПортБ - надо опрашивать по Таймеру1 10 раз в сек ; movf PORTB,W,0 ;Читаем для сброса условия прерывания ; bcf INTCON,RBIF,0 ;сброс флага прерывания ; #ifdef IntPortB_Present ; andlw b'11100000' ;Оставляем только входы ПортБ ; movwf PortB_Buf,0 ;Форматер экрана не могет прочитать напрямую ПортБ ; bsf TaskFlag1,1,ACCESS ; Флаг PortB выставлен в прерывании PortB ; #include Proj_Dir\Int_Encoder.inc> ;обработка Encod во включаемом файле. ; #endif ; return ;HighInt code 0x100 ; Выравнен к секции с нулевым младшим байтом адреса для быстрого вычисляемого перехода ;addwf PCL,F,0 ; Чтение-Модификация-запись PCL. Защёлки U и H НЕ присваиваются сами при чтении ; Выгодно иметь 1 или 2 никогда не запрещаемых высокоскоростных часто происходящих прерывания ; Упрощение обработчика - ускоряет процесс/минимизирует накладные потери. ; Чаще или НЕ чаще - вопрос точности ШИМ, 11.7 или 23.4 КГц IntPWM ; Заглушка случайно возникшего прерывания ; btfss PIR3,PTIF,ACCESS ; PWM Flag Clear ; bra HiNextInt1 bcf PIR3,PTIF,ACCESS ; PWM Flag Clear retfie ;FAST ; Затычка ;;End of program END