;Include for: PCPWM_3F_4431.asm ;SpeedChange ; Реализация плавного старт/стопа двигла и останова/пуска PCPWM модуля ; Выполняется 18 750/PCPWM_Accelerate Гц - регулируемая частота PCPWM_Accelerate,PCPWM_AccelCounter ; Возможные состояния моста синтезатора: ; 1. Полный останов, вывод термистора=1 выход, разрыв всех ключей, размыкание зарядного реле ; 2. Останов, нижние ключи замкнуты, зарядка кондёров верхних ключей ; 3. Вращение поля, плавное изменение скорости вращения поля в соответствии с указанным ускорением ; Внешние сабпроги StopMotor и FullStopMotor могут вызываться в любой момент из любой ветки кода ; При вызове - автомат изменения скорости ждёт обязательное время выбега, ; ждёт нажатия кнопы, приводит состояние всех флагов к состоянию 1, ; Кнопа старт/стоп меняет лишь бит PCPWM_Flag,3,ACCESS ;Бит старт/стоп ; и копирует задатчик скорости в скорость работы при старте ; Заменяю PCPWM_SpeedStop на PCPWM_WorkSpeed для понятности и контроля переделки алго ; Заменяю PCPWM_Speed на PCPWM_Speed_M0/PCPWM_Speed_M1 для реализации 2х ячеек памяти movff PCPWM_Accelerate,PCPWM_AccelCounter; Начальное значение счётчика времени ускорения PCPWM_Page ; BSR for PCPWM Task bcf PCPWM_Flag,5,ACCESS ;;5= Запрос на обработку из 9 375 прерывания АЦП, при обнулении делителя movf PCPWM_SpCh_Route,W,BANKED ; bz SpCh_R0 ; 0. Аварийный останов, в том числе подача питания. dcfsnz WREG,W,ACCESS bra SpCh_R1 ; 1. Однократный Вкл АЦП модуля, Ожидание тайм-аута после аварийного останова. dcfsnz WREG,W,ACCESS bra SpCh_R2 ; 2. Мотор остановлен, синтезатор заглушен, реле зарядки разомкнуто, dcfsnz WREG,W,ACCESS bra SpCh_R3 ; 3. ждём тайм-аут 0.1 сек зарядки конденсаторов сдвига, dcfsnz WREG,W,ACCESS bra SpCh_R4 ; 4. ждём соблюдения условия температуры IRAMX меньше указанного порога, ; dcfsnz WREG,W,ACCESS bra SpCh_R5 ; 5. Инкремент/Декремент/Поддержание скорости поля в соответствии с раб скоростью задания, ; dcfsnz WREG,W,ACCESS ; bra SpCh__R6 ; 6. Нулевая реальная скорость поля достигнута после нажатия кнопы стоп. SpCh_R0 ; 0. Аварийный останов, в том числе подача питания, перезагруз АЦП ;******* bcf ADCON0,ADON,ACCESS ;Гасим АЦП - сброс АЦП на всяк случай ; Дублируем останов на всяк случай ;3 Аналог Вход 1 Термистор IRAMX вход 0-5 вольт RA1/AN1 bsf LATA,1,ACCESS ;Ставим выход термистора bcf TRISA,1,ACCESS ;делаем вход термистора выходом call StopMotor ; OverRide PWM bcf PCPWM_Flag,3,ACCESS ;;3= Старт/Стоп bcf PCPWM_Flag,4,ACCESS ;;4= Left/Right bcf PCPWM_Flag1,0,ACCESS;;0= Редактирование "ускорения", многократный цикл торможение-реверс-разгон-. bcf PCPWM_Flag1,4,ACCESS;;4= Однократный останов-реверс-разгон bcf PCPWM_Flag1,5,ACCESS;;5= Контроль термистора/тока в обработчике АЦП (установлен при нормальной работе мотора) ; movf PCPWM_Alarm_Route,W,BANKED ;Указатель вида аварийного останова ; bz Alarm_R0 ; 0. подача питания, PowerOnReset. ; dcfsnz WREG,W,ACCESS ; bra Alarm_R1 ; 1. ОверТок, ОверНапруга, ОверТемпература, Кусание собаки. ; ;Alarm_R0 ; 0. подача питания, PowerOnReset. movff Tic_10_Counter,Alarm_DelayStamp ; Засечка времени задержки incf PCPWM_SpCh_Route,F,BANKED ; След шаг "проги" ;******* bsf ADCON0,ADON,ACCESS ;Заводим АЦП после перестраховочного сброса retlw 0x01 ; Переход через опрос остальных событий SpCh_R1 ; 1. Ожидание тайм-аута после аварийного останова, сброс событий нажатий клавы. bcf PCPWM_Flag1,1,ACCESS;;1= Нажата Кнопа Старт/Стоп bcf PCPWM_Flag1,4,ACCESS;;4= Однократный останов-реверс-разгон movf PCPWM_Alarm_Route,W,BANKED ;Указатель вида аварийного останова, присваивается в неизвестном месте bz Alarm_R10 ; 0. подача питания, PowerOnReset. ; Все остальные случаи пока что обрабатываются без разбора ; dcfsnz WREG,W,ACCESS ; bra Alarm_R11 ; 1. ОверТок, ОверНапруга, ОверТемпература, Кусание собаки. WaitTimeL d'20',Tic_10_Counter,ACCESS,Alarm_DelayStamp,BANKED,0xD1 bra DoneWait Alarm_R10 ; 0. подача питания, PowerOnReset. bcf PCPWM_Flag,4,ACCESS ;;4= Left/Right WaitTimeL d'5',Tic_10_Counter,ACCESS,Alarm_DelayStamp,BANKED,0xD2 bra DoneWait DoneWait incf PCPWM_SpCh_Route,F,BANKED ; След шаг "проги" retlw 0x02 ; Переход через опрос остальных событий SpCh_R2 ; 2. Мотор остановлен, синтезатор заглушен, реле зарядки разомкнуто, ;Ждём условий НЕ превышения общего тока шины некоторого порога ; и НЕ занижения напруги шины некоторого порога #ifndef __DEBUG;******* Разгрузка отладчика - контроль отключён movff ADC_Out+5,WREG ; Старший байт 16 бит общего тока sublw PCPWM_StartCurrent; вычесть WREG from Literal btfss _C ; Инверсный заём для вычитания retlw 0x03 ; Ток слишком высокий - ждём снижения movff ADC_Out+7,WREG ; Старший байт 16 бит напряжения шины ; sublw PCPWM_StartVoltage; вычесть WREG from Literal subwf Par_UV,W,BANKED ;; Порог Нижнего Напряжения шины перед замыканием реле btfsc _C ; Инверсный заём для вычитания retlw 0x04 ; Напряжение шины слишком низкое - ждём повышения #endif ; Выбор целевой скорости запуска двигла в зависимости от условий - кнопа или подача питания btfsc PCPWM_Flag1,3,ACCESS;3= 0=однократный Старт по подаче питания 50 Гц, ставится при обнаружении нажатия кнопы старт/стоп bra SpCh_R2_KeyWait movlf 0x80,PCPWM_WrkSpdBuf,BANKED; Заносим 50 Гц в буфер регулировки раб скорости bra SpCh_R2_Next ;Обработка нажатий кноп старт/стоп при старте из состояния останова SpCh_R2_KeyWait #ifdef __DEBUG;******* Разгрузка отладчика btfss PORTE,1,ACCESS ;Кнопа старт/стоп;1= Анализ флага "Нажата Кнопа Старт/Стоп" #else btfss PCPWM_Flag1,1,ACCESS;1= Анализ флага "Нажата Кнопа Старт/Стоп" #endif ; btfss PCPWM_Flag1,1,ACCESS;1= Нажата Кнопа Старт/Стоп retlw 0x05 ; ждём нажатия кнопы ; Загрузка ячейки памяти в буфер скорости по старту - не нужна ? ; Нужна - ибо как иначе организовать более 1 ячейки памяти ? ; Можно заменить на сохранение вместо восстановления - тогда разруливается. ; movff PCPWM_Speed_M1,PCPWM_WrkSpdBuf ; Первая ячейка памяти movff PCPWM_WrkSpdBuf,PCPWM_Speed_M0; Спасаем скорость в Нулевая ячейка памяти bsf LCD_Flg1,0,ACCESS ; Флаг необходимости синхронизировать ЕПРОМ и ОЗУ btfss PCPWM_Flag1,2,ACCESS;2= Номер нажатой кнопы Старт/Стоп bra Start_0_Pressed ; movff PCPWM_Speed_M0,PCPWM_WrkSpdBuf ; Нулевая ячейка памяти movlf 0x80,PCPWM_WrkSpdBuf,BANKED; Заносим 50 Гц в буфер регулировки раб скорости bcf PCPWM_Flag1,3,ACCESS;3= 0=однократный Старт по подаче питания 50 Гц, ставится при обнаружении нажатия кнопы старт/стоп Start_0_Pressed ; Спасение буфера скорости в ячейке памяти при пуске кнопой. ; btfss PCPWM_Flag1,2,ACCESS;2= Номер нажатой кнопы Старт/Стоп ; btfsc PCPWM_Flag1,2,ACCESS;2= Номер нажатой кнопы Старт/Стоп ; movff PCPWM_WrkSpdBuf,PCPWM_Speed_M1; Спасаем скорость в Первая ячейка памяти ;*************** SpCh_R2_Next ; Установка флагов работы двигла ;3 Аналог Вход 1 Термистор IRAMX вход 0-5 вольт RA1/AN1 bcf LATA,1,ACCESS ;чистим выход термистора bcf PCPWM_Flag1,1,ACCESS;1= Сброс флага "Нажата Кнопа Старт/Стоп" bsf TRISA,1,ACCESS ;делаем выход термистора входом bsf PCPWM_Flag,3,ACCESS;;3= Старт/Стоп bsf PCPWM_Flag,6,ACCESS;6= Ставим флаг RealStop PCPWM Module - после остановки поля для снижения выделения тепла movlf 0x1,PCPWM_SpeedReal,BANKED;Реальная скорость вращения поля синтезатора=1 на всяк случай. ; Оверрайд выходов в положение "нижние замкнуть" для заряда кондёров сдвига уровня PCPWM модуля clrf OVDCONS,ACCESS ; НЕ активное состояние определяем при оверрайде movlw b'11000000' ; Чистим нижние 6 andwf OVDCOND,F,ACCESS incf PCPWM_SpCh_Route,F,BANKED ; След шаг "проги" movff Tic_10_Counter,Alarm_DelayStamp ; Засечка времени задержки retlw 0x06 ; Переход через опрос остальных событий SpCh_R3 ; 3. ждём тайм-аут 0.1 сек зарядки конденсаторов сдвига, WaitTimeL d'2',Tic_10_Counter,ACCESS,Alarm_DelayStamp,BANKED,0xD3 incf PCPWM_SpCh_Route,F,BANKED ; След шаг "проги" retlw 0x07 ; Переход через опрос остальных событий SpCh_R4 ; 4. ждём соблюдения условия температуры IRAMX меньше указанного порога, movff ADC_Out+3,WREG ; Старший байт 16 бит напруги термистора sublw PCPWM_StartTermistor; вычесть WREG from Literal btfss _C ; Инверсный заём для вычитания retlw 0x08 ; Термистор слишком горячий - ждём снижения ;Запуск PCPWM модуля movlw b'111111' ; Ставим нижние 6 выходов iorwf OVDCOND,F,ACCESS ; Управление от ШИМ bcf PCPWM_Flag1,1,ACCESS;1= Сброс флага "Нажата Кнопа Старт/Стоп" clrf PCPWM_Alarm_Route,BANKED ; Чистим код ошибки incf PCPWM_SpCh_Route,F,BANKED ; След шаг "проги" retlw 0x09 ; Переход через опрос остальных событий SpCh_R5 ; 5. Инкремент/Декремент/Поддержание скорости поля в соответствии с раб скоростью задания, #ifdef __DEBUG;******* Симулирование кнопы для отладчика btfss PORTE,1,ACCESS ;Кнопа старт/стоп;1= Анализ флага "Нажата Кнопа Старт/Стоп" #else btfss PCPWM_Flag1,1,ACCESS;1= Анализ флага "Нажата Кнопа Старт/Стоп" #endif bra StopKeyNotPressed btfsc PCPWM_Flag1,3,ACCESS;3= 0=однократный Старт по подаче питания 50 Гц, ставится при обнаружении нажатия кнопы старт/стоп bra SecondTimeStopKeyPressed bsf PCPWM_Flag1,3,ACCESS;3= 0=однократный Старт по подаче питания 50 Гц, ставится при обнаружении нажатия кнопы старт/стоп bcf PCPWM_Flag1,1,ACCESS;Сброс флага "Нажата Кнопа Старт/Стоп" ; Загрузка ячейки памяти в буфер скорости при первом нажатии кнопы после подачи питания ; movff PCPWM_Speed_M1,PCPWM_WrkSpdBuf ; Первая ячейка памяти ; btfss PCPWM_Flag1,2,ACCESS;2= Номер нажатой кнопы Старт/Стоп movff PCPWM_Speed_M0,PCPWM_WrkSpdBuf ; Нулевая ячейка памяти bra StopKeyNotPressed SetStandartSpeed bcf PCPWM_Flag1,3,ACCESS;3= 0=однократный Старт по подаче питания 50 Гц, ; ставится при обнаружении нажатия кнопы старт/стоп №0, чистится при №1 movlf 0x80,PCPWM_WrkSpdBuf,BANKED; Заносим 50 Гц в буфер регулировки раб скорости bra StopKeyNotPressed SecondTimeStopKeyPressed bcf PCPWM_Flag1,1,ACCESS;Сброс флага "Нажата Кнопа Старт/Стоп" movff PCPWM_WrkSpdBuf,PCPWM_Speed_M0; Спасаем скорость в Нулевая ячейка памяти bsf LCD_Flg1,0,ACCESS ; Флаг необходимости синхронизировать ЕПРОМ и ОЗУ btfsc PCPWM_Flag1,2,ACCESS;2= Номер нажатой кнопы Старт/Стоп bra SetStandartSpeed ;movff PCPWM_WrkSpdBuf,PCPWM_Speed_M1; Спасаем скорость в Первая ячейка памяти bcf PCPWM_Flag,3,ACCESS ;Бит старт/стоп в останов bcf PCPWM_Flag1,4,ACCESS; Чистка флага ;4= Однократный останов-реверс-разгон clrf PCPWM_WorkSpeed,BANKED; Обнуляем рабочую скорость StopKeyNotPressed bsf PCPWM_Flag1,5,ACCESS;;5= Контроль термистора/тока в обработчике АЦП (установлен при нормальной работе мотора) ; синхронизируем буфер и рабочую в одном месте btfsc PCPWM_Flag1,4,ACCESS;4= Однократный останов-реверс-разгон bcf PCPWM_Flag,3,ACCESS ;Бит старт/стоп чистим при однократном старт-стопе btfss PCPWM_Flag,3,ACCESS ;Бит старт/стоп bra SpdStop movff PCPWM_WrkSpdBuf,PCPWM_WorkSpeed;,W,BANKED; Копия задатчика скорости для старт/стопа. #ifdef LCD_Work_Present btfss LCD_Flg1,3,ACCESS ; Флаг 0=служебный/рабочий проверяем movff PCPWM_Speed,PCPWM_WorkSpeed;,W,BANKED; Копия задатчика скорости для старт/стопа. #endif bra SpdRun ; Закончили выбор рабочей скорости синтезатора SpdStop clrf PCPWM_WorkSpeed,BANKED; Обнуляем рабочую скорость для реверса SpdRun movf PCPWM_SpeedReal,W,BANKED;Реальная скорость вращения поля синтезатора. cpfseq PCPWM_WorkSpeed,BANKED; Копия задатчика скорости для старт/стопа. bra SpeedNoEq; Не равны скорости btfss _Z ; Статус Z определён парой строк выше bra StopAfterRun ;return ; Скорости равны, но НЕ нулевые ; Нулевая реальная скорость поля, равная рабочей btfsc PCPWM_Flag1,0,ACCESS; Выставлен флаг "Циклер Старт-Стоп" bra RunAfterStop btfsc PCPWM_Flag1,4,ACCESS; Выставлен флаг ;4= Однократный останов-реверс-разгон bra RunAfterStop btfsc PCPWM_Flag,6,ACCESS;6= RealStop PCPWM Module - после остановки поля для снижения выделения тепла bra StopMotor ; Остановка мотора без цикловых флагов btfsc PCPWM_Flag,3,ACCESS ;Бит старт/стоп retlw 0x10 ; Останов без нажатия кнопы "стоп" bcf PCPWM_Flag1,5,ACCESS;;5= Контроль термистора/тока в обработчике АЦП (установлен при нормальной работе мотора) ; Остановка вращения поля по кнопе "стоп" достигнута ; Отключение модуля через OVERTEMP bsf LATA,1,ACCESS ;Ставим выход термистора bcf TRISA,1,ACCESS ;делаем вход термистора выходом movff Tic_10_Counter,Alarm_DelayStamp ; Засечка времени задержки clrf PCPWM_Alarm_Route,BANKED ;Указатель вида аварийного останова=как по подаче питания movlf 0x1,PCPWM_SpCh_Route,BANKED ; В первый шаг "проги" - ждать 1.5 сек retlw 0x11 ; через основной циклер ;************ MotorFault ; сабпрога аварийного максимально быстрого затыкания PWM модуля и IRAMX ;Вызывается ХЗ откуда, страницу не портит, в раб реге - номер источника аварии ;************ bsf LATA,1,ACCESS ;Ставим выход термистора bcf TRISA,1,ACCESS ;делаем вход термистора выходом bsf PCPWM_Flag1,3,ACCESS;3= 0=однократный Старт по подаче питания 50 Гц, ставится при обнаружении нажатия кнопы старт/стоп bcf PCPWM_Flag,3,ACCESS ;;3= Старт/Стоп bcf PCPWM_Flag1,0,ACCESS;;0= Редактирование "ускорения", многократный цикл торможение-реверс-разгон-. bcf PCPWM_Flag1,4,ACCESS;;4= Однократный останов-реверс-разгон bcf PCPWM_Flag1,5,ACCESS;;5= Контроль термистора/тока в обработчике АЦП (установлен при нормальной работе мотора) infsnz WREG,F,ACCESS ; setf WREG,ACCESS ; movff WREG,PCPWM_Alarm_Route; clrf WREG,ACCESS ; В начало проги состояний мотора без порчи банков movff WREG,PCPWM_SpCh_Route ; В начало проги состояний мотора Beeper 0xA0 ; Голос ;Количество телепаний 500 Гц ; return ; После неё отрабатывает Переназначение выходов PWM StopMotor: bcf PCPWM_Flag,6,ACCESS;6= RealStop PCPWM Module - после остановки поля для снижения выделения тепла ; **** Однократный Останов PCPWM модуля clrf OVDCONS,ACCESS ; НЕ активное состояние определяем при оверрайде movlw b'11000000' ; Чистим нижние 6 andwf OVDCOND,F,ACCESS ; clrf OVDCOND,ACCESS ; Активен низкий уровень, Оверрайд в ; Запрограммировать задержку 1 сек retlw 0x12 ; Останов сделан RunAfterStop ; Циклер Старт-Стопа btg PCPWM_Flag,4,ACCESS ;Бит прямо/реверс - только в останове bcf PCPWM_Flag1,4,ACCESS; Чистка флага ;4= Однократный останов-реверс-разгон ; movff PCPWM_Speed_M1,PCPWM_WorkSpeed ; Первая ячейка памяти ; btfss PCPWM_Flag1,2,ACCESS;2= Номер нажатой кнопы Старт/Стоп ; movff PCPWM_Speed_M0,PCPWM_WorkSpeed ; Нулевая ячейка памяти movff PCPWM_WrkSpdBuf,PCPWM_WorkSpeed;,W,BANKED; Копия задатчика скорости для старт/стопа. bsf PCPWM_Flag,3,ACCESS ;Бит старт/стоп retlw 0x13 StopAfterRun; Скорости равны, но НЕ нулевые btfss PCPWM_Flag1,0,ACCESS; Выставлен флаг "Циклер Старт-Стоп" retlw 0x14 bcf PCPWM_Flag,3,ACCESS ;Бит старт/стоп для НЕ синхронизации буфера и рабочей скорости ; ***** Временно отключил сохранение буфера в ячейке - нет необходимости ; btfss PCPWM_Flag1,2,ACCESS;2= Номер нажатой кнопы Старт/Стоп ; movff PCPWM_WrkSpdBuf,PCPWM_Speed_M0; Спасаем скорость в Нулевая ячейка памяти ; btfsc PCPWM_Flag1,2,ACCESS;2= Номер нажатой кнопы Старт/Стоп ; movff PCPWM_WrkSpdBuf,PCPWM_Speed_M1; Спасаем скорость в Первая ячейка памяти clrf PCPWM_WorkSpeed,BANKED; Обнуляем рабочую скорость retlw 0x15 SpeedNoEq; Не равны скорости movf PCPWM_SpeedReal,W,BANKED btfss _Z ; Статус Z определён в movf PCPWM_SpeedReal,W,BANKED bra MotorRunning btfsc PCPWM_Flag,6,ACCESS;6= RealStop PCPWM Module - после остановки поля для снижения выделения тепла bra MotorRunning bsf PCPWM_Flag,6,ACCESS;6= RealStop PCPWM Module - после остановки поля для снижения выделения тепла ;***** Однократный Запуск PCPWM модуля movlw b'111111' ; Ставим нижние 6 выходов iorwf OVDCOND,F,ACCESS ; MotorRunning cpfsgt PCPWM_WorkSpeed,BANKED; Реальная скорость вращения поля синтезатора. bra SpeedDec ; cpfsgt PCPWM_WorkSpeed,BANKED; Реальная скорость вращения поля синтезатора. ; bra SpeedInc SpeedInc; 0 не пересекем infsnz PCPWM_SpeedReal,F,BANKED; Реальная скорость вращения поля синтезатора. setf PCPWM_SpeedReal,BANKED; Реальная скорость вращения поля синтезатора. retlw 0x16 SpeedDec; FF не пересекем decf PCPWM_SpeedReal,F,BANKED; Реальная скорость вращения поля синтезатора. btfss _C ; Переполнение было ? clrf PCPWM_SpeedReal,BANKED; Реальная скорость вращения поля синтезатора=0. retlw 0x17