Вы находитесь на странице: 1из 14

2-2/9. Предварительное уменьшение инерционности срабатывания защиты.

Организация, в режиме выключенной защиты, второго сценария-помощника


(подсказки).

Программа, о которой пойдет речь (черновик №6), называется BP_6.asm (прилагается).

Теперь можно уменьшить наихудшую инерционность срабатывания защиты.


Сколько было?
250 мкс.
Каково наихудшее время отработки ПП прерывания?
Не более 170 мкс. (можете поработать с секундомером).
Вывод: инерционность защиты можно смело уменьшить до 200 мкс.
Можно и ниже, но пока не буду. Успеется.
В подобных случаях, окончательное решение лучше принимать на конечной стадии
работы. Значит:

;********************************************************************************
; НАЧАЛО ИСПОЛНЕНИЯ ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
START
....................................
....................................
movlw .199 ; Задание константы периода ухода в
movwf PR2 ; прерывания =.199 {было .249}
; (F = 5 Кгц. Было 4 Кгц.).
bcf Status,RP0 ; Переход в 0-й банк.
;================================================================================
; Процедура инициализации ЖКИ модуля.
;================================================================================
....................................
....................................

Так как, после этого, время отработки цикла "основного тела" программы увеличилось,
нужно произвести коррекцию времени отработки фиксированной задержки PAUSE_UI, в
сторону уменьшения:

;================================================================================
; Задержка, определяющая скорость смены показаний и "добывание" результатов
; измерения.
;================================================================================
PAUSE_UI movlw .250 ;
movwf Reg_2 ;
movlw .80 ; Стало .80, а было .150.
movwf Reg_3 ;

decfsz Reg_2,F ; Стандартный,


goto $-1 ; 2-байтный,
decfsz Reg_3,F ; вычитающий
goto $-3 ; счетчик.
return ; Возврат по стеку.
;================================================================================

Эта коррекция произведена "на глазок" (мой). Если "резвость" не устраивает, то в чем
дело? Изменяйте значения констант на свой вкус.

Ну и ладушки.
Выигрыш по инерционности, в 50 мкс., "под каждым кустом не валяется".
Далее, нужно задать себе элементарный вопрос: "Что важнее, реакция на перегруз по
напряжению или реакция на перегруз по току"?

1
Ответ: наивысший приоритет имеет реация на "перегруз" по току (догадайтесь,
почему?).
Вывод: в ПП прерывания, нужно переставить местами процедуры, работающие с
напряжением и током.
Первой должна исполняться процедура, работающая с током.
И в самом деле, при наличии "перегруза" по току, ждать отработки процедуры,
работающей с напряжением, это непозволительная роскошь (можно и "поплатиться").
А после указанной выше перестановки - красота и ляпота.
В смысле "наибыстрейшей реакции на токовую бяку".
К тому же, после того, как "миссия выполнена" (транзистор "токовозакрылся"), можно и
напряжение "текущезамерить".
Никаких препятствий этому нет, так как "напруга" замеряется до транзистора.
Что и имеет место быть.
После соответствующей перестановки, ПП прерывания выглядит так:

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; ПОДПРОГРАММА ПРЕРЫВАНИЯ. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; Процедура сохранения содержимого регистров Status и W.
;================================================================================
; Определение банка, из которого осуществлен уход в прерывание.
;--------------------------------------------------------------------------------
btfsc Status,RP0 ; Из какого банка осуществлен уход
; в прерывание ?
goto BANK_1 ; Если это 1-й банк, то переход
; на метку BANK_1.
; Если это 0-й банк, то программа
; исполняется далее.
;--------------------------------------------------------------------------------
; Процедура сохранения Status и W в регистрах 0-го банка (Stat_Temp, W_Temp).
;--------------------------------------------------------------------------------
movwf W_Temp ; W -> W_Temp.
swapf Status,W ; Смена п/байтов регистра Status.
; Результат -> W.
movwf Stat_Temp ; W -> Stat_Temp.
bcf Flag,7 ; Сброс флага признака банка
; (Flag,7=0: 0-й банк).
; Используется при восстановлении.
goto ACP_1 ; Переход на начало 1-го АЦП.
;--------------------------------------------------------------------------------
; Процедура сохранения Status и W в регистрах 1-го банка (Stat_Temp1, W_Temp1).
;--------------------------------------------------------------------------------
BANK_1 movwf W_Temp1 ; W -> W_Temp1.
swapf Status,W ; Смена п/байтов регистра Status.
; Результат -> W.
movwf Stat_Temp1 ; W -> Stat_Temp1.
bcf Status,RP0 ; Установка 0-го банка.
bsf Flag,7 ; Установка флага признака банка
; (Flag,7=1: 1-й банк).
; Используется при восстановлении.
;********************************************************************************
; 1-е АЦП (сила тока). **********************************************************
;********************************************************************************
; Анализ, на предмет обхода процедуры 1-го АЦП, в случае предыдущего поднятия
; флага превышения порога защиты по току.
;--------------------------------------------------------------------------------
ACP_1 btfsc Flag,4 ; Флаг превышения порога защиты по току
; поднят или нет ?
goto ZAMER ; Если поднят, то обход процедуры 1-го АЦП.
; Если опущен, то процедура 1-го АЦП
; исполняется.
;--------------------------------------------------------------------------------
; Работа с регистром Adcon0.
;--------------------------------------------------------------------------------
2
movlw b'01001001' ; Включение модуля АЦП, выбор канала AN1
movwf Adcon0 ; (RA1), источник тактового сигнала Fosc/8,
; состояние ожидания, конденсатор подключен к
; выбранному аналоговому входу и начал
; перезаряжаться.
call PAUSE ; Задержка для перезаряда конденсатора Hold.
;----> Возврат по стеку из ПП PAUSE.
;--------------------------------------------------------------------------------
; Начало аналого-цифрового преобразования.
;--------------------------------------------------------------------------------
bsf Adcon0,GO ; Включение преобразования. Конденсатор
; отключается от аналогового входа на время
; преобразования.
;--------------------------------------------------------------------------------
; Ожидание окончания АЦП ("плавающая" задержка).
;--------------------------------------------------------------------------------
btfsc Adcon0,GO ; Ожидание окончания аналого-цифрового
goto $-1 ; преобразования.
;------------------------------------------------
; 1-е АЦП закончено. Результат - в AdresH/AdresL.
;================================================================================
; Проверка состояния флага разрешения/запрета изменения
; результата измерения, который выводится на индикацию.
;--------------------------------------------------------------------------------
btfsc Flag,6 ; Каково состояние флага ?
goto OBH_1 ; Если поднят (1), то изменения
; Temp_IH/Temp_IL запрещаются.
; Если опущен (0), то изменения
; Temp_IH/Temp_IL разрешаются.
;--------------------------------------------------------------------------------
; Отрабатывается, если изменения Temp_IH/Temp_IL разрешаются.
;--------------------------------------------------------------------------------
movf AdresH,W ; AdresH --> W.
movwf Temp_IH ; W --> Temp_IH (для измерения).
movwf Mem_IH ; W --> Mem_IH (для деления на 4).

bsf Status,RP0 ; Переход в 1-й банк.


movf AdresL,W ; AdresL --> W.
bcf Status,RP0 ; Переход в 0-й банк.
movwf Temp_IL ; W --> Temp_IL (для измерения).
movwf Mem_IL ; W --> Mem_IL (для деления на 4).
goto POROG__I ; Переход в ПП работы с порогом тока.
;--------------------------------------------------------------------------------
; Отрабатывается, если изменения Temp_IH/Temp_IL запрещаются.
;--------------------------------------------------------------------------------
OBH_1 movf AdresH,W ; AdresH --> W.
movwf Mem_IH ; W --> Mem_IH (для деления на 4).

bsf Status,RP0 ; Переход в 1-й банк.


movf AdresL,W ; AdresL --> W.
bcf Status,RP0 ; Переход в 0-й банк.
movwf Mem_IL ; W --> Mem_IL (для деления на 4).
;================================================================================
; Приведение 2-байтного результата измерения тока к 1-байтному.
;================================================================================
; Деление результата измерения на 4.
;--------------------------------------------------------------------------------
POROG__I rrf Mem_IH,F ; 1-й сдвиг вправо
rrf Mem_IL,F ; на 1 бит.
rrf Mem_IH,F ; 2-й сдвиг вправо
rrf Mem_IL,F ; на 1 бит.
movf Mem_IL,W ; Mem_IL -> W.
;-----------------------------------
; В Mem_IL - результат деления на 4.
;--------------------------------------------------------------------------------
; Проверка на превышение порога.
3
;--------------------------------------------------------------------------------
bcf Flag,4 ; Сброс флага превышения порога защиты по току
subwf Porog_I,W ; Porog_I - Mem_IL = ... (Результат -> W).
btfsc Status,C ; Результат "+"/=0 или "-" ?
goto ZAMER ; Если "+"/=0, то переход на 2-е АЦП.
bcf PortA,2 ; Если "-", то блокировка срабатывает и флаг
bsf Flag,4 ; превышения порога защиты, по току,
; поднимается.
;********************************************************************************
; 2-е АЦП (напряжение). *********************************************************
;********************************************************************************
; Работа с регистром Adcon0.
;--------------------------------------------------------------------------------
ZAMER bcf Adcon0,3 ; Выбор канала AN0 (RA0). Остальные
; настройки Adcon0 не меняются.
call PAUSE ; Задержка для перезаряда конденсатора Hold.
;----> Возврат по стеку из ПП PAUSE.
;--------------------------------------------------------------------------------
; Начало аналого-цифрового преобразования.
;--------------------------------------------------------------------------------
bsf Adcon0,GO ; Аналогично.
;--------------------------------------------------------------------------------
; Ожидание окончания АЦП ("плавающая" задержка).
;--------------------------------------------------------------------------------
btfsc Adcon0,GO ; Аналогично.
goto $-1 ; ----"----
;------------------------------------------------
; 2-е АЦП закончено. Результат - в AdresH/AdresL.
;================================================================================
; Проверка состояния флага разрешения/запрета изменения
; результата измерения, который выводится на индикацию.
;--------------------------------------------------------------------------------
btfsc Flag,6 ; Аналогично, только для
goto OBH_2 ; регистров Temp_UH/Temp_UL.
;--------------------------------------------------------------------------------
; Отрабатывается, если изменения Temp_UH/Temp_UL разрешаются.
;--------------------------------------------------------------------------------
movf AdresH,W ; ----"----
movwf Temp_UH ; ----"----
movwf Mem_UH ; ----"----
bsf Status,RP0 ; Аналогично, только для
movf AdresL,W ; регистров Temp_UH/Temp_UL
bcf Status,RP0 ; и Mem_UH/Mem_UL.
movwf Temp_UL ; ----"----
movwf Mem_UL ; ----"----
goto POROG__U ; Переход в ПП работы с порогом напряжения.
;--------------------------------------------------------------------------------
; Отрабатывается, если изменения Temp_UH/Temp_UL запрещаются.
;--------------------------------------------------------------------------------
OBH_2 movf AdresH,W ; ----"----
movwf Mem_UH ; ----"----
bsf Status,RP0 ; Аналогично, только для
movf AdresL,W ; и Mem_UH/Mem_UL.
bcf Status,RP0 ; ----"----
movwf Mem_UL ; ----"----
;================================================================================
; Приведение 2-байтного результата измерения напряжения к 1-байтному.
;================================================================================
; Деление результата измерения на 4.
;--------------------------------------------------------------------------------
POROG__U rrf Mem_UH,F ; ----"----
rrf Mem_UL,F ; Аналогично, только для
rrf Mem_UH,F ; регистров Mem_UH/Mem_UL.
rrf Mem_UL,F ; ----"----
movf Mem_UL,W ; ----"----
;-----------------------------------
4
; В Mem_UL - результат деления на 4.
;--------------------------------------------------------------------------------
; Проверка на превышение порога.
;--------------------------------------------------------------------------------
bcf Flag,5 ; Сброс флага превышения порога защиты
; по напряжению.
subwf Porog_U,W ; Porog_U - Mem_UL = ... (Результат -> W).
btfsc Status,C ; Результат "+"/=0 или "-" ?
goto ACP_END ; Если "+"/=0, то переход на процедуру выхода
; из прерывания.
bcf PortA,2 ; Если "-", то блокировка срабатывает и флаг
bsf Flag,5 ; превышения порога защиты, по напряжению,
; поднимается.
;--------------------------------------------------------------------------------
; Теперь модуль АЦП можно выключить (начало выхода из прерывания).
;--------------------------------------------------------------------------------
ACP_END clrf Adcon0 ; Для снижения потребляемого устройством тока,
; модуль АЦП выключается до конца отработки
; текущего полного цикла программы.
;================================================================================
; Процедура восстановления содержимого регистров Status, W и выхода из
; прерывания.
;================================================================================
btfss Flag,7 ; Каково состояние флага признака банка ?
goto VOSST_0 ; Если 0-й банк (Flag,7=0), то работа
; с Stat_Temp и W_Temp.
; Если 1-й банк (Flag,7=1), то работа
; с Stat_Temp1 и W_Temp1.
;--------------------------------------------------------------------------------
; Процедура восстановления Status и W из содержимого регистров 1-го банка
; (Stat_Temp1, W_Temp1).
;--------------------------------------------------------------------------------
bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.

bsf Status,RP0 ; Установка 1-го банка.


swapf Stat_Temp1,W; Обмен п/байтами. Результат -> W.
movwf Status ; W -> Status.
swapf W_Temp1,F ; Обмен п/байтами. Результат -> W_Temp1.
swapf W_Temp1,W ; Обмен п/байтами. Результат -> W.
retfie ; Возврат из прерывания с 1-м банком (с 1-м
; банком вошли в прерывание, с 1-м банком
; и вышли).
;--------------------------------------------------------------------------------
; Процедура восстановления Status и W из содержимого регистров 0-го банка
; (Stat_Temp, W_Temp).
;--------------------------------------------------------------------------------
VOSST_0 swapf Stat_Temp,W ; Обмен п/байтами. Результат -> W.
movwf Status ; W -> Status.
swapf W_Temp,F ; Обмен п/байтами. Результат -> W_Temp.
swapf W_Temp,W ; Обмен п/байтами. Результат -> W.

bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.


retfie ; Возврат из прерывания с 0-м банком (с 0-м
; банком вошли в прерывание, с 0-м банком
; и вышли).
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Кстати, в результате такой перестановки, "убивается" один безусловный переход.
А это выигрыш аж в 2 м.ц. (в ПП прерывания, каждый м.ц. "на вес золота").
Номера АЦП сменил "для порядка", так как нумерацию принято начинать сверху.
Теперь - ладушки. Относительные (лучше, чем раньше).
Что дальше будет - сообразим по ходу дела.
Никто "со свечкой над душой не стоит". Все под контролем.

А теперь "взбрыкну-ка" я по поводу подсказки.

5
При переходе в режим включенной защиты, подсказка есть, а при переходе в режим
выключенной защиты, подсказки нет.
Форменное безобразие. "Прокол".
И тем более, что прежде чем свершить такое ответственное действие, как выключение
защиты, обязательно нужно "профилактически капнуть пользователю на мозги".
В смысле: "Уважаемый пользователь, а Вы хорошо подумали, прежде чем решиться на
такое? Если да, то это только на Вашей совести, а если нет, то можете вернуться в
режим включенной защиты. А вот Вам и подсказка".
Это называется "упреждающим диалогом конструктор (через железяку) - пользователь".
Кто скажет, что это не человеколюбиво?
Это во-первых.
Во-вторых, конструктор это совсем не чурбан, так как он имеет индивидуальность/душу.
Чем, в конце концов, мы с Вами здесь занимаемся, ваянием/творением или
"штамповкой"?
Речь идет именно о первом (а кто не понял, тот не туда попал).
А раз это так, то эта самая индивидуальность (не важно, какая именно) должна
"выглядывать/вылезать из всех возможных отверстий".
В-третьих, все мы тут собрались для того, чтобы узнать какие-то новые, оригинальные
(хулиганские) способы реализации "того-сего".
Что касается лично меня, то свой "локальный вклад", в это благое дело, я реализовал
следующим образом.
В начале любого перехода в режим выключенной защиты, автоматически запускается
сценарий-подсказка №2.
Примечание: то, что было в предыдущем подразделе,
назову сценарием-подсказкой №1
Вы видите три надписи, которые чередуются в том
порядке, в котором следуют картинки.
Первая из них - "предупреждалка".
Вторая и третья - подсказки: на что нужно "жать",
чтобы достигнуть желаемого/предлагаемого.
Эти надписи чередуются "безлимитно".
То есть, для того чтобы прекратить это чередование и
"уйти" в один из предлагаемых режимов, нужно
нажать/отжать одну из предлагаемых кнопок (намека,
конкретнее этого, просто не бывает).
Я рассчитываю на то, что после такого рода
информации, пользователь будет "жать" на ту или
иную кнопку не абы как, а хотя бы более-менее
осмысленно. А если же пользователь "не внемлет", то
он, если что плохое случится, сам и виноват.
Для конструктора подобного рода "железяк", это
немаловажно.
И в самом деле, зачем ему "отдуваться за чужие грехи"? У него и своих хватает.
На все время нажатия любой из предлагаемых, в
диалоге, кнопок, появляется та надпись, которую Вы
видите слева.
Это я творчески "взбрыкнул".
Чтобы было не скучно (не люблю формализм) и
пользователь улыбнулся.
Пользователю ничто человеческое не чуждо (когда
"слушаются и повинуются", это всем приятно).
После отжатия кнопки "-/Нет", Вы увидите "вариацию"
того, что изображено на картинке слева (U/I могут быть
другими).
То есть, "железяка послушно уйдет" в режим
выключенной защиты.
В этом случае, защита работать не будет (если что, то
конструктор не виноват. Он предупреждал), и на индикацию будут выведены текущие
значения напряжения и тока.
6
После отжатия кнопки "+/Да", Вы увидите надпись,
изображенную на картинке слева.
Она будет "высвечиваться" примерно 2 секунды, после
чего "исчезнет", и автоматически начнется отработка
сценария-подсказки №1. То есть, того, о чем
говорилось в предыдущем подразделе (повторять не
буду).
Сказанное "ваяется" так:

7
Обращаю Ваше внимание на то, что флаг факта нажатия кнопки как бы
"обезличился".
То есть, сейчас он "привязан" уже не к одной кнопке (как ранее), а к нескольким.
К какой именно?
Это зависит от конкретного алгоритма.
А так как алгоритмы разные, то и "привязки" тоже разные.
Это мой текущий "бзик" (а куда деваться, если "яблоко на голову упало"?),
позволяющий многократно/многофункционально задействовать один и тот же флаг.
По-моему, это смотрится вполне прилично.
Также обратите внимание на то, что, для фиксации надписей, используется
фиксированная задержка, с "принудительным" выходом из нее, по фактам нажатия
кнопки "+/Да" или "-/Нет" (на блок-схеме, выделено светло-желтым цветом):

;================================================================================
; Задержка, с "принудительным" выходом из нее
; (при нажатии любой из кнопок "+/Да", "-/Нет").
;================================================================================
PAUSE_S movlw .93 ;
movwf Reg_1 ; Константы
movlw .38 ; можно подобрать
movwf Reg_2 ; на Ваш вкус.
movlw .5 ;
movwf Reg_3 ;
;---------------------------------------------------------------
; Вычитающий счетчик с "врезкой" в него процедуры опроса кнопок.
;---------------------------------------------------------------
btfss PortB,2 ; Кнопка "+/Да" нажата или отжата ?
return ; Если нажата, то выход из задержки
; (возврат по стеку).
btfss PortB,3 ; Кнопка "-/Нет" нажата или отжата ?
return ; Если нажата, то выход из задержки
; (возврат по стеку).
decfsz Reg_1,F ;
goto $-5 ;
decfsz Reg_2,F ; 3-байтный,
goto $-7 ; вычитающий
decfsz Reg_3,F ; счетчик.
goto $-9 ;
return ; Возврат по стеку.
;================================================================================

То есть, в случае нажатия любой из этих кнопок, задержка не отрабатывается до


конца, и происходит "принудительный" переход на ее окончание.
А проще говоря, происходит выход из ПП задержки посредством возврата по стеку
(ПП задержки вызывается командой call).
Если применить обычную задержку (без "принудиловки"), то при условии организации
одного опроса клавиатуры (это и имеет место быть), для того чтобы "железяка
среагировала на домогательства", придется долго "жать" кнопку (до нескольких секунд).
Естественно, пользователь за это спасибо не скажет (точно "плеваться будет').
А в случае предлагаемой Вашему вниманию "принудиловки", получается "полнейшая
красота/ляпота": все задержки, отрабатываемые с момента времени нажатия кнопки
"+/Да" или "-/Нет", будут отработаны "с реактивным свистом", "железобетонным"
результатом которого будет "быстренькая закольцовка" в процедуре ожидания отжатия
кнопки.
Вот и вся, достаточно немудреная и по-моему, эстетичная, суть этой вполне
"реактивной" задумки.

Следующая особенность.
Обратите внимание на надпись СЛУШАЮСЬ и / ПОВИНУЮСЬ !
Она не "укомплектована" фиксированной задержкой, а после нее, если кнопки отжаты,
на индикацию выводится надпись Вы хорошо / подумали? (а также и еще 2 надписи.
После них, фиксированные задержки есть).
8
То есть, в случае отжатия кнопок, надпись СЛУШАЮСЬ и / ПОВИНУЮСЬ ! конечно же
будет выведена на индикацию, но она тут же "уничтожится" (задержки-то нет. "Не
долго птичка пела"…) надписью Вы хорошо / подумали? (запись по верху надписи
СЛУШАЮСЬ и / ПОВИНУЮСЬ !).
И визуально ощущаемой будет именно надпись Вы хорошо / подумали?, так как она
"укомплектована" фиксированной задержкой.
Проще говоря, если кнопки отжаты, то надписи СЛУШАЮСЬ и / ПОВИНУЮСЬ ! просто
не будет видно по причине ее "реактивного мелькания" (глаз человека - совсем не
фотоаппарат).
Вопрос: "При каких условиях, эту надпись можно увидеть?"
Ответ: если любая из кнопок нажата достаточно продолжительное время (более чем
на 0,15 сек.).
В этом случае, рабочая точка программы "закольцовывается" в "плавающей" задержке
(ожидание отжатия кнопки) и надпись СЛУШАЮСЬ и / ПОВИНУЮСЬ !, соответственно,
"успевает высветиться".
Сколько будете "жать" на кнопку (любую из двух), столько эта надпись и будет
"высвечиваться".
А после отжатия кнопки, рабочая точка программы "вырвется" из "плавающей"
задержки и перейдет в "рабочее действие после отжатия", которое зависит от того,
какая именно из двух кнопок была нажата.
Если кнопки отжаты, то в конечном итоге, происходит "закольцовка" на постоянный,
последовательный, визуально ощущаемый, вывод на индикацию надписей
Вы хорошо / подумали?,
Откл. | защиты / кнопка "-/Нет",
Вкл. | защиты / кнопка "+/Да",
а надпись СЛУШАЮСЬ и / ПОВИНУЮСЬ ! , по причине своей "суперреактивности" (в
смысле соответствующего "свиста"), визуально ощущаться не будет.
Смотрится вся эта "свистопляска" вполне прилично и даже приятно.
Душа радуется. Значит с качеством "продукта", а заодно и с мозгами, все в порядке.

О процедуре записи признака режима в EEPROM-память данных ПИКа:

;================================================================================
; Опрос кнопки "+/Да".
;================================================================================
btfsc PortB,2 ; Кнопка "+/Да" нажата или отжата ?
goto KN_NO ; Если отжата, то переход на опрос кнопки
; "-/Нет".
;-----------------------------------
; Противодребезговая задержка.
;-----------------------------------
call PAUSE_UI ; Переход в ПП PAUSE_UI.
;----> Возврат по стеку из ПП PAUSE_UI.
;-----------------------------------
; Ожидание отжатия кнопки.
;-----------------------------------
btfss PortB,2 ; Кнопка "+/Да" нажата или отжата ?
goto $-1 ; Если нажата, то ожидание отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
; Рабочее действие после отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
bsf Trig,0 ; Установка режима "ЗАЩИТА ВКЛЮЧЕНА".
;---------------------------------------------------------------------------
; Запись измененного значения регистра Trig, в ячейку EEPROM, с адресом 00h.
;---------------------------------------------------------------------------
call WR_TRIG ; Переход в ПП записи.
;----> Возврат по стеку из ПП WR_TRIG.
goto YES_VKL ; Вход в цикл рабочего сценария
; включенной защиты.
;================================================================================

9
В данном случае, она архинужна, так как, после отжатия кнопки "+/Да", содержимое
регистра Trig изменяется.
Если не произвести этой записи, то после выключения/включения питания, будут
ошибки перехода в ранее установленный режим.
Эта запись производится совсем не на каждом цикле, а только по факту отжатия
кнопки "+/Да", что, с точки зрения "экономии EEPROM-моторесурса", есть несомненный
"зер гут".
А так как одна и та же процедура записи, в EEPROM-память данных ПИКа,
используется уже не один, а два раза (см. предмет разговора, а также и ПП INKEY),
то я ее назвал подпрограммой WR_TRIG и "вынес" в "нижнюю обслугу" (вызывается
командой call).
Если кто-то скажет, что это слишком сложно, то я потеряю веру в человечество и
уйду сами знаете куда.

О "блочных делах".
Обратите внимание на то, что я не стал "прислонять новорожденные" ПП табличных
переходов к ранее созданной группе ПП таких же (в принципе) переходов (см.
"верхнюю обслугу").
Если это сделать, то "граница" между 1-м и 2-м блоками памяти программ ПИКа будет
проходить через одну из таблиц вычисляемого перехода ("Гитлер капут", "Караул!
Убивают!" и т.п.).
Конечно же можно "подсуетиться" с оператором low, но зачем нужны лишние
"телодвижения"?
Я просто "засунул новорожденную" группу ПП табличных переходов приблизительно в
начало 2-го блока памяти программ ПИКа (в 1-м блоке "ловить больше нечего").
И все дела. "Дешево, сердито и комары не кусают".
Это, по любому, заставляет (а куда деваться? "Важняк") задуматься об организации
"безбяковых" переходов между блоками памяти программ ПИКа, так как ПП
вычисляемых переходов "раскиданы" в двух блоках.
То есть, о соответствующей коррекции содержимого регистра PCLATH.
Попробуй, не задумайся (напоминаю о волосатом кулаке)…
"Окурок сьесть" придется. И не один.
Принцип всего этого "изворачивания" прост и незамысловат:

- Если ранее происходила работа с таблицей, "лежащей" в 1-м блоке


памяти программ ПИКа, а далее будет происходить работа с таблицей
(таблицами), "лежащей" во 2-м блоке памяти программ ПИКа, то прежде
чем переходить к работе с таблицей (таблицами), "лежащей" во 2-м блоке
памяти программ ПИКа, нужно скорректировать содержимое регистра
PCLATH (bsf PCLATH,0).
- Если ранее происходила работа с таблицей, "лежащей" во 2-м блоке
памяти программ ПИКа, а далее будет происходить работа с таблицей
(таблицами), "лежащей" в 1-м блоке памяти программ ПИКа, то, прежде
чем переходить к работе с таблицей (таблицами), "лежащей" во 1-м блоке
памяти программ ПИКа, нужно скорректировать содержимое регистра
PCLATH (clrf PCLATH).

Этот же принцип, без проблем, можно распространить и на все остальные случаи


переходов, из текущего блока памяти программ ПИКа, с любым номером, в любой
другой блок.
В данном случае, когда совершенно точно известны направления переходов из блока в
блок (из какого в какой), оператор high использовать, конечно же, можно, но
нецелесообразно, так как можно обойтись меньшим количеством команд.
Что и сделано.

О флаге факта нажатия кнопки.


Он нужен для ответа на вопрос: "Обходить сценарий-подсказку №2 или не обходить"?

;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
10
; Опрос флага факта нажатия кнопки.
;--------------------------------------------------------------------------------
btfsc Flag,2 ; Флаг факта нажатия кнопки поднят или опущен?
goto YES_VIKL ; Если поднят, то обход сценария-подсказки.
bcf PortA,2 ; Если опущен, то транзистор закрывается и
; отрабатывается сценарий-помощник №2.
;********************************************************************************
; Начало сценария-помощника №2
; (отрабатывается после перехода в режим выключенной защиты).
;********************************************************************************

Обойти его нужно в том случае, если ранее был осуществлен переход в режим
выключенной защиты.
Если этого не сделать, то после перехода в режим выключенной защиты, будет
отрабатываться не то, что нужно, а сценарий-подсказка №2.
Флаг факта нажатия кнопки (в данном случае, кнопки "-/Нет") поднимается в ходе
исполнения "Рабочего действия после отжатия" (выделено красным цветом):

;================================================================================
; Опрос кнопки "-/Нет".
;================================================================================
KN_NO btfsc PortB,3 ; Кнопка "-/Нет" нажата или отжата ?
goto $+7 ; Если отжата, то обход 6-ти следующих команд
; Выод надписи "Вы хорошо / подумали?".
;-----------------------------------
; Противодребезговая задержка.
;-----------------------------------
call PAUSE_UI ; Переход в ПП PAUSE_UI.
;----> Возврат по стеку из ПП PAUSE_UI.
;-----------------------------------
; Ожидание отжатия кнопки.
;-----------------------------------
btfss PortB,3 ; Кнопка "-/Нет" нажата или отжата ?
goto $-1 ; Если нажата, то ожидание отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
; Рабочее действие после отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
clrf PCLATH ; Так как далее - переходы в вычисляемые
; переходы, лежащие во 1-м блоке PC.
bsf Flag,2 ; Поднятие флага факта нажатия кнопки.
goto YES_VIKL ; Вход в цикл рабочего сценария
; выключенной защиты.
;================================================================================

Если это (нажатие/отжатие кнопки "-/Нет") произойдет, то на следующем "витке"


полного цикла программы, процедура сценария-подсказки №2 будет обойдена.
Вопрос: "А где опускать этот универсальный флаг (как же без этого?)"?
Ответ: в сценарии ЗАЩИТА ВКЛЮЧЕНА.
Вопрос: "Почему"?
Ответ: так как переход в режим выключенной защиты может произойти:
- из режима установки порогов,
- из режима включенной защиты.
Что касается первого, то обеспечивается возврат в текущий режим.
То есть, если произошел возврат, из режима установки порогов, в заранее
выставленный режим выключенной защиты, то с флагом факта нажатия кнопки ничего
делать (сбрасывать) не нужно.
Он будет поднят. Ну и ладушки. Это и нужно.
А вот в режиме включенной защиты, флаг факта нажатия кнопки, с "прицелом" на
дальнейший переход в режим выключенной защиты, нужно обязательно сбросить, а
иначе, после перехода, из режима включенной защиты, в режим выключенной защиты,
сценарий-подсказка №2 никогда не будет отработан.
Это выглядит так:

11
;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; Сценарий "ЗАЩИТА ВКЛЮЧЕНА".
;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; Подготовительные операции.
;--------------------------------------------------------------------------------
Z_VKL
....................................
....................................
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая подпрограмма слежения.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
KOL_MOZALO
....................................
....................................
;================================================================================
; Опрос клавиатуры.
;================================================================================
; Опрос кнопки "Переключение режимов".
;--------------------------------------------------------------------------------
ЭТО БЫЛО:
;;;MOZALO_1 btfss PortB,0 ; Кнопка "Переключение режимов" нажата
;;; ; или отжата ?
;;; goto INKEY ; Если нажата, то переход на опрос
;;; ; клавиатуры.
;;; ; Если отжата, то программа
;;; ; исполняется далее.
А ЭТО ЕСТЬ:
MOZALO_1 btfsc PortB,0 ; Кнопка "Переключение режимов" нажата
; или отжата ?
goto $+3 ; Если отжата, то обход следующих двух команд.
bcf Flag,2 ; Если нажата, то флаг факта нажатия кнопки
goto INKEY ; опускается и переход в ПП INKEY.
....................................
....................................

;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
; Процедура вывода на индикацию справочной надписи
; " Вкл. | нагрузки / кнопка "+/Да". "
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
....................................
....................................
;================================================================================
; Опрос клавиатуры.
;================================================================================
; Опрос кнопки "Переключение режимов".
;--------------------------------------------------------------------------------
ЭТО БЫЛО:
;;;MOZALO_2 btfss PortB,0 ; Кнопка "Переключение режимов" нажата
;;; ; или отжата ?
;;; goto INKEY ; Если нажата, то переход на опрос
;;; ; клавиатуры.
;;; ; Если отжата, то программа
;;; ; исполняется далее.
А ЭТО ЕСТЬ:
MOZALO_2 btfsc PortB,0 ; Кнопка "Переключение режимов" нажата
; или отжата ?
goto $+3 ; Если отжата, то обход следующих двух команд.
bcf Flag,2 ; Если нажата, то флаг факта нажатия кнопки
goto INKEY ; опускается и переход в ПП INKEY.
....................................
....................................
goto KOL_MOZALO ; Переход на начало следующего цикла слежения.
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

12
То есть, состояние флага факта нажатия кнопки зависит от наличия/отсутствия факта
нажатия кнопки "Переключение режимов" (в данном случае. Поэтому и флаг
универсален).
Проще говоря, если осуществляется переход, из режима включенной защиты, в режим
выключенной защиты, то флаг факта нажатия кнопки всегда опускается.
А это гарантирует последующую отработку сценария-подсказки №2.
Вот и получается "железобетонная" реализация того, что задумано.
Примечание: то же самое сделано и в ПП PROV_U_I.

Следующий "момент":
;================================================================================
; Вывод на индикацию, во 2-ю строку, фиксированной надписи " кнопка "+/Да". ".
;================================================================================
clrf PCLATH ; Так как далее - переходы в вычисляемые
; переходы, лежащие в 1-м блоке PC.
movlw b'11000000' ; Установка курсора в крайнее
call ENTER_BF ; левое знакоместо 2-й строки.
movlw .16 ;
movwf Count ;
movf Count,W ;
sublw .16 ; Аналогично, только
call TEXT_8 ; для TEXT_8.
bsf PortC,RS ;
call ENTER_BF ;
decfsz Count,F ;
goto $-6 ;

bsf PCLATH,0 ; Так как далее - переходы в вычисляемые


; переходы, лежащие во 2-м блоке PC.
;================================================================================

В данном случае, используется та надпись, которая имелась в наличии до "свершения


текущих катаклизмов".
Так как переход в эту процедуру происходит при PCLATH = .1 (2-й блок памяти
программ), а вычисляемый переход ПП TEXT_8 "дислоцируется" в 1-м блоке памяти
программ, то прежде чем исполнить команду call TEXT_8, нужно перейти в 1-й блок
памяти программ.
Что и имеет место быть (clrf PCLATH).
Так как, после окончания отработки вычисляемого перехода ПП TEXT_8, позднее,
происходит переход в ПП TEXT_15, вычисляемый переход которой "дислоцируется" во
2-м блоке памяти программ, то прежде чем исполнить команду call TEXT_15, нужно
перейти во 2-й блок памяти программ.
Что и имеет место быть (bsf PCLATH,0).
Вот и вся "премудрость".
Кстати, свободная и непринужденная "ориентация в подобного рода премудрости"
(звучит легко, но зарабатывается совсем не так, как звучит), которая, каждый раз,
строго специфична (зависит от конкретных причин), есть один из явных признаков
тренированно-матерого конструктора-микроконтроллерщика.

Следующий "момент".
В сценарии включенной защиты программы предыдущего подраздела (BP_5.asm),

;--------------------------------------------------------------------------------
; Анализ содержимого указателя количества смен надписей.
;--------------------------------------------------------------------------------
decfsz Temp_2,F ; Уменьшение содержимого указателя
; количества смен надписей на 1.
goto KOL_MOZALO ; Если результат не=0, то переход
; на начало следующего цикла слежения.
;--------------------------------------------------------------------------------
; Поднятие флага завершения смен надписей.
;--------------------------------------------------------------------------------
13
была допущена вполне безобидная неточность, выражающаяся в отсутствии явного
указания на "место" сохранения результата операции (выделено красным цветом).
Просто забыл "настучать" ,F.
Вопрос: "Почему безобидная"?
Ответ: потому, что в случае "неуказания места" сохранения результата операции,
MPLAB, по умолчанию, сохраняет его в F, что в данном случае и требуется.
То есть, в данном, конкретном случае, никакого нарушения работы программы нет.
Было бы гораздо хуже, если бы речь шла о сохранении результата операции в
регистре W (при наличии забывчивости).
Вывод: если результат операции нужно сохранить в F, то в тексте
программы можно и не указывать "место" сохранения результата операции,
так как по умолчанию, результат операции будет сохранен в F.
Это универсальный принцип.
Правда при этом выдается соответствующее количество Message.
Кого это не сильно нервирует, могут поступать так, как сказано (меня нервирует).
Кстати, сие может быть применено "агентом 007" для "запутывания следов" (если в
этом есть какая-то необходимость).

В справедливости сказанного, Вы можете убедиться с помощью программы BP_6.asm.


Принципиальная схема устройства (см. предыдущий подраздел) - без изменений.

Общее замечание: инерционность срабатывания защиты улучшилась.


Однозначно. На 50 мкс.
И без какой бы то ни было программностратегической "лабуды/лапши".
Все честно.
Сценарий-помощник №2 (и №1 тоже) никоим образом не влияет на инерционность
срабатывания защиты (догадайтесь, почему?).
Что дальше?
Поживем, хлеб пожуем, посмотрим (творческий процесс. Тайна сия велика есть) …

"Практикум по конструированию устройств на PIC контроллерах"      http://ikarab.narod.ru       E-mail: karabea@lipetsk.ru

14