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

2-2/15.

Уменьшение инерционности срабатывания защиты по превышению


порогов U/I за счет увеличения тактовой частоты ПИКа (практикум по переводу
программы, с кварца 4 Мгц., на кварц 20 Мгц.). "Модернизация" процедуры
вывода на индикацию надписи "СЛУШАЮСЬ и ПОВИНУЮСЬ!" (свидетельствует о
"достижении взаимопонимания" пользователя и "железяки") и расширение
"сферы" ее применения. Организация ручного включения/выключения нагрузки (в
обеих, основных режимах), сопровождаемое подсказками.

Дальнейший, наиразумнейший (на мой взгляд), текущий план работы таков: сначала
нужно перевести "железяку" (а соответственно и программу) на максимально
возможную тактовую частоту (минимально возможное время отработки машинных
циклов).
После успешного завершения этого "предприятия", можно озаботиться тем
"запланированным счастьем", которое будет иметь место быть ("куда его прислонить"?).
То есть, после повышения тактовой частоты и доведения "железяки" до
соответствующего, работоспособного состояния, ничто не мешает улучшить такой
архиважнейший параметр, как инерционность срабатывания защиты по превышению
порогов U/I.
Все остальные "навороты" à только после этого.
Реализую.
Теперь, принципиальная схема выглядит так:

Программа, "обслуживающая" эту принципиальную схему, называется BP_11.asm


(прилагается).

Имеются 2 изменения, связанные с переводом "железяки" на более высокую тактовую


частоту (см. выделенное зеленым цветом):
- кварц 4 Мгц. заменен на кварц 20 Мгц.,
- емкость конденсатора С4 снижена до 1 мкф.
Внешний вид кварца на 20 Мгц., который использован,
показан на картинке слева.
Понятия не имею, какая именно "контора" его сделала,
но работает он четко. "С первого тыка".

1
Подключенные к кварцу емкости (15 пф.), какими были, такими и остались.
Несколько забегая вперед, скажу, что после перехода на Fкв. = 20 Мгц., на данном
этапе работы, наихудшая инерционность срабатывания защиты по превышению порогов
U/I снижена в 2 раза: с 200 мкс. до 100 мкс.
Это свидетельствует о том, что частота ШИМ-сигнала управления вентиллятором
повысилась с 5 Кгц. до 10 Кгц.
Соответственно, емкость С4 можно уменьшить.
В принципе, этот конденсатор можно вообще убрать, так как на такой высокой частоте,
вентиллятор (по крайней мере тот, который я применяю) практически не "пищит" (c
поправкой на мое "тугое ухо"), но это, при прочих, равных условиях, приводит к
некоторому уменьшению количества оборотов "пропеллера", что вполне закономерно.
Может быть даже такие обороты и будут приемлемыми, но я все-таки не стал
"убивать" конденсатор С4, а снизил его емкость до 1 мкф., что позволяет применить
не "электролит", а неполярный конденсатор.
Его емкость можно подобрать в диапазоне от 0,1 до 1,0 мкф.
Это уж Вы решайте сами. С учетом того количества оборотов (можно ориентироваться
на комнатную температуру), которое для Вас приемлемо.
Как видите, в принципиальной схеме, изменения минимальны.
Чего не скажешь об изменениях, внесенных в текст программы.
Давайте разбираться.

Перевод программы, с кварца 4 Мгц., на кварц 20 Мгц.

Перво-наперво, при переходе, с кварца 4 Мгц., на кварц 20 Мгц. нужно изменить


слово конфигурации.
Что "стояло"?
XT-генератор (применяется "обычный" кварц).
Что нужно?
HS-генератор (применяется "высокочастотный" кварц).
Конкретнее.
Если имеет место быть "шаг" изменения частоты кварца, равный 4 Мгц. (что чаще
всего и бывает при переходе с одного такта на другой), то по стандарту Микрочипа, в
случаях работы с Fкв., превышающими 4 Мгц. (8, 12, 16, 20 Мгц.), нужно перейти на
HS-генератор (см. "Справочник по среднему семейству …").
У некоторых типов ПИКов (например, у PIC16F873A), частота кварца = 4 Мгц. может
быть "пограничной".
То есть, на частоте кварца = 4 Мгц., в случае, если в режиме XT-генератора, кварц не
"возбуждается", можно попробовать его "возбудить" в режиме HS-генератора.
Следует учитывать то, что при работе в режиме HS-генератора, с Fкв. = 20 Мгц., по
сравнению с режимом XT-генератора (при прочих, равных условиях), потребление
ПИКом тока возрастает (я бы не сказал, что очень уж сильно), и это вполне
естественно, так как переход на более высокую, тактовую частоту "требует жертв"
(дополнительной энергии).
Переход в режим HS-генератора выглядит так:

LIST p=16F873A ; Задание типа микроконтроллера.


__CONFIG 3F72H ; Включено: HS-генератор, PWRT, сброс BOR,
; Выключено: защита, WDT, LVP, DEBUG.
3F71H заменяется на 3F72H, и дело с концом.
"Поковылял" дальше.
После перехода, с кварца 4 Мгц., на кварц 20 Мгц., время отработки одного машинного
цикла уменьшится с 1 мкс. до 0,2 мкс.
То есть, в 20/4 = 5 раз.
Прежде всего, это отразится на подпрограммах задержек.
То есть, если какая-то ПП задержки, "до того", отрабатывалась, например, за
1 секунду, то "после того", она будет отрабатываться за 0,2 секунды.
В рассматриваемом случае, если не предпринять соответствующих мер, то визуально,
это выразится в "наишустрейшей" смене надписей, успеть прочесть которые будет
затруднительно.
2
Вывод: для того чтобы привести время отработки, той или иной подпрограммы
фиксированной задержки, к тому времени ее отработки, которое имело место быть "до
того", нужно в 5 раз увеличить интервал времени отработки этой подпрограммы.
Проще говоря, в данном случае ("до того", ПП отрабатывалась за 1 сек.), в программе
Николая Марова, нужно задать задержку в 5 000 000 мкс., после чего, заменить
получившимся результатом (или "скорректировать" константы) то "односекундное
безобразие", которое имело место быть в "матери".
После этого, с учетом Fкв. = 20 Мгц., задержка будет отработана за ту же, одну
секунду.
Не всегда, но иногда, для обеспечения нужного времени отработки задержки, может
потребоваться повышение "байтности" счетчика.
Например, как в этом случае.
Это то, что было (Fкв. = 4 Мгц.):
;================================================================================
; Задержка, определяющая скорость смены показаний и "добывание" результатов
; измерения (61585 м.ц., без учета call и return).
;================================================================================
;;;PAUSE_UI movlw .250 ;
;;; movwf Reg_2 ;
;;; movlw .80 ;
;;; movwf Reg_3 ;

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


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

Это то, что нужно в случае перехода на Fкв. = 20 Мгц.:


;================================================================================
; Задержка, определяющая скорость смены показаний и "добывание" результатов
; измерения (307925м.ц.х0,2мкс.=61585мкс., без учета call и return).
;================================================================================
PAUSE_UI movlw .228 ;
movwf Reg_1 ;
movlw .144 ;
movwf Reg_2 ;
movlw .2 ;
movwf Reg_3 ;

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


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

Но частенько, повышать "байтность" просто не нужно.


Достаточно только скорректировать числовое значение констант.
Например, как в этом случае.
Это то, что было (Fкв. = 4 Мгц.):
;================================================================================
; Задержка на 1 сек.
;================================================================================
;;;PAUSE_1SEK movlw .173 ;
;;; movwf Reg_1 ;
;;; movlw .19 ;
;;; movwf Reg_2 ;
;;; movlw .6 ;
;;; movwf Reg_3 ;

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

Это то, что нужно в случае перехода на Fкв. = 20 Мгц.:


;================================================================================
; Задержка на 1 сек.
;================================================================================
PAUSE_1SEK movlw .110 ;
movwf Reg_1 ;
movlw .94 ;
movwf Reg_2 ;
movlw .26 ;
movwf Reg_3 ;

decfsz Reg_1,F ; 3-байтный,


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

"Поковылял" дальше.
Но ведь в программе, кроме стандартных ПП фиксированных задержек, имеется еще
много "всякой, специфической всячины".
В данном случае, "орлиный взор неизбежно упирается" в ЖК-модуль.
И с ним нужно разобраться в первую очередь, так как в "пустом" дисплее можно
увидеть только "глюк" (например, жирафа с крыльями, ругающегося матом и т.д.).
Вопрос: "В ЖК-делах меются временнЫе бяки"?
Ответ: так точно. Имеются (см. предельные временнЫе характеристики).
И в данном случае, все они связаны с временнЫми параметрами формирования
импульсов на линии Е.
Все остальные временнЫе изменения приемлемы, так как они "не выходят за границы
дозволенного".
Вывод: "орлиный взор" нужно "направлять" вовсе не на все то, что вообще связано с
ЖК-модулем, а его нужно "направить" на конкретную ПП с названием ENTER_BF (ну и
на ENTER_BF_1 тоже. Так как "клон").
Есть там фиксированные задержки?
Есть. В виде NOPов (при Fкв. = 4 Мгц, это фиксированная задержка на 1 мкс).
Вот их-то, "не мудрствуя лукаво" (соответствующие "мудрствования" были гораздо
ранее), в первую очередь, и нужно "подрихтовать". По-умному.
После "предоценки оперативной обстановки", в голове возникает следующее
"автоопасение": "Что-то многовато NOPов получается… Кабы не намусорить …".
Конечно же, можно заменить один "материнский" NOP 2-мя командами goto $+1, плюс
один "дочерний" NOP, а затем повторить сие несколько раз, но это же, с точки зрения
рациональности, "форменное безобразие"!
Как на это реагируют другие души, не знаю, но моя душа этого совершенно не выносит.
Поэтому, организованы две "сверхминиатюрные" подпрограммы задержек.
Для 1-й страницы памяти программ (под ПП ENTER_BF):
;================================================================================
; Задержка 1 мкс. (с учетом call и return).
;================================================================================
PAUSE_1MKS nop ; Задержка 1 м.ц.
return ; Возврат по стеку.

Для 2-й страницы памяти программ (под ПП ENTER_BF_1):


4
;================================================================================
; Задержка 1 мкс. (с учетом call и return).
;================================================================================
PAUSE_1MKS1 nop ; Задержка 1 м.ц.
return ; Возврат по стеку.

При Fкв. = 20 Мгц., с учетом перехода и возврата, это ровно 1 мкс.


А теперь call PAUSE_1MKS или call PAUSE_1MKS1 (в зависимости от страницы
памяти программ), и все дела.
Кроме всего прочего, ПП PAUSE_1MKS1 применяется и в ПП WIRE.
По сравнению с упомянутым выше "форменным безобразием", выигрыш по количеству
команд очевиден.
Значит так тому и быть.
Теперь "падаю" на процедуру инициализации ЖК-модуля.
В ней имеется универсальная задержка (время задержки определяется
предустановленным содержимым W) на 50 мкс. (в "матери", константа .15).
В принципе, можно ничего не менять, так как, после перехода на Fкв. = 20 Мгц. и
осуществления "вышележащей рихтовки", инициализация проходит успешно, но лучше
"подрихтовать". Хуже от этого не будет.
И на душе спокойнее (в смысле обеспечения надежной "нейтрализации возможных
разбросов").
Поэтому, значение константы увеличивается в 20/4 = 5 раз (было .15, а стало .75):

movlw .75 ;
call PAUSE_X ; Задержка 50 мкс.

То есть, величина "материнской" задержки сохранена.


Точно такой же принцип применяется во всех тех случаях, когда речь идет о
подпрограммах задержек, время отработки которых определяется "внешней" константой
(константами).
"Плавающие" задержки не в счет ("расшифровка лежит" ниже).
Другие примеры:

;================================================================================
; Задержка, с "принудительным" выходом из нее (при нажатии любой из кнопок
; "+/Да", "-/Нет").
;================================================================================
PAUSE_S movlw .93 ;
movwf Reg_1 ; Константы
movlw .38 ; можно подобрать
movwf Reg_2 ; на Ваш вкус.
movlw .20 ;
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 ; Возврат по стеку.
;================================================================================

"До того", имела место быть константа .5.

5
"После того", имела место быть константа .25.
Наличие же константы .20 (а не .25) объясняется тем, что я счел время отработки
этой фиксированной задержки слишком большим и поэтому уменьшил его
(субъективный фактор. Вот захотелось мне так …).
Разъяснения.
В данном случае, целесообразно (так проще) изменить только числовое значение
константы самого старшего разряда, ведь именно ей задается основной "прирост" (или
"убыль", если ее числовое значение уменьшается) времени отработки задержки.
Можно "подрихтовать" и все 3 константы, но в данном случае, какого-то могучего,
практического смысла в этом нет, так как допустИм "достаточно приличный шаляй-
валяй" ("плюс-минус 2 лаптя". На усмотрение конкретной личности).
А вот если бы речь шла о задержке со строго калиброванным временем ее отработки,
то в этом случае, нужно точнейше "рихтовать" числовые значения всех ее констант.

Еще один пример:


;================================================================================
; Аварийная "пищалка" (мультивибратор, формирующий "пачку" импульсов).
;================================================================================
MULTI movlw .250 ; "Пищать" будем
movwf Reg_2 ; 250 периодов.

bcf PortC,4 ; Установка на выходе защелки RC4 уровня 0.


movlw .250 ; Задание периода
movwf Reg_3 ; (частоты).

decfsz Reg_3,F ; Формирование


goto $-1 ; полупериода.

btfsc PortC,4 ; Если на выходе защелки RC4 уровень 1,


goto $-6 ; то дальнейшая его смена на уровень 0.
decf Reg_2,F ; Если на выходе защелки RC4 уровень 0,
; то Reg_2 - 1 = ... и программа исполняется
; далее.
btfsc Status,Z ; Каков результат декремента ?
return ; Если =0, то "пачка" импульсов сформирована
; и выход из "пищалки".
bsf PortC,4 ; Если не=0, то установка на выходе защелки
; RC4 уровня 1.
goto $-.10 ; Переход на формирование следующего периода.
;================================================================================

"До того", имела место быть константа .50.


"После того", имеет место быть константа .250.
Если такой замены не произвести, то "писк" будет таким "тонюсеньким и скоротечным",
что даже "куры будут смеяться".

Вернусь к "ЖК-модульным делам".


Каковы они?
Они просто прекрасны.
В том смысле, что ЖК-модуль, при Fкв. = 20 Мгц., нормально функционирует (сбоев не
заметил).
Ничуть не хуже, чем до "рихтований", связанных с заменой кварца.
Ну и ладушки.

Вопрос: "Что еще критично к времени исполнения того-сего"?


Ответ: то, что связано с термодатчиком (напоминаю про "правила игры" 1-Wire
протокола).
В связи с этим, "орлиный взор" нужно направить на процедуру инициализации
термодатчика (так как "с нее начинается все сущее").
В ПП инициализации термодатчика, "фигурирует" одна-разъединственная ПП задержки с
названием PAUSE_X1.

6
И это не та универсальная задержка, о которой шла речь выше.
Она, если так можно выразиться, еще универсальнее.
В том смысле, что "на счетчик ставится" количество циклов отработки внутренней,
фиксированной задержки.
А раз это так, то нужно просто "подрихтовать" время отработки одного, внутреннего
цикла этой задержки.
То есть, с учетом времени исполнения одного "дочернего", машинного цикла (0,2 мкс.),
это время нужно сделать равным 10-ти микросекундам.
Было:

;================================================================================
; ПП задержки, кратной 10 мкс.
;================================================================================
; Задание количества проходов по 10 мкс.
;----------------------------------------
;;;PAUSE_X1 movwf Count ; W --> Count.
;----------------------------------------
; Задержка 10 мкс.
;----------------------------------------
;;;PAUSE_10 nop ;
;;; goto $+1 ; Одноразрядный,
;;; goto $+1 ; вычитающий
;;; goto $+1 ; счетчик
;;; decfsz Count,F ; с "врезкой".
;;; goto PAUSE_10 ;
;;; return ; Возврат по стеку.
;================================================================================

Стало:

;================================================================================
; ПП задержки, кратной 10 мкс.
;================================================================================
; Задание количества проходов по 10 мкс.
;----------------------------------------
PAUSE_X1 movwf Count ; W --> Count.
;----------------------------------------
; Задержка 10 мкс.
;----------------------------------------
PAUSE_10 movlw .15 ;
movwf Reg_1 ;
decfsz Reg_1,F ; Комбинированный,
goto $-1 ; вычитающий
nop ; счетчик.
decfsz Count,F ;
goto PAUSE_10 ;
return ; Возврат по стеку.
;================================================================================

После такой "рихтовки", в ПП инициализации термодатчика, значения времязадающих


констант изменять не нужно (в ПП DQ_INIT вообще ничего не меняется).
ПП задержки, с такой "конструкцией", выгодны в случаях изменения тактовой частоты
ПИКа. И тем выгоднее, чем большее количество раз они вызываются.
После этой доработки, ПП инициализации термодатчика будет "полноценно" работать.
Ну и прекрасно. "Двигаюсь" дальше.
"Просачиваюсь в сердцевину термодел" под названием ПП WIRE.
Перво-наперво нужно обеспечить фиксированные задержки величиной по 1-й мкс. каждая.
Это "мы уже проходили выше": все "материнские" NOPы "убиваются", а вместо них
"врезаются" вызовы (всего 4 штуки) ПП PAUSE_1MKS1 (так как именно она "лежит" на
2-й странице памяти программ).
Имеются переходы в ПП универсальной задержки (время задержки определяется
предустановленным содержимым W) с названием PAUSE_X2.

7
Это "мы, опять же, проходили выше": значения констант умножается на 5, и все дела.
А теперь по поводу этого (см. ПП TERMO):
.........................
.........................
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; Исполняется в случае превышения верхнего Т-порога.
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
PEREGREV .........................
.........................
;------------------------------------
; Определение начала цикла анализа.
;------------------------------------
movlw .50 ;
subwf Count1,W ; Count1 - .50 = ...
btfsc Status,Z ; Результат =0 или не=0
; (это начало цикла или нет?) ?
goto NORMA ; Если =0 (начало цикла), то обход сравнения
; Temp_LSB и Temp_LSB1.
; В остальных случаях, сравнение.
;------------------------------------
; Сравнение Temp_LSB и Temp_LSB1.
;------------------------------------
.........................
.........................

Числовое значение константы (выделена красным цветом) не изменилось.


Потому, что после коррекции задержек, время отработки цикла ПП TERMO (в случае
превышения верхнего Т-порога) изменилось очень незначительно.
Поэтому, "в силе остается такой расклад": увеличение/уменьшение числового значения
этой константы на .10, соответствует увеличению/уменьшению времени интервала
времени контроля за температурой, осуществляемого после срабатывания термозащиты,
примерно на 1 минуту.

Что касается "плавающей" задержки ПП WIRE, а также и вообще всех


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

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

8
Лично я, в подобных случаях пользуюсь мозгами, в комплексе с "зубодробильными
приемами" программно-аппаратного анализа (знание предельных, временных
характеристик того, что "вожделеется", обязательно!), "тормозом коммунизма" типа
goto $, "ехидными закольцовками" на "то-сё", "коварными" (по отношению к проблеме)
обходами того-сего" и т.д. (зависит от конкретных обстоятельств).
То же самое относится и к другим процедурам, "чувствительным" либо к времени
отработки каких-то их составных частей, либо к времени отработки процедуры в целом.

Выяснить можно абсолютно всё.

И это не поиск ответа на "скользкий" вопрос типа "что такое счастье?", а "дуэль"
между мозгами и достаточно "тупой" (по отношению к мозгам) "железякой", действия
которой абсолютно предсказуемы.
Лишь бы было желание и соответствующие возможности.
С желанием, обычно, проблем не возникает.
Проблемы возникают с возможностями.
Единственный способ избавления от этих проблем - целенаправленное улучшение
качества содержимого черепной коробки (Америку не открываю).
Советую разместить "вышележащее" утверждение (то, что в рамке) на Вашем рабочем
месте и почаще на него поглядывать. Хуже от этого не будет.
По поводу "интеллектуального удава".
Это просто один из возможных образов (выбрал потому, что удав исключительно
спокоен и дело свое знает), делающих жизнь интересной, а заодно и
"инициализирующих" такой "мощнейший инструмент", как подсознание.
Можно вспомнить, например, про бультерьера, волосатый кулак, сворачивание челюсти,
рога/копыта, шило в … и т.д.
Это уж Вы решайте сами.
Смысл же заключается не в абы каком, а в целенаправленном создании условий
успешной и абсолютно спокойной работы по "удавлению/загрызанию/стиранию в
порошок/… и т.д., той или иной проблемы.
Все это "упирается" в то, что я называю "интеллектуальной агрессией".
Ее и "проповедую".

Уменьшение инерционности срабатывания защиты по превышению порогов U/I


(иллюстрация принципа "интеллектуального удава").

Ну хорошо. Программа переведена на более высокую, тактовую частоту.


Вопрос: "Ради чего? Каковы девиденды от этого геморроя"?
Ответ: в данном случае, ради того, чтобы снизить инерционность срабатывания защиты
по превышению порогов U/I.
В случае успешного завершения этой "концессии", сие и есть "девиденды".
И по-моему, вполне приличные.
А раз это так, то возникает текущий вопрос: "Как конкретно это сделать, и на сколько
именно нужно обкарнать упомянутую выше инерционность"?
Ответ: наихудшая инерционность "карнается" путем уменьшения значения периода
ухода в прерывания. Однозначно.
При ответе на вторую часть вопроса, для того чтобы знать, "от чего плясать" в
дальнейшем (эти дела делаются "не с бухты-барахты"), нужно, после перевода
программы на более высокую тактовую частоту, определить интервал времени
отработки ПП прерывания.
Определяю.
Сразу же "упираюсь" в такой "суперважняк", как Tad.
Если оставить Tad прежним (Fosc/8), то значение Tad будет равно
1 / (20 000 000 Гц. : 8) = 0,4 мкс.
что "вообще не лезет ни в какие ворота", так как минимальное значение Tad = 1,6 мкс.
Следовательно, нужно перейти на Fosc/32 (особо не развыбираешься).
В этом случае,
9
Tad = 1 / (20 000 000 Гц. : 32) = 1,6 мкс.
Больше никак не получается, так как используется кварц с максимально допустимым
"номиналом", и в PIC16F873A, деления Fosc более чем на 32 не предусмотрено.
Забегая вперед, скажу, что такое значение Tad вполне приемлемо.
В том смысле, что "железяка", в части касающейся АЦП, работает вполне прилично.
В соответствии со сказанным, в ПП прерывания,

;;; movlw b'01001001' ; Включение модуля АЦП, выбор канала AN1


;;; movwf Adcon0 ; (RA1), источник тактового сигнала Fosc/8,
; состояние ожидания, конденсатор подключен
; к выбранному аналоговому входу и начал
; перезаряжаться.
заменяется на

movlw b'10001001' ; Включение модуля АЦП, выбор канала AN1


movwf Adcon0 ; (RA1), источник тактового сигнала Fosc/32,
; состояние ожидания, конденсатор подключен к
; выбранному аналоговому входу и начал
; перезаряжаться.

Следующий текущий вопрос: "Как быть с задержкой, обеспечивающей перезаряд


конденсатора Hold ?"
Ответ: ее нужно оставить прежней.
Конденсатору Hold "абсолютно наплевать" на любой такт, так как он вообще не из
этой "епархии" (между цифровым и аналоговым существует большая разница).
Если не предпринять никаких мер (величина этой задержки в разы меньше требуемой),
то при наличии более-менее быстрых изменений уровней напряжения, приведенного к
соответствующему входу канала АЦП, велика вероятность того, что этот канал просто
не успеет оперативно отследить динамику изменений этих уровней (за один уход в
прерывание, конденсатор Hold не успеет полностью перезарядиться), а это, как сами
понимаете, "пахнет" существенным увеличением инерционности срабатывания защиты.
Значит, так дело не пойдет и нужно подсуетиться.
То есть, в случае работы с кварцем номиналом 20 Мгц., нужно обеспечить время
перезаряда конденсатора Hold не меньшее, чем в случае работы с кварцем номиналом
4 Мгц.
Что и сделано.
Было так:
;================================================================================
; Задержка для обеспечения перезаряда конденсатора Hold.
;================================================================================
;;;PAUSE movlw .5 ; Стандартный,
;;; movwf Reg_1 ; вычитающий,
;;; decfsz Reg_1,F ; однобайтный
;;; goto $-1 ; счетчик.
;;; return ; Возврат по стеку.
;================================================================================

А стало так:
;================================================================================
; Задержка для обеспечения перезаряда конденсатора Hold.
;================================================================================
PAUSE movlw .25 ; Стандартный,
movwf Reg_Hold ; вычитающий,
decfsz Reg_Hold,F ; однобайтный
goto $-1 ; счетчик.
return ; Возврат по стеку.
;================================================================================

По принципу, описанному выше, числовое значение константы (а соответственно и


время отработки задержки) увеличено в 5 раз.
В этом случае, "байтность" счетчика наращивать не нужно (имеется большая "фора").

10
Так как, в связи с произведенными ранее изменениями, регистр Reg_1 задействован в
ПП задержки, не имеющей отношения к ПП прерывания, то под задержку,
обеспечивающую перезаряд конденсатора Hold, назначен/"прописан" регистр общего
назначения с названием Reg_Hold.
В соответствии с ранее сформулированной "концепцией", регистр Reg_Hold
используется только в этой задержке, и нигде более.
В MPLAB, проверяю время отработки "новорожденной" ПП PAUSE (в Options, нужно
выставить режим HS-генератора и номинал кварца 20 Мгц.).
Получились те же 16 мкс.
Ладушки.
В том же MPLAB, проверяю время "свершения" АЦП-преобразования.
Оно равно 19,6 мкс., что составляет 19,6 / 1,6 = 12,25 Tad, что вполне приемлемо.
По поводу последнего.
Радостная информация: MPLAB, при замере времени отработки "плавающей" задержки
(в секундомере), обеспечивающей "пережидание" процесса АЦП-преобразования, совсем
не "зависает" и "не проскакивает ее транзитом", а отмеряет ее строго по тем
"правилам игры", которые заданы разработчиками.
Можете проверить.
Это к вопросу о том, откуда взялось 19,6 мкс.
"Дебет-кредит": (16 + 19,6) х 2 = 71,2 мкс. "никуда не выкинешь". Это "святое".
"Сильно карнать" это "святое" никак нельзя. Так как "наказание" последует
незамедлительно.
"Гитлер капута" не будет, но будут неприятности, связанные с "враньем".
Это и есть "наказание".
Ладно. "Проехали". Никакого "наказания" не будет, так как "орлиный взор" это не
"хухры-мухры", а … (сами домыслите).
Что получается?
А получается то, что после перехода на Fкв. = 20 Мгц. и "соблюдения вышележащих
формальностей", время отработки ПП прерывания "находится где-то в районе"
86-ти микросекунд.
Значит, с учетом того, что и про "основное тело" программы забывать не нужно,
период ухода в прерывания вполне можно сократить с 200 мкс. до 100 мкс.
Вот именно ради этого и "проливалась вышележащая кровь".
А теперь, после того, как в мозгах имеет место быть полная ясность (в смысле того,
что именно нужно делать), все просто.
"Иду в ПИК-калькулятор" и жму кнопку "ШИМ".
Выставляю OSC = 20 Мгц., и частоту 10 Кгц.
Результат: Кдел. предделителя 1:4, PR2 = .124.
После этого, "вставляю все это добро" в ПП START (взамен "старью"):

;********************************************************************************
; НАЧАЛО ИСПОЛНЕНИЯ ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
START .........................
.........................
movlw b'00000101' ; Модуль TMR2 включен с Кдел. предделителя = 4
movwf T2CON ; и Кдел. выходного делителя = 1.
.........................
.........................
movlw .124 ; Задание периода ухода в
movwf PR2 ; прерывания =.124 (100 мкс., 10Кгц).
.........................
.........................

После этого, нужно не забыть произвести соответствующие числовые изменения в тех


"местах", в которых производится предустановка TMR2 (если такие предустановки есть).
Например:
.........................
.........................
11
clrf PCLATH ; Выбор 1-го блока 1-й страницы.
bsf Flag,3 ; Поднятие флага завершения смен надписей.
bsf Flag,2 ; Поднятие флага факта нажатия кнопки.
movlw .122 ; Обеспечение ухода в прерывание
movwf TMR2 ; сразу же после открытия транзистора.
bsf PortA,2 ; ОТКРЫТИЕ ТРАНЗИСТОРА.
goto HELP_1 ; Обход опроса кнопки "-/Нет".
.........................
.........................
И все дела.
В итоге, в "зоне" разрешения прерываний, обеспечены уходы в прерывания с
периодичностью в 100 мкс., а сразу же после отжатия кнопки "+/Да" (пуск), происходит
"оперативный" уход в прерывание.
Соответственно, частота ШИМ-сигнала управления вентиллятором повысилась c 5-ти до
10 Кгц., что позволяет значительно уменьшить емкость конденсатора С4 (см. рис. 1).
Естественно, что такой "глобальный катаклизм" отразится на времени полной отработки
тех циклов, находящихся в "зоне" разрешения прерываний, которые "поставлены на
счетчики".
Но это не беда, так как ничто не мешает скорректировать числовые значения
констант, задающих количество этих циклов.
В данном случае, это количество нужно уменьшать, так как "масса довеска" (100 – 86 =
14 мкс.), по сравнению с тем, что было, уменьшилась.
Это приводит к увеличению времени отработки тех процедур, которые, в "зоне"
разрешения прерываний, "поставлены на счетчики".
Вот и вся теория.
И никаких "трагедий" (знание - сила).
После осознания сказанного, нужно просто сократить количество циклов до
приемлемого (субъективный фактор).
Уменьшайте числовое значение константы, задающей количество внутренних циклов, и
смотрите на "железячный" результат этого уменьшения.
Если "ползет как черепаха", то уменьшайте еще.
Если "происходит переход на реактивный свист", то увеличивайте.
А как результат понравится, так и "СТОП-МАШИНА".
Например, в этом случае, ранее, задавалось 10 циклов, а теперь задается 7:
.........................
.........................
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая подпрограмма слежения.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
KOL_MOZALO bsf IntCon,7 ; РАЗРЕШЕНИЕ ПРЕРЫВАНИЙ.
movlw .7 ; Задание количества отрабатываемых циклов ПП
movwf Temp_1 ; MOZALO_1 (определяет интервал времени
; "высвечивания" надписи
; "РЕЖИМ СЛЕЖЕНИЯ / U=хх,x I=х,хха").
;================================================================================
.........................
.........................

А в этом случае, ранее, задавалось 200 циклов, а теперь задается 5:


.........................
.........................
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
; Процедура вывода на индикацию справочной надписи
; " Вкл. | нагрузки / кнопка "+/Да". "
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
movlw .5 ; Задание количества отрабатываемых циклов ПП
movwf Temp_1 ; MOZALO_2 (определяет интервал времени
; "высвечивания" надписи
; " Вкл. | нагрузки / кнопка "+/Да". ").
;================================================================================
.........................
.........................

12
Такой большой "разброс" объясняется тем, что после реализации сказанного выше, я
счел нужным произвести "временнУю корректировку" (чисто субъективный фактор), но в
любом случае, тенденция к уменьшению количества циклов прослеживается.
Итак, наихудшая инерционность защиты по превышению порогов U/I уменьшена c 200
до 100 мкс.
Обращаю Ваше внимание на то, что в течении этого достаточно короткого интервала
времени, в комплексе, "делаются и напряженческие, и токовые дела", и на то, что в
течение всего интервала времени нахождения в "рабочем" подрежиме режима
включенной защиты, никаких "подлых провалов защиты" нет и в помине.
То есть, в течение всего интервала времени работы в этом подрежиме, наихудшая
инерционность защиты по превышению порогов U/I, никогда не будет хуже 100 мкс.
За что и "пролито ведро крови".
И за это время, "железяка успевает засечь" такой объем информации, который
позволяет оценить основные "параметры бяки".
Можно и лучше. Но это уже "второе ведро".
Например, при работе только с током, инерционность срабатывания защиты по току
можно смело довести до 50-ти микросекунд.
А если как следует подсуетиться, то и того меньше (но уже не в разы, а поскромнее).
Но я пока занимаюсь "комплексными делами" (так замыслено). А там посмотрим …

"Модернизация" процедуры вывода на индикацию надписи "СЛУШАЮСЬ и


ПОВИНУЮСЬ!" (свидетельствует о "достижении взаимопонимания" пользователя и
"железяки") и расширение "сферы" ее применения.

После "воплощения в жизнь вышележащего", вполне можно что-нибудь


"замодернизировать".
"Жертву" долго искать не пришлось.
Это процедура вывода на индикацию надписи СЛУШАЮСЬ и ПОВИНУЮСЬ!
Она хороша тем, что ее появление свидетельствует о понимании "железякой"
"домогательств" пользователя.
Если отжать кнопку до появления этой надписи, то "железяка просто проигнорирует
приказ" ("моя твоя не понимайт").
Если отжать кнопку после появления этой надписи, то "железяка возьмет под козырек"
и все будет в полном порядке.
А плоха эта надпись тем, что она выводится на индикацию в каждом цикле той
процедуры, в состав которой она входит.
В связи с этим, напоминаю, что если кнопка не "жмется", надпись СЛУШАЮСЬ и
ПОВИНУЮСЬ! "проскакивает" так быстро, что визуально не ощущается.
Голос внутреннего цензора: "Что за каракатицу ты соорудил? Не стыдно"?
Ответ: стыдно, но частично. На 50%.
Так как сам принцип такого "проскакивания" вполне заслуживает внимания и может
быть применен в каких-то специфических случаях.
Но объективности ради, нужно согласиться, что в данном случае, это не есть "зер гут".
И в самом деле, зачем затягивать время отработки цикла процедуры, в состав которой
входит эта "каракатица", и зачем нужны, хотя и незначительные, но все-таки
"мерцания"?
Это и вообще, и в частности, не нужно.
Поза мыслителя … Как быть?
А очень просто: нужно "повырезАть" вызовы подпрограммы вывода на индикацию
надписи СЛУШАЮСЬ и ПОВИНУЮСЬ! из тех "неудачных мест", в которых они
находятся, и "поврезАть" их в "стыки" между опросами тех или иных кнопок и
"привязанными" к этим опросам, противодребезговыми задержками.
В этом случае, надпись СЛУШАЮСЬ и ПОВИНУЮСЬ! не будет выводиться на
индикацию на каждом цикле процедуры (как это было ранее), а она будет выводиться
на индикацию только в случае нажатия на ту кнопку, к которой она "привязана".
Кроме этого, процедура вывода на индикацию надписи СЛУШАЮСЬ и ПОВИНУЮСЬ!,
"по совместительству", будет исполнять функцию противодребезговой задержки.

13
В принципе, после такой "модернизации", "штатные", противодребезговые задержки
можно убрать, но я их все-таки оставил.
По соображениям обеспечения надежной работы "железяки" в случаях использования
кнопок, имеющих "повышенный уровень дребезга".
Например, в случае работы с кнопкой "+/Да", это будет выглядеть так (один из
случаев):
....................................
....................................
;--------------------------------------------------------------------------------
; Опрос кнопки "+/Да".
;--------------------------------------------------------------------------------
btfsc PortB,2 ; Кнопка "+/Да" нажата или отжата ?
goto OPR_NO ; Если отжата, то переход на опрос кнопки
; "-/Нет".
;--------------------------------------------------------------------------------
; Вывод на индикацию фиксированной надписи " СЛУШАЮСЬ и / ПОВИНУЮСЬ! ".
;--------------------------------------------------------------------------------
call SL_I_POVIN ; Переход в ПП вывода на индикацию
; этой надписи.
;--> Возврат по стеку из ПП SL_I_POVIN.
;-----------------------------------
; Противодребезговая задержка.
;-----------------------------------
call PAUSE_UI ; Переход в ПП PAUSE_UI.
;----> Возврат по стеку из ПП PAUSE_UI.
;-----------------------------------
; Ожидание отжатия кнопки.
;-----------------------------------
btfss PortB,2 ; Кнопка "+/Да" нажата или отжата ?
goto $-1 ; Если нажата, то ожидание отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
; Рабочие действия после отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
....................................
....................................

В случаях опросов других кнопок, принцип тот же самый, только будет опрашиваться
другая кнопка и вместо goto OPR_NO, будет goto на что-то другое.
В конечном итоге, получается "дешево и сердито": простой перенос вызова ПП
SL_I_POVIN "из одного места в другое" (немного ниже того, "где это стояло").
Далее, по ходу "терзания текущей проблемы", возникает следующее умозаключение:
"Надпись-то полезная/удобная. Почему она используется не во всех тех случаях, когда
ее можно использовать"?
Явный "прокол". Безобразие какое-то. Прямо зла не хватает.
Я бы себя за палец укусил, но здравый рассудок подсказывает, что нужно укусить не
его, а проблему.
Поэтому, начинаю усиленно ее (проблему) кусать.
.....................................................................
Всю искусал. Испугалась и убежала.
В той программе, которая прилагается к этому подразделу (BP_11.asm), мало того, что
вызов call SL_I_POVIN перенесен в указанное выше "место", но и организованы
дополнительные вызовы надписи СЛУШАЮСЬ и ПОВИНУЮСЬ! в тех "местах", в
которых ранее этих вызовов не было.
В конечном итоге, это закончилось тем, что эта надпись "высвечивается" при нажатии
различных кнопок.
Ее наличие свидетельствует о том, что "железяка восприняла команду", и после
отжатия кнопки, "с неизбежностью смен времени года", будет произведено
соответствующее, "рабочее" действие.
То есть, нажав на кнопку, нужно дождаться появление надписи СЛУШАЮСЬ и
ПОВИНУЮСЬ!, что является "указивкой" на то, что кнопку можно отжимать.
Исключением является только "внутренняя работа" в обеих подрежимах установки
порогов.
14
Так как в данных случаях, на мой взгляд, отсутствует практический смысл вывода на
индикацию этой надписи.

Организация ручного включения/выключения нагрузки (в обеих, основных


режимах), сопровождаемое подсказками.

Потребность в организации ручного включения/выключения нагрузки "продиктовано"


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

Flag_1 equ 3Ah ; Еще один регистр флагов:


; бит №7 - флаг срабатывания термозащиты.
; бит №6 - флаг ручного отключения нагрузки
; для сценария "ЗАЩИТА ВЫКЛЮЧЕНА".
; бит №5 - флаг ручного отключения нагрузки
; для сценария "ЗАЩИТА ВКЛЮЧЕНА".

Можно работать и с одним флагом, но с двумя, работать "программнопонятийно"


проще.
В части касающейся сценария "ЗАЩИТА ВЫКЛЮЧЕНА", сказанное, программно
организовано так:

;################################################################################
; ВЕРХНЯЯ "ОБСЛУГА" 1-й СТРАНИЦЫ. ###############################################
;################################################################################
...................................
...................................
15
; (1-я страница, 3-й блок памяти программ).
;-----------------------------------
; Надпись " Нагрузка "
;-----------------------------------
TEXT_35 addwf PC,F ; -----"-----
dt 0x20,0x20,0x20,0x20,0x48,0x61,0xB4,0x70
dt 0x79,0xB7,0xBA,0x61,0x20,0x20,0x20,0x20
;-----------------------------------
; Надпись " ОТКЛЮЧЕНА. "
;-----------------------------------
TEXT_36 addwf PC,F ; -----"-----
dt 0x20,0x20,0x20,0x4F,0x54,0x4B,0xA7,0xB0
dt 0xAB,0x45,0x48,0x41,0x2E,0x20,0x20,0x20
;-----------------------------------
; Надпись " ВКЛЮЧЕНА "
;-----------------------------------
TEXT_37 addwf PC,F ; -----"-----
dt 0x20,0x20,0x20,0x20,0x42,0x4B,0xA7,0xB0
dt 0xAB,0x45,0x48,0x41,0x20,0x20,0x20,0x20
...................................
;################################################################################
; КОНЕЦ ВЕРХНЕЙ "ОБСЛУГИ" 1-й СТРАНИЦЫ. #########################################
;################################################################################
...................................
...................................
...................................
...................................
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
; Сценарий "ЗАЩИТА ВЫКЛЮЧЕНА". VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
; Обеспечение "штатных" условий отработки сценария "ЗАЩИТА ВКЛЮЧЕНА", в случае
; дальнейшего перехода из сценария "ЗАЩИТА ВЫКЛЮЧЕНА" в сценарий
; "ЗАЩИТА ВКЛЮЧЕНА".
;--------------------------------------------------------------------------------

bcf Flag_1,5 ; Перевод флага ручного отключения нагрузки


; в состояние "нагрузка выключена".
...................................
...................................
;********************************************************************************
; Начало сценария-подсказки №4.
;********************************************************************************
; Опрос клавиатуры.
;================================================================================
; Опрос кнопки "+/Да".
;================================================================================
OBHOD_D btfss Flag_1,6 ; Каково состояние флага ручного отключения
; нагрузки ?
goto KN_NO_1 ; Если нагрузка ранее включена, то обход
; опроса кнопки "+/Да" (зачем подтверждать
; ранее установленное состояние?).
; Если выключена, то опрос кнопки "+/Да".
btfsc PortB,2 ; Кнопка "+/Да" нажата или отжата ?
goto KN_NO_1 ; Если отжата, то переход на опрос кнопки
; "-/Нет".
;--------------------------------------------------------------------------------
; Вывод на индикацию фиксированной надписи " СЛУШАЮСЬ и / ПОВИНУЮСЬ! ".
;--------------------------------------------------------------------------------
call SL_I_POVIN ; Переход в ПП вывода на индикацию этой
; надписи.
;--> Возврат по стеку из ПП SL_I_POVIN.
;-----------------------------------
; Противодребезговая задержка.
;-----------------------------------
call PAUSE_UI ; Переход в ПП PAUSE_UI.
;----> Возврат по стеку из ПП PAUSE_UI.
16
;-----------------------------------
; Ожидание отжатия кнопки.
;-----------------------------------
btfss PortB,2 ; Кнопка "+/Да" нажата или отжата ?
goto $-1 ; Если нажата, то ожидание отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
; Рабочее действие после отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
bcf Flag_1,6 ; Перевод флага ручного отключения нагрузки
; в состояние "нагрузка включена".
;================================================================================
; Вывод на индикацию, в 1-ю строку, фиксированной надписи " Нагрузка ".
;================================================================================
call NAGRUZKA ; Переход в ПП NAGRUZKA.
;--> Возврат по стеку из ПП NAGRUZKA.
;================================================================================
; Вывод на индикацию, во 2-ю строку, фиксированной надписи " ВКЛЮЧЕНА ".
;================================================================================
call N_VKL ; Переход в ПП N_VKL.
;--> Возврат по стеку из ПП N_VKL.
;================================================================================
; Обеспечение необходимого времени "высвечивания" надписи.
;================================================================================
call PAUSE_1SEK ; Задержка.
;----> Возврат по стеку из ПП PAUSE_1SEK.
;================================================================================
goto FINAL ; Обход опроса кнопки "-/Нет".
;================================================================================
; Опрос кнопки "-/Нет".
;================================================================================
KN_NO_1 btfsc Flag_1,6 ; Каково состояние флага ручного отключения
; нагрузки ?
goto FINAL ; Если нагрузка ранее выключена, то обход
; опроса кнопки "-/Нет" (зачем подтверждать
; ранее установленное состояние?).
; Если выключена, то опрос кнопки "-/Нет".
btfsc PortB,3 ; Кнопка "-/Нет" нажата или отжата ?
goto FINAL ; Если отжата, то переход на окончание
; цикла программы.
;--------------------------------------------------------------------------------
; Вывод на индикацию фиксированной надписи " СЛУШАЮСЬ и / ПОВИНУЮСЬ! ".
;--------------------------------------------------------------------------------
call SL_I_POVIN ; Переход в ПП вывода на индикацию этой
; надписи.
;--> Возврат по стеку из ПП SL_I_POVIN.
;-----------------------------------
; Противодребезговая задержка.
;-----------------------------------
call PAUSE_UI ; Переход в ПП PAUSE_UI.
;----> Возврат по стеку из ПП PAUSE_UI.
;-----------------------------------
; Ожидание отжатия кнопки.
;-----------------------------------
btfss PortB,3 ; Кнопка "-/Нет" нажата или отжата ?
goto $-1 ; Если нажата, то ожидание отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
; Рабочее действие после отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
bcf PortA,2 ; ЗАКРЫТИЕ ТРАНЗИСТОРА.
;================================================================================
; Вывод на индикацию, в 1-ю строку, фиксированной надписи " Нагрузка ".
;================================================================================
call NAGRUZKA ; Переход в ПП NAGRUZKA.
;--> Возврат по стеку из ПП NAGRUZKA.
;================================================================================
; Вывод на индикацию, во 2-ю строку, фиксированной надписи " ОТКЛЮЧЕНА. ".
17
;================================================================================
call N_OTKL ; Переход в ПП N_OTKL.
;--> Возврат по стеку из ПП N_OTKL.
;================================================================================
; Обеспечение необходимого времени "высвечивания" надписи.
;================================================================================
call PAUSE_1SEK ; Задержка.
;----> Возврат по стеку из ПП PAUSE_1SEK.
;================================================================================
bsf Flag_1,6 ; Перевод флага ручного отключения нагрузки
; в состояние "нагрузка выключена".
;--------------------------------------------------------------------------------
; Окончание цикла программы (для сценария "ЗАЩИТА ВЫКЛЮЧЕНА").
;--------------------------------------------------------------------------------
FINAL btfsc Flag_1,6 ; Ручное отключение нагрузки было или не было?
goto $+2 ; Если было, то ОТКРЫТИЯ ТРАНЗИСТОРА
; не происходит (обход).
bsf PortA,2 ; Если не было, то ОТКРЫТИЕ ТРАНЗИСТОРА
; происходит.
goto INKEY ; Переход на следующий цикл программы.
;********************************************************************************
...................................
...................................

Темно-синим цветом выделено то, о чем говорилось выше.


Предмет текущего разговора выделен красным цветом.

На "влете" в сценарий выключенной защиты, флаг ручного отключения нагрузки


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

OBHOD_D btfss Flag_1,6 ; Каково состояние флага ручного отключения


; нагрузки ?
goto KN_NO_1 ; Если нагрузка ранее включена, то обход
; опроса кнопки "+/Да" (зачем подтверждать
; ранее установленное состояние?).
; Если выключена, то опрос кнопки "+/Да".

Дело в том, что в предыдущем цикле этого сценария, в зависимости от того, какая из
кнопок "жалась" последней, флаг Flag_1,6 может быть установлен как в 0 (состояние
"нагрузка включена"), так и в 1 (состояние "нагрузка выключена").
В зависимости от этого, опрос кнопки "+/Да" либо может состояться (если имеет место
быть 1, то есть, нагрузка отключена), либо не соостояться (обход. Если имеет место
быть 0, то есть, нагрузка включена).
То же самое, но "с точностью до наоборот", относится и к опросу кнопки "-/Нет".
То есть, используется такая процедура анализа:

KN_NO_1 btfsc Flag_1,6 ; Каково состояние флага ручного отключения


18
; нагрузки ?
goto FINAL ; Если нагрузка ранее выключена, то обход
; опроса кнопки "-/Нет" (зачем подтверждать
; ранее установленное состояние?).
; Если выключена, то опрос кнопки "-/Нет".

Она, по отношению к первой, комплиментарна ("инверсна").


Вот Вам и "программные зачатки" RS-триггера.
Что получается?
А получается то, что если, например, нагрузка ранее была подключена, то все то, что
связано с кнопкой "+/Да", программно блокируется, и поэтому нет никакого смысла на
нее "жать" (конечно же можно, но будет "нулевая реакция").
Соответственно, заблокирована и возможность "дебильного" вывода на индикацию
надписей СЛУШАЮСЬ и ПОВИНУЮСЬ! и НАГРУЗКА ВКЛЮЧЕНА.
Кнопка "+/Да" будет программно разблокирована только после отключения нагрузки:
...................................
...................................
;================================================================================
; Опрос кнопки "-/Нет".
;================================================================================
...................................
...................................
bsf Flag_1,6 ; Перевод флага ручного отключения нагрузки
; в состояние "нагрузка выключена".
...................................
...................................

И это должно быть понятным, так как, если нагрузка отключена, то нужно обеспечить
дальнейшую возможность ее включения.
И наоборот.
Из этого "наоборот" следует то, что тоже самое относится и к кнопке "-/Нет", но
только в этом случае, "вышележащее как бы инвертируется".
Вот Вам и программный RS-триггер, имеющий два устойчивых состояния и
осуществляющий "рулежку" внутри довольно-таки "мощненьких" циклов.
В подобных случаях, понятийная сложность программной реализации такого RS-триггера
заключается в "разбросанности по циклу" его команд (их нужно "разместить не абы
как, а в нужных местах").
Но если как следует понять принцип, то конкретные "циклы по барабану".
Любому циклу "рога обломаете" (напоминаю про "властелина колец").
Желаю Вам достигнуть этой "нирваны".
Что касается вывода на индикацию надписей Нагрузка ВКЛЮЧЕНА и Нагрузка
ОТКЛЮЧЕНА (см. "вышележащие" картинки), то это делается в "Рабочих действиях
после отжатия кнопки".
Под это дело организованы 3 подпрограммы вычисляемых переходов (TEXT_35 … 37).
Вывод на индикацию - стандартный.
Так как процедуры вывода на индикацию этих надписей требуются более одного раза,
они вынесены в "обслугу".
Что касается сценария включенной защиты, то суть одна и та же.
Специфика заключается только в том, что в целях наиболее "экономной" (по
количеству команд), программной реализации RS-триггера, я "проинвертировал" (по
отношению к флагу ручного отключения нагрузки сценария выключенной защиты)
состояния флага ручного отключения нагрузки сценария включенной защиты.
То есть, включенному состоянию соответствовует не 0, а 1, а выключенному состоянию
соответствует не 1, а 0.
Таким образом, имеет место быть 2 программно реализованных RS-триггера, которые
взаимодействуют между собой.
Первая "половинка" этого взаимодействия "вышележит", а вторая его половинка такая:
...................................
...................................
;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; Сценарий "ЗАЩИТА ВКЛЮЧЕНА". |||||||||||||||||||||||||||||||||||||||||||||||||||
19
;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
...................................
...................................
;--------------------------------------------------------------------------------
; Обеспечение "штатных" условий отработки сценария "ЗАЩИТА ВЫКЛЮЧЕНА", в случае
; дальнейшего перехода из сценария "ЗАЩИТА ВКЛЮЧЕНА" в сценарий
; "ЗАЩИТА ВЫКЛЮЧЕНА".
;--------------------------------------------------------------------------------
bcf Flag_1,6 ; Перевод флага ручного отключения нагрузки
; в состояние "нагрузка включена".
...................................
...................................

Это нужно для того, чтобы в любом случае (по умолчанию), обеспечить включение
нагрузки после перехода из режима включенной защиты, в режим выключенной
защиты.
Если Вам такое "правило игры" не нравится (моя "самодеятельность"), то уберите эту
команду.
В этом случае, после возврата в режим выключенной защиты, факт включения или
выключения нагрузки будет определяться тем состоянием Flag_1,6, которое имело
место быть на момент предыдущего перехода из режима выключенной защиты в
режим включенной защиты (оперативная память).

Подсуетился на счет "наишустрейшего" закрытия транзистора при нажатии кнопки


"-/Нет".
Обращаю Ваше внимание на то, что речь идет не о закрытии транзистора после
отжатия этой кнопки, а о закрытии транзистора сразу же после ее нажатия.
Это "счастье" обеспечивается путем "врезки" команды bcf PortA,2 в цикл ожидания
отжатия кнопки "-/Нет":
...................................
...................................
;--------------------------------------------------------------------------------
; Опрос кнопки "-/Нет".
;--------------------------------------------------------------------------------
...................................
...................................
;-----------------------------------
; Ожидание отжатия кнопки.
;-----------------------------------
btfsc PortB,3 ; Кнопка "-/Нет" нажата или отжата ?
goto $+3 ; Если отжата, то выход из этой "пережидалки".
bcf PortA,2 ; Если нажата, то ЗАКРЫТИЕ ТРАНЗИСТОРА
goto $-3 ; и ожидание отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
; Рабочие действия после отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
...................................
...................................
Мелочь, а приятно … А заодно и полезно.

А теперь о "периферии". То есть, о внешних устройствах.


Очень хотелось бы, чтобы Вы осознали следующую аксиому: если "матка" (ПИК)
"просчитана от и до", то все "бяки", которые возможны, связаны только с
"периферией".
И особенно актуально это тогда, когда в состав этой "периферии" входят
операционные усилители (ОУ).
Эти "штуковины" имеют одну принеприятнейшую особенность: чем более коэффициент
усиления, тем более они склонны к самовозбуждению.
Обычно (но не всегда), с ОУ, имеющими Кус. = 1, проблем нет.
Но чем выше Кус., тем "бдительнее нужно держать ушки на макушке".
В рассматриваемом случае, нужно обратить самое пристальное внимание на D1.1
(см. рис. 1).
20
Совсем не факт, что самовозбуждение будет иметь место быть (зависит от многих
причин. Достаточно "мутная" тема), но оно вероятно, и поэтому нужно "быть в полной
боеготовности".
Также обращаю Ваше внимание на то, что существует вероятность ВЧ-наводок, тем
более искажающих результаты замеров того параметра, к которому "привязан" ОУ, чем
бОльший у него Кус и чем более не продуман монтаж.
Это намек на то, что монтаж должен быть капитально продуман.
D1, R4,5,6 лучше расположить подальше от кварца и конденсаторов, которые к нему
подключены.
Металлический корпус кварца совсем не помешает "посадить на минус".
В части касающейся выводов ПИКа с №№ 9,10, нужно сделать электрические
соединения как можно более короткими.
Не во всех, но во многих случаях, ВЧ-"бяку" можно "убить" путем подключения
конденсатора малой емкости (желательно не более 100 пф. Чем меньше, тем лучше)
между инвертирующим и неинвертирующим входами ОУ.
Существуют и другие способы "борьбы".
Я это говорю к тому, что "матка маткой" (она гораздо более предсказуема, так как
"цифирь есть цифирь"), но и от "периферии" многое зависит.
И если "она родом из аналоговой епархии", то "нужно держать ушки на макушке" и не
расхолаживаться.

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

22

Оценить