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

2-2/17.

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


замыкания. Организация ручной блокировки/разблокировки электрически
подключенного термодатчика и соответствующей "предупреждалки". Организация
"плавающего" 5-го пункта меню выбора порогов.

Присваиваю программе BP_12.asm статус "матери", и сразу же устремляю


упреждающий, орлиный взор на "ефрейторский суперзазорище".
Да … Маловата будет кольчужка.
Этого, для свершения текущего подвига, явно не достаточно.
Значит, для того чтобы не "нарваться на потенциальный Гитлер капут", нужно что-то
перенести с 1-й страницы памяти программ на 2-ю.
В соответствии с принципом, сформулированным ранее, ищу подходящую "кандидатуру".
Орлиный взор упирается в процедуру чтения, из EEPROM-памяти данных, значений
текущих порогов U/I (находится в сценарии включенной защиты).
Присваиваю соответствующей группе команд статус подпрограммы с названием
READ_UI, "укомплектовываю" ее командой return и "передислоцирую" ее в нижнюю
"обслугу" (вычисляемых переходов нет) 2-й страницы памяти программ ("прислоняю к
другой стенке").
В том "месте, где это стояло", настукиваю:
....................................
;================================================================================
; Чтение, из EEPROM, текущих порогов U/I.
;================================================================================
bsf PCLATH,3 ; Выбор 2-й страницы.
call READ_UI ; Переход в ПП чтения текущих порогов U/I.
;--> Возврат по стеку из ПП READ_UI.
clrf PCLATH ; Выбор 1-го блока 1-й страницы.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
; Циклическая подпрограмма слежения.
;CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
....................................

и будь здоров. В том смысле, что дело сделано.


Гляжу в окно ROM.
Ага … Полегчало. Но не совсем.
Так как "лимит безгеморройных переносов" потихоньку "стремится к нулю".
Вывод: почти весь текущий подвиг нужно свершать на 2-й странице памяти программ,
а на 1-й странице помещать только то, что помещать на 2-й странице "смертельно"/не
выгодно.
Вот Вам и четкая "ориентация на будущее" (в том числе и на далекое).
Обратите внимание на то, что эта "ориентация не свалилась с потолка", а
продумана/выстрадана "через пинки".
Вам эти "пинки" нужны?
Навряд ли. Это унижает. Значит, нужно учиться на ошибках других.
Итак, "местечко расчищено" и можно заняться улучшением инерционности
срабатывания защиты от короткого замыкания.
Перво-наперво нужно разрешить прерывания во всем "рабочем" цикле сценария
выключенной защиты, упреждающе запретив прерывания на время отработки ПП
TERMO.
До "выяснения текущих обстоятельств" (следствие ведут не абы какие, а русские
колобки). Что и сделано.
Нужно "прикинуть что к чему".
"Прикидываю".
Орлиный взор вынужденно/неумолимо/фатально уперся в ПП TERMO.
Поза мыслителя, пачка сигарет и литр кофе.
Да … Тяжелый случай.
Но извернуться можно (это к вопросу о преимуществах тренированной извилины).
Попробую объяснить.
В ПП WIRE, в некоторых ее "местах", за исключением фиксированных задержек (это
"святое"! Упаси Бог разрешать прерывания на время их отработки), можно
1
организовать "зоны" разрешения прерываний, но практического смысла в этом
маловато потому, что этих "зон" мало, они очень "тщедушны", и по этой причине
будут "проскакиваться с реактивным свистом" (напоминаю, что 1 м.ц. = 0,2 мкс.).
Конечно же, в этих "зонах", вероятность ухода в прерывания есть, но она, с учетом
"массивного", полного цикла ПП TERMO (сравните муравья со слоном), и не смотря на
то, что ПП WIRE отрабатывается многократно, очень мала.
По этой причине, на мой взгляд, с этим сейчас "связываться не стОит".
Хотя и можно. Но лучше позднее. Когда "жировать" можно будет.
Сейчас же нужно разобраться со "слоном", а "муравей пусть в очереди постоит"
(расстановка текущих приоритетов).
Речь идет о задержке, обеспечивающей "пережидание" температурного преобразования.
Именно время отработки этой задержки и составляет "львиную долю" цикла ПП
TERMO.
Вопрос: "Какая применена задержка"?
Ответ: "плавающая".
Вопрос: "Можно ли включить плавающую задержку в зону разрешения прерываний"?
Ответ: можно. Но только стандартную. Например такую, которая применяется в ПП
ENTER_BF для проверки состояния флага BF, а также и другие, аналогичные ей.
Но только не "плавающую" задержку, о которой идет речь.
Вопрос: "Почему"?
Ответ: потому, что она нестандартная. В цикл такой задержки входит та часть ПП WIRE,
в которой нельзя разрешать прерывания (см. goto WIRE).
Если разместить такую "плавающую" задержку в "зоне" разрешения прерываний и
принять меры, обеспечивающие запрет прерываний на время отработки этой части ПП
WIRE (а иначе всем термоделам будет "Гитлер капут"), то бОльшая часть этой
задержки будет отрабатываться в "зоне" запрета прерываний.
В данном случае, такая "плавающая" задержка и даром не нужна.
"Проливать за нее прерывательную кровь", по большому счету, бессмысленно
(выигрыш - копейки).
Эта задержка хороша (и даже очень) только в тех случаях, когда подпрограмма
работы с термодатчиком "не привязана к прерывательным делам" (то, что было "до того").
Вывод: "плавающую" задержку нужно заменить на фиксированную, так как
фиксированная задержка не имеет указанного выше недостатка, и ее смело можно
помещать в "зону" разрешения прерываний.
Ладушки. Так тому и быть.

Далее возникает хитрющая и коварнейшая проблема, связанная с организацией


"материального обеспечения" разрешения/запрета прерываний на 2-й странице памяти
программ.
Конечно же, прерывания можно разрешить/запретить на любой странице памяти
программ. С этим никаких проблем нет.
Речь идет о конкретной, программной специфике "безбякового" обеспечения оного.
"Разбор полетов".
Применяется PIC16F873A.
Ранее я обращал Ваше внимание на то, что в этом ПИКе, регистры общего
назначения 0-го банка не отображаются в 1-м банке (отображаются во 2-м).
Соответственно, в ПП прерывания, организованы процедуры сохранения/восстановления
содержимого регистров W и Status, "адаптированные" под эту специфику.
Это первое.
Второе.
Ранее, уходы в прерывания происходили только с 1-й страницы памяти программ и в
ПП прерывания нет вычисляемых переходов.
Поэтому практической необходимости, в сохранении/восстановлении содержимого
регистра PCLATH, не было.
В случаях же ухода в прерывания не только с 1-й, но и со 2-й страницы памяти
программ, эта необходимость возникает. И очень "мощно".
Все было бы прекрасно, если хотя бы часть регистров общего назначения 0-го банка
отображалась в 1-м банке (например, как в PIC16F876A), но в PIC16F873A этого нет
(булыжник в огород разработчиков).
2
В данном случае, это неизбежно привело к такому началу ПП прерывания:

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; ПОДПРОГРАММА ПРЕРЫВАНИЯ. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; Процедура сохранения содержимого регистров Status и W.
;================================================================================
; Определение банка, из которого осуществлен уход в прерывание.
;--------------------------------------------------------------------------------
btfsc Status,RP0 ; Из какого банка осуществлен уход
; в прерывание ?
goto BANK_1 ; Если это 1-й банк, то переход на метку
; BANK_1.
; Если это 0-й банк, то программа
; исполняется далее.

Обратите внимание на команду, выделенную красным цветом (первая по ходу


исполнения ПП прерывания).
Это команда goto, которая имеет 10-разрядную адресацию (и call тоже).
То есть, если в бите №3 регистра PCLATH имеет место быть 0, то команда goto
будет работать в пределах 1-й страницы памяти программ, а если в нем имеет место
быть 1, то команда goto будет работать в пределах 2-й страницы памяти программ.
В данном случае, команда goto "лежит" на 1-й странице памяти программ, и она
обращается к метке (BANK_1), которая тоже "лежит" на 1-й странице памяти программ.
Значит, если уход в прерывание произошел с 1-й страницы памяти программ, то
никаких проблем не будет.
В частности, если "влет" в прерывание происходит с 1-м банком, то переход на метку
BANK_1 будет успешно произведен.
Что и наблюдалось ранее.
А вот если уход в прерывание произойдет, например, из ПП TERMO, которая
"дислоцируется" на 2-й странице памяти программ, то будет "Гитлер капут".
В любом случае.
Даже в случае "влета" в ПП прерывания из 0-го банка (команда goto BANK_1
обходится).
Вопрос: "Почему"?
Ответ: потому, что в ПП прерывания имеется не одна команда goto, а несколько
(плюс, еще и call).
Ну "облапошили" (обошли) команду goto BANK_1, а остальные-то никак не
"облапошишь".
"Гитлер капут" наступит после исполнения первой же команды goto/call.
Однозначно, так как все команды goto/call подпрограммы прерывания "ориентированы"
на 1-ю страницу памяти программ, а в случае ухода в ПП прерывания из ПП TERMO,
в PCLATHе, если не принять "упреждающих мер", будет "выставлена" 2-я страница
памяти программ.
Вопрос: "А если это проигнорировать (не принять упреждающих мер), то что
произойдет"?
Ответ: в данном случае, рабочая точка программы "улетит" не на метку/ПП, к которой
обращается команда goto (call), а на ее (метки/ПП), если так можно выразиться,
"зеркальное отображение", находящееся на 2-й странице памяти программ ("совсем
другая опера").
При этом, "железяка сделает круглые глаза, икнёт, изумленно пукнет" (стресс) и
"выдаст на гора" такое, чего нет даже в кошмарном сне ("шизофрению". Если еще
живая).
Или вообще ничего не выдаст ("гроб и белые тапки").
Если человек не догадывается о первопричине оного, то я его искренне жалею.
Так как тяготею к гуманизму (поэтому и объясняю).
Вопрос: "Как быть"?
Ответ: первое, что приходит в голову, так это "доукомплектование" процедуры
сохранения/восстановления группой команд сохранения/восстановления содержимого
регистра PCLATH, причем, в данном случае, "ориентированную" на оба банка.
3
Это уже, как минимум, 8 команд.
Плюс, команда bcf PCLATH,3, которую обязательно нужно выставить перед goto ACP_1.
И это при обязательном условии ухода в ПП прерывания, из 2-й страницы памяти
программ, только из 0-го банка (обход команды goto BANK_1).
Иными словами, об универсальности речи не идет.
Можно и так, но только при этом увеличивается время отработки ПП прерывания
(потенциальная возможность дальнейшего снижения инерционности срабатывания
защиты по превышению порогов U/I становится более "дохлой"), что тут же "аукнется"
на времени отработки той части "основного тела" программы, которая находится в
"зоне" разрешения прерываний.
А если конкретно, то эта "часть" будет отрабатываться более медленно, что может
привести к "гемморою", связанному с корректировкой времени отработки нескольких
внутренних циклов.
Кроме того, все содержимое 1-й страницы памяти программ, "лежащее" ниже ПП
прерывания, сдвинется вниз.
В части касающейся вычисляемых переходов, это уже "на грани фола" (в первую
очередь, имеется ввиду 1-й блок 1-й страницы).

Еще один вариант, реализовав который, можно работать в обеих банках.


В случае ухода в ПП прерывания, из 2-й страницы памяти программ, с 1-м банком,
рабочая точка "сиганет" на "зеркальное отображение" метки BANK_1, находящееся в
начале 2-й страницы памяти программ.
Ну и пусть "сигает" на здоровье.
Нужно только просчитать адрес соответствующей ячейки памяти программ (находится
"в точке зеркального отображения") и "настукать" по этому адресу команду
bсf PCLATH,3 (так как нужно обеспечить возврат на 1-ю страницу), а затем
goto BANK_1.
Перед этим, чтобы "зеркально не наехать" на ПП вычисляемых переходов верхней
"обслуги" 2-й страницы, нужно сместить вниз все содержимое 2-й страницы, например,
с помощью NOPов.
Количество NOPов должно быть таковым, чтобы команда bcf PCLATH,3 установилась в
"точке зеркального отображения".
Но этот вариант имеет существенные недостатки.
Во-первых, его применение вполне может привести к необходимости "геморройного
перелопачивания" верхней "обслуги" 2-й страницы (там "дислоцируются привередливые"
ПП вычисляемых переходов).
Во-вторых, после любого "чиха", произведенного на 1-й странице, приводящего к
изменению количества команд того "куска" программы, который на ней "лежит", нужно
соответствующим образом корректировать смещение.
В-третьих, "разбазаривается моторесурс" памяти программ.
И он "разбазаривается" тем более, чем более отстоит, от 0-го адреса PC, то, на что
нужно перейти.
Плюс: сей "геморрой" можно использовать для защиты программы от
несанкционированного вмешательства в ее текст.
Достаточно всего плюс-минус одной команды (на 1-й странице памяти программ. По
отношению к "матери"), не говоря уж о бОльшем, чтобы программа "фатально дала
дуба" ("высший агент007пилотаж").
"Это дельце можно было бы провернуть", но я "ваяю" программу для друзей, а не для
врагов.

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

4
При этом, ПП прерывания "остается совершенно нетронутой" и можно уходить в
прерывания как с 0-го банка, так и с 1-го банка.
По сравнению с двумя предыдущими вариантами, "командного проигрыша" нет.
Условно/упрощенно говоря, в этом случае, нужно только организовать переход из
"пункта А" 2-й страницы, в "пункт Б" 1-й страницы (напоминаю про "ефрейторский
суперзазорище"), "зону" разрешения прерываний и возврат из "пункта Б" 1-й страницы
в "пункт А" 2-й страницы.
На мой взгляд, в данном случае, именно этот вариант и является наиболее
предпочтительным (субъективный выбор).
Его и реализовал.
Общее замечание: теоретически, я мог бы "выдать на гора" конечный результат и, как
говорится, будь здоров, но "внутренний цензор" не позволяет.
Говорит: "Придушу если ослушаешься".
Собственно говоря, я и не думаю перечить, так как осознаю его правоту.
И в самом деле, нужно же объяснить людям, почему именно так, а не эдак, а заодно
и показать "кухню" практической работы (без "мыльных пузырей" и "пены").
Последнее - самое главное.

В результате этих (а также и последующих) "словоблудий", а также и всяческих


сопутствующих экспериментов, родилось такое "творение":
...................................
...................................
;================================================================================
; ПП задержки, обеспечивающей "пережидание" температурного преобразования.
; Tзадержки, с учетом ухода в прерывания, примерно = 200000мкс.
;================================================================================
PAUSE_2 bsf IntCon,7 ; РАЗРЕШЕНИЕ ПРЕРЫВАНИЙ.
movlw .208 ;
movwf Reg_1 ; 750000 -> 105000 x 5 = 525000 мц 205-170-3
movlw .182 ; 600000 -> 84000 x 5 = 420000 мц 112-34-3
movwf Reg_2 ; 500000 -> 70000 x 5 = 350000 мц 136-199-2
;;; movlw .XXX ; 400000 -> 54000 x 5 = 280000 мц 159-108-2
;;; movwf Reg_3 ; 300000 -> 42000 x 5 = 210000 мц 183-17-2
; 200000 -> 28000 x 5 = 140000 мц 208-182
decfsz Reg_1,F ; 100000 -> 14000 x 5 = 70000 мц 231-91
goto $-1 ; 50000 -> 7000 x 5 = 35000 мц 115-46
decfsz Reg_2,F ; 25000 -> 3500 x 5 = 17500 мц 185-23
goto $-3 ; 10000 -> 1400 x 5 = 7000 мц 21-10
;;; decfsz Reg_3,F ; 5000 -> 700 x 5 = 3500 мц 138-5
;;; goto $-5 ; 1000 -> 140 x 5 = 700 мц 233
bcf IntCon,7 ; ЗАПРЕТ ПРЕРЫВАНИЙ.
return ; Возврат по стеку.
;################################################################################
; КОНЕЦ НИЖНЕЙ "ОБСЛУГИ" 1-й СТРАНИЦЫ. ##########################################
;################################################################################
...................................

;22222222222222222222222222222222222222222222222222222222222222222222222222222222
; 2-я СТРАНИЦА ПАМЯТИ ПРОГРАММ.
;22222222222222222222222222222222222222222222222222222222222222222222222222222222
...................................
...................................
;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
; ПП РАБОТЫ С ТЕРМОДАТЧИКОМ. DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
; "Администраторская" группа команд.
;================================================================================
TERMO call DQ_INIT ; Инициализация датчика.
;--->Возврат по стеку из ПП DQ_INIT
movlw 0CCh ; Выполнение команды
call WIRE ; "Skip_ROM".
;--->Возврат по стеку из ПП WIRE
movlw 44h ; Выполнение команды

5
call WIRE ; "Start_Conv".
;--->Возврат по стеку из ПП WIRE
;--------------------------------------------------------------------------------
; Анализ состояния флага "одноразовой" задержки.
;--------------------------------------------------------------------------------
btfsc Flag,0 ; Каково состояние флага
; "одноразовой" задержки ?
goto OBHOD_5 ; Если он поднят (1), то обход задержки.
; Если он опущен, то программа
; исполняется далее.
;--------------------------------------------------------------------------------
; "Одноразовая" задержка.
;--------------------------------------------------------------------------------
movlw .100 ; Reg_1=Reg_2=.100
movwf Reg_1 ; Reg_3:
movlw .100 ; .11 и менее -> хрень
movwf Reg_2 ; (2047759м.ц.*0,2=409551,8 мкс.)
movlw .20 ; .12 -> норма
movwf Reg_3 ; (2244881м.ц.*0,2=448976,2 мкс.)
; .20 -> использовано
; (382185м.ц.*0,2=764371,4 мкс.)
decfsz Reg_1,F ;
goto $-1 ; Стандартный,
decfsz Reg_2,F ; 3-байтный,
goto $-3 ; вычитающий
decfsz Reg_3,F ; счетчик.
goto $-5 ;
bsf Flag,0 ; Флаг "одноразовой" задержки поднимается.
;--------------------------------------------------------------------------------
; Ожидание окончания температурного преобразования.
;--------------------------------------------------------------------------------
OBHOD_5 bcf PCLATH,3 ; Выбор 1-й страницы.
call PAUSE_2 ; Переход в ПП PAUSE_2.
;--->Возврат по стеку из ПП PAUSE_2
bsf PCLATH,3 ; Выбор 2-й страницы.
;--------------------------------------------------------------------------------
call DQ_INIT ; Инициализация датчика.
;--->Возврат по стеку из ПП DQ_INIT
movlw 0CCh ; Выполнение команды
call WIRE ; "Skip_ROM".
;--->Возврат по стеку из ПП WIRE
movlw 0BEh ; Выполнение команды
call WIRE ; "Read_Scratchpad".
;--->Возврат по стеку из ПП WIRE
;--------------------------------------------------------------------------------
; Чтение младшего байта температуры.
;--------------------------------------------------------------------------------
...................................
...................................

Черным цветом выделено то, что осталось без изменений.


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

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

;;; bsf Flag,0 ; Поднятие флага исполнения/обхода


; "плавающей" задержки.
;;; call WIRE ; Исполнение процедуры 1-Wire протокола.
;--->Возврат по стеку из ПП WIRE
;;; bcf Flag,0 ; Сброс флага исполнения/обхода
; "плавающей" задержки.
удалена.

6
Хорошая была задержка. Интеллектуальная, изящная и уважаемая.
Ну не повезло ей. "Не попала в текущую струю".
Поэтому "убивать" ее рука не поднимается.
Будем считать, что она "ушла в заслуженный отпуск".
Примечание: флаг Flag,0 не удален. Он просто сменил функциональность (см. ниже).
Вместо "плавающей" задержки, применена стандартная, фиксированная задержка.
Ей присвоен статус подпрограммы с названием PAUSE_2, и в полном соответствии со
сказанным выше, она помещена на 1-й странице памяти программ (в нижней "обслуге").
В ПП PAUSE_2, организована "зона" разрешения прерываний.
Далее возникает уважаемый вопрос: "Какой должна быть величина этой задержки"?
И этот вопрос нельзя "непринужденно закидать шапками", так как задержка находится
в "зоне" разрешения прерываний.
То есть, рабочая точка программы будет из нее "отлучаться" с периодичностью
в 100 мкс.
Ранее, был "обнародован" такой практический результат: 100 мкс. = 86 мкс. + 14 мкс.
86 мкс. это приблизительное время отработки ПП прерывания.
14 мкс. это "довесок/хвостик", в течение которого происходит работа в "основном теле"
программы.
То есть, фиксированная задержка, "лежащая" в "зоне" разрешения прерываний, будет
отрабатываться "кусочно-рвано" (не за один, а за несколько приемов).
Соответственно, время отработки такой задержки будет бОльшим, чем ее рассчетное
время.
И тем бОльшим, чем меньшим будет "довесок/хвостик".
Почему?
Потому, что рассчетное время "ориентировано" на отработку задержки за один прием
(уходов в прерывания нет).
Значит, для того чтобы фиксированная задержка, "лежащая" в "зоне" разрешения
прерываний, отрабатывалась в течение заданного интервала времени, нужно сделать
ее меньшей, чем этот заданный интервал времени.
С поправкой на уход в прерывания (на конкретную ПП прерывания).
Вопрос: "Каковым должно быть числовое значение этой поправки (коэффициента)"?
Ответ: К = Tд/Тп
К - поправочный коэффициент.
Тд - время отработки "хвостика/довеска".
Тп - период ухода в прерывания.
Таким образом, в данном случае, К = 14/100 = 0,14
С учетом поправочного коэффициента, упрощенная формула для пересчета времени
фиксированной задержки, "лежащей" в "зоне" разрешения прерываний, будет выглядеть
так: Трасч х К = Tз
Трасч - рассчетное время отработки задержки. То есть, то время задержки (с учетом
уходов в прерывания), которое нужно обеспечить.
К - поправочный коэффициент.
Тз - время отработки задержки, которое нужно задать в программе.
Например, нужно обеспечить время отработки фиксированной задержки, "лежащей" в
"зоне" разрешения прерываний, равное 500 000 мкс. (Трасч).
500 000 мкс. х 0,14 = 70 000 мкс.
Проверка:
500 000 мкс. / 100 мкс. = 5 000 уходов в прерывания.
За счет отработки этих 5 000 прерываний, будет осуществлена задержка величиной
5 000 х 86 мкс. = 430 000 мкс.
А за счет отработки 5 000 "хвостиков/довесков", будет осуществлена задержка
величиной 5 000 х 14 мкс. = 70 000 мкс.
430 000 мкс. + 70 000 мкс. = 500 000 мкс.
Все сходится.
Непосредственно к ПП задержки относится второе (70 000 мкс.).
Значит, нужно "состряпать" фиксированную задержку величиной 70 000 мкс.
То есть, с учетом применяемого кварца (Fкв = 20 Мгц), в программе Николая Марова,
нужно задать
70 000 мкс. х 5 = 350 000 машинных циклов
7
Этому соответствуют константы .136 - .199 - .2 (расположены в порядке возрастания
старшинства).
В данном случае (100=86+14), задержка с такими "параметрами", с учетом того, что
она "лежит" в "зоне" разрешения прерываний, будет отработана примерно за
500 000 мкс.
Точно таким же образом можно рассчитать и Тз для других значений Трасч, а затем
осуществить перевод в машинные циклы.
Что я и сделал для Вашего удобства (см. "вышележащий кусок" программы).
Вопрос: "Какое именно Трасч выбрать"?
Ответ: эту проблему, по причине ее серьезности, нужно капитальнейшим образом
"провентиллировать".
"Провентиллировал" и сильно удивился. Аж "челюсть об пол стукнулась".
Сейчас будет что-то типа детектива (с техническим уклоном).
После практической реализации "вышележащего", "прошивки" ПИКа и включения
"железяки", начала срабатывать защита по превышению верхнего Т-порога
("Караул! Убивают!" и т.д.).
При этом, "высвечивалось" текущее значение температуры равное 85-ти градусам, что
выше верхнего Т-порога, заданного в EEPROM-памяти данных по умолчанию
(80 градусов).
Поэтому и термозащита добросовестно сработала.
Молодец!!! Умница!!! Свое дело четко знает. Казенный хлеб не даром кушает.
И эта "бяка" наблюдалась только в первом цикле сценария-подсказки.
В конце второго цикла этого сценария (после 2-го замера температуры, которая была
в норме), происходила "штатная", автоматическая разблокировка, и в дальнейшем,
"температурные дела" были в полном порядке.
Это что-то подозрительно напоминает.
Вызываю летающую корову по кличке "Термодатчица" и начинаю ее "доить".
Ба … Точно. Показание величиной 85 градусов есть верный признак "глюка"
температурного преобразования.
В том смысле, что оно, в 1-м цикле, "не свершилось как положено".
Но потом-то (от 2-го цикла и далее) свершилось.
Вопрос: "Почему раньше такого не было"?
Ответ: потому, что работала "плавающая" задержка.
Вопрос: "Почему это сейчас имеет место быть"?
Ответ: потому, что работает фиксированная задержка и в наличии имеется классная
"бякозасекалка" (ценой в "литр не даром пролитой крови"), которая четко сработала.
Если бы ее не было, то так и остался бы в неведении.
Ведь что такое 1-й цикл?
Это то, чему обычно не придается значения, ведь потом-то все в полном порядке.
Вроде как и совсем не смертельно, но в данном-то случае, по причине срабатывания
термозащиты, с этим мириться нельзя.
Даже с учетом того, что в дальнейшем произойдет авторазблокировка.
По факту, халтура получается.
Думаю, что пользователю это не понравится (и мне тоже не нравится).
Значит, так дело не пойдет.
Так как стараниями разработчиков, в этом вопросе, имеет место быть полный "туман",
мне вынужденно пришлось поэкспериментировать.
"Стряпаю" еще одну фиксированную задержку, с заведомо большИм временем
отработки (3 байта, "забитые под завязку"), и делаю так, чтобы она отрабатывалась
только при первом (после включения питания) "влете" в ПП TERMO.
Делается это очень просто: при помощи флага Flag,0, ведь он, после отказа от
"плавающей" задержки, "свободен как ветер в поле".
Просто изменяется его функциональность, и все дела.
При первом "влете" в ПП TERMO, в бите №0 регистра Flag "лежит" 0 (все биты этого
регистра, в ПП START, устанавливаются в 0).
Перед началом отработки задержки, состояние этого бита анализируется.
Если он установлен в 0, то задержка отрабатывается (это происходит только при 1-м
"влете").
В конце задержки производится установка Flag,0 в 1.
8
После этого, вплоть до выключения питания, задержка будет обходиться.
После "экспериментального врезания" всего этого "безобразия" в различные "места"
(любопытно же!), выяснилось то, что "вышележащая бяка" не есть результат
неисполнения команд Skip_ROM и Start_Conv.
Они исполняются четко.
"Бяка" есть результат первого, после включения питания, температурного
преобразования.
О причинах оного можно только гадать.
С одной стороны, шунтирующее действие "паразитного" конденсатора, на линию DQ,
вроде как и не при чем (команды Skip_ROM и Start_Conv исполняются), а с другой
стороны, все это "безобразие" сильно смахивает на нечто, связанное с зарядом
изначально разряженного конденсатора (гипотеза).
А именно, если выключить питание, дождаться сброса (BOR) и сразу же после этого
включить питание, то "бяки" не будет, а если выключить питание, достаточно долго
подождать, а затем включить питание, то "бяка" есть.
Поэкспериментировал с величиной этой "одноразовой" задержки.
Выяснилось, что для того чтобы, в 1-м цикле, температурное преобразование
произошло успешно, нужна задержка величиной, примерно, не менее 450 000 мкс.
("пыткам" подвергался тот DS1820, который у меня имеется).
А если учесть разброс параметров и перестраховку разработчиков, то становится
понятным, откуда взялось наихудшее время температурного преобразования величиной
750 мс.
Примерно такое время (с запасом) и выставил.
Обращаю Ваше внимание на то, что речь идет о задержке, которая отрабатывается
один раз (за одно включение питания) и которая не находится в "зоне" разрешения
прерываний (отрабатывается за один прием).
Теперь, направляю орлиный взор на задержку, обеспечивающую "пережидание"
температурного преобразования (ПП PAUSE_2).
Так как, в этих вопросах, я любопытен до совершеннейшего неприличия, то решил
выяснить, каковой именно является минимальная задержка, обеспечивающая
"полноценную" конвертацию.
Начинаю последовательно уменьшать ее значение и смотрю, что из этого выходит.
После того, как я дошел до 1000 мкс., глаза значительно округлились.
После того, как я вообще заблокировал исполнение ПП PAUSE_2 и после этого
увидел точно такое же показание температуры, как и в случае задержки в 750 000
мкс., "моя челюсть стукнулась об пол".
Сначала подумал что грешным делом что-то "напартачил" с "одноразовой" задержкой,
и она исполняется не только в 1-м, но и в каждом цикле.
Блокирую ее исполнение.
После "Караул! Убивают!" (и т.д. В 1-м цикле "высвечиваются" те же 85 градусов) и
и последующей, автоматической разблокировки ("одноразовая" задержка работает четко,
и она "не при чем"), наблюдаю то же самое (конвертация происходит без ошибок).
И это не "мистика", так как, по мере уменьшения величины задержки PAUSE_2,
абсолютно четко наблюдается увеличение скорости смены показаний.
Это что же такое, братцы, получается?
Если обеспечить "одноразовую" задержку величиной 750 000 мкс. (можно и поменьше,
но пусть будет так. Для определенности), то можно сделать "пережидание" интервала
времени температурного преобразования очень малым, вплоть до отказа от такого
"пережидания".
В соответствии с тем, что я наблюдал собственными глазами (и Вы тоже можете это
увидеть), получается именно так.
Но ведь это же существенное увеличения скорости замеров температуры, а
соответственно и уменьшение инерционности срабатывания термозащиты!
И еще "куча полезностей впридачу".
Это же целая "DSтермореволюция"!
Например, за одно и то же время, можно опросить гораздо бОльшее количество
датчиков, чем при "стандартном подходе", или значительно уменьшить время опроса
фиксированного количества датчиков.

9
Сие заявление очень серьезно, и по этой причине, его нужно как следует
"поприслонять к разнообразнейшим стенкам".
Надеюсь что в будущем, коллективными усилиями, мы в этом как следует разберемся.
А пока, делаю интервал времени отработки задержки PAUSE_2 приблизительно равным
200 000 мкс. (с учетом уходов в прерывания).
Так как 200 000 мкс. является "официальным", типовым значением времени "свершения"
температурного преобразования (не могу удержаться от иронии).
С учетом сказанного, эта задержка нужна не столько для обеспечения температурного
преобразования, сколько для задания приемлемой скорости смены показаний и
увеличения соотношения времени нахождения рабочей точки программы в "зонах"
разрешения прерываний к времени ее нахождения в "зонах" запрета прерываний (в
комплексе).
Можно выставить и другую величину этой задержки (для Вашего удобства, некоторые
варианты "разрисованы" в ПП PAUSE_2).
Если задержка большАя (3 константы), то нужно разблокировать те 4 команды,
которые выделены серым цветом, а если малая (1 константа), то нужно
заблокировать еще 4 команды, работающие с регистром Reg_2.
Короче, экспериментируйте. Все условия для этого созданы.
И направление "вектора усилий" обозначено.
В перспективе, используя "вышележащее", имеется вполне реальная возможность
создания быстрых (качественных) "DSтермоподпрограмм".

Теперь о задержках ПП DQ_INIT.


Имеется такой "расклад": 600 мкс. - 70 мкс. - 500 мкс.
600 мкс. - длительность формирование 0-го уровня.
70 мкс. - задержка перед опросом состояния линии DQ.
500 мкс. - длительность задержки после опроса состояния линии DQ.
Значение длительности формирования 0-го уровня можно уменьшить с 600 до 500 мкс.,
так как в худшем случае, это значение не превышает 480 мкс. (см. даташит на DS…).
Задержку перед опросом состояния линии DQ лучше "не трогать". Она в норме.
Значение длительности задержки после опроса состояния линии DQ можно уменьшить
с 500 до 250 мкс., так как в худшем случае, это значение не превышает 240 мкс. (см.
даташит на DS…).
Получилось это:
;...................................
;...................................
;################################################################################
; НИЖНЯЯ "ОБСЛУГА" 2-й СТРАНИЦЫ.
;################################################################################
; Инициализация термодатчика.
;================================================================================
; Установка на линии DQ 1.
;-----------------------------------
DQ_INIT call PIN_HI ; Установка вывода в высокоимпедансное
; состояние: за счет подтягивающего резистора,
; на линии устанавливается 1.
;----> Возврат по стеку из ПП PIN_HI.
;-----------------------------------
; Установка на линии DQ 0.
;-----------------------------------
call PIN_LO ; Установка на линии DQ нуля.
;----> Возврат по стеку из ПП PIN_LO.
;-----------------------------------
; Задержка 500 мкс.
;-----------------------------------
movlw .50 ; Установка количества проходов по 10мкс.
; (было .60)
call PAUSE_X1 ; Переход в ПП задержки(задержка=50х10=500мкс)
;----> Возврат по стеку из ПП PAUSE_X1.
;-----------------------------------
; Установка на линии DQ 1.
;-----------------------------------
10
call PIN_HI ; Установка вывода в высокоимпедансное
; состояние: за счет подтягивающего резистора,
; на линии устанавливается 1.
;----> Возврат по стеку из ПП PIN_HI.
;-----------------------------------
; Задержка 70 мкс.
;-----------------------------------
movlw .7 ; Установка количества проходов по 10мкс.
call PAUSE_X1 ; Переход в ПП задержки (задержка=7х10=70мкс.)
;----> Возврат по стеку из ПП PAUSE_X1.
;--------------------------------------------------------------------------------
; Определение наличия (или нет) отклика на импульс сброса.
;--------------------------------------------------------------------------------
btfsc PortC,DQ ; На линии DQ 0 или 1 (отклик есть или нет)?
bsf Flag,1 ; Если отклика нет (1), то флаг наличия
; термодатчика поднимается.
; Если отклик есть (0), то флаг наличия
; термодатчика остается опущенным и программа
; исполняется далее.
;-----------------------------------
; Задержка 250 мкс.
;-----------------------------------
movlw .25 ; Установка количества проходов по 10мкс.
; (было .50)
call PAUSE_X1 ; Переход в ПП задержки(задержка=25х10=250мкс)
;----> Возврат по стеку из ПП PAUSE_X1.
return ; Возврат по стеку.

;WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
; ПРОЦЕДУРА 1-WIRE ПРОТОКОЛА.
;WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
;...................................
;...................................

Изменения выделены красным цветом.


В результате этой простенькой "комбинации из двух пальцев", не приводящей к
"термобякам", цикл ПП DQ_INIT сокращается на 350 мкс.
В одном цикле ПП TERMO, ПП DQ_INIT исполняется 2 раза.
Вот Вам и выигрыш в 700 мкс.
То есть, время отработки одного цикла ПП TERMO уменьшилось аж на 700 мкс.
Это к вопросу о пользе знания предельных временнЫх характеристик.
Пока хватит. Спешить не нужно.
В том смысле, что соответствующим образом включить эти 2 задержки в "зоны"
разрешения прерываний, можно в любой момент.
Посмотрим, как в дальнейшем, на 1-й странице памяти программ, будут обстоять дела
со "свободным местечком" и прочее (типа "стоит ли овчинка выделки"?).

А пока, по здравому разумению, выгоднее ориентироваться на более "глобальное".


Рассуждаю.
Вопрос: "Можно ли, без "заморочек" с прерываниями, существенно улучшить
инерционность срабатывания защиты от КЗ"?
Ответ: можно, если обойти вызовы ПП TERMO.
Это соответствует "принудительной", программной блокировке подключенного
термодатчика (электрически отключать его не нужно).
То есть, речь идет об организации некой ручной блокировки/разблокировки
термодатчика.
Заблокировать его или разблокировать, решает пользователь.
Если термодатчик заблокировать, то скорость срабатывания защиты от КЗ будет
высокой (условно), но термозащита работать не будет (вентиллятор переходит на
программно заданное количество оборотов).
Если термодатчик разблокировать, то термозащита работать будет, но скорость
срабатывания защиты от КЗ будет не такой высокой, как в предыдущем случае.

11
То есть, пользователю предлагается возможность свободного выбора "того-сего", что,
на мой взгляд, должным образом будет им оценено (для кого работаем?).
А раз это так, то и все средства хороши.
Правда, нужно признать, что такого рода работа есть дополнительный "геморрой" для
конструктора, но это его личные проблемы (а кому сейчас легко?).
Подвиг свершить, это не в свисток дунуть (да здравствует Мюнхаузен!).
Вердикт: так тому и быть.
Реализую.
1-й этап работы
По ехидному (по отношению к проблеме) принципу "раскручивания цепочки", перво-
наперво, нужно "состряпать" дополнительный, 5-й пункт меню выбора порогов, ведь
именно с его выбора и начинается вся "свистопляска".
То есть, нужно организовать вывод на индикацию соответствующей надписи и "уход в
нечто", если кнопка "Установка порогов" отжимается в интервале времени этого
"высвечивания", а также и переход в следующий пункт меню, если эта кнопка не
отжимается.
В данном случае, в 1-й строке ЖК-модуля, это надпись Термодатчик (уже имеется и
ничего выдумывать не нужно), а во 2-й строке, это надпись ВКЛ. ОТКЛ. (а вот ее
нужно организовать).
На мой взгляд, будет логичным вывести на индикацию эту надпись после надписи 3-го
пункта меню, то есть, после надписи Задание порогов / защиты от КЗ.
Таким образом, процедуру вывода на индикацию надписи Термодатчик / ВКЛ. ОТКЛ.
нужно "врезать" между процедурами вывода на индикацию надписей
Задание порогов / защиты от КЗ и Возврат / из режима.
Программно, это выглядит так:
;...................................
;...................................
;################################################################################
; ВЕРХНЯЯ "ОБСЛУГА" 1-й СТРАНИЦЫ. ###############################################
;################################################################################
;...................................
;...................................
;-----------------------------------
; Надпись " Термодатчик "
;-----------------------------------
TEXT_19 addwf PC,F ; -----"-----
dt 0x20,0x20,0x54,0x65,0x70,0xBC,0x6F,0xE3
dt 0x61,0xBF,0xC0,0xB8,0xBA,0x20,0x20,0x20
;...................................
;...................................
;################################################################################
; КОНЕЦ ВЕРХНЕЙ "ОБСЛУГИ" 1-й СТРАНИЦЫ. #########################################
;################################################################################
;...................................
;...................................
;...................................
;...................................
;22222222222222222222222222222222222222222222222222222222222222222222222222222222
; 2-я СТРАНИЦА ПАМЯТИ ПРОГРАММ.
;################################################################################
; ВЕРХНЯЯ "ОБСЛУГА" 2-й СТРАНИЦЫ. ###############################################
;################################################################################
;...................................
;...................................
;-----------------------------------
; Надпись " ВКЛ. ОТКЛ."
;-----------------------------------
TEXT_43 addwf PC,F ; -----"-----
dt 0x20,0x42,0x4B,0xA7,0x2E,0x20,0x20,0x20
dt 0x20,0x20,0x20,0x4F,0x54,0x4B,0xA7,0x2E
;...................................
;...................................
;################################################################################
12
; КОНЕЦ ВЕРХНЕЙ "ОБСЛУГИ" 2-й СТРАНИЦЫ. #########################################
;################################################################################

;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
; ПП РАБОТЫ С ТЕРМОДАТЧИКОМ. DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
;...................................
;...................................
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
; ПП УСТАНОВКИ КЗ-ПОРОГА.
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
;...................................
;...................................
;================================================================================
; Анализ состояния флага блокировки 4-го пункта меню.
;================================================================================
btfsc Flag_1,4 ; Каково состояние флага ?
goto VOZVRAT ; Если поднят, то 4-й пункт меню
; не выводится на индикацию.
; Если опущен, то выводится.
;================================================================================
; Вывод на индикацию, в 1-ю строку, фиксированной надписи " Термодатчик ".
;================================================================================
movlw .35 ; Задание времени (количества циклов)
movwf Temp ; "высвечивания" надписи " Термодатчик ".

SNOVA_7 movlw b'10000000' ; Установка курсора в крайнее


call ENTER_BF_1 ; левое знакоместо 1-й строки.
movlw .16 ;
movwf Count ;
movlw high TEXT_19; Выбор PCH 1-й команды ПП TEXT_19
movwf PCLATH ; (находится во 2-м блоке 1-й страницы).
movf Count,W ;
sublw .16 ; Аналогично, только
call TEXT_19 ; для TEXT_19.
bsf PortC,RS ;
bsf PCLATH,3 ; Переход на 2-ю страницу.
call ENTER_BF_1 ;
decfsz Count,F ;
goto $-9 ;
;================================================================================
; Вывод на индикацию, в 2-ю строку, фиксированной надписи " ВКЛ. ОТКЛ.".
;================================================================================
movlw high TEXT_43; Выбор PCH 1-й команды ПП TEXT_43
movwf PCLATH ; (находится во 1-м блоке 2-й страницы).
movlw b'11000000' ; Установка курсора в крайнее
call ENTER_BF_1 ; левое знакоместо 2-й строки.
movlw .16 ;
movwf Count ;
movf Count,W ;
sublw .16 ; Аналогично, только
call TEXT_43 ; для TEXT_43.
bsf PortC,RS ;
call ENTER_BF_1 ;
decfsz Count,F ;
goto $-6 ;
;--------------------------------------------------------------------------------
; Пауза между циклами вывода на индикацию.
;--------------------------------------------------------------------------------
call PAUSE_UI_1 ; Переход в ПП PAUSE_UI_1.
;----> Возврат по стеку из ПП PAUSE_UI_1.
;--------------------------------------------------------------------------------
; Счет циклов.
;--------------------------------------------------------------------------------
btfsc PortB,1 ; Кнопка "Установка порогов" нажата
; или отжата ?
13
goto T_DATCHIK ; Если отжата, то переход в ПП
; включения/отключения термодатчика.
decfsz Temp,F ; Если нажата, то цикл вывода надписи
; "Термодатчик/ВКЛ. ОТКЛ." повторяется
goto SNOVA_7 ; до тех пор, пока счетчик не обнулится.
; После этого, программа исполняется далее.
;================================================================================
; Вывод на индикацию, в 1-ю строку, фиксированной надписи " Возврат ".
;================================================================================
VOZVRAT
;...................................
;...................................
;================================================================================
; Вывод на индикацию, в 2-ю строку, фиксированной надписи " из режима ".
;================================================================================
;...................................
;...................................
;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
; Подпрограмма включения/отключения термодатчика.
;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
T_DATCHIK
;...................................
;...................................
А визуально, этот пункт меню выглядит так (см.
картинку слева).
Под надпись ВКЛ. ОТКЛ. организована ПП
вычисляемого перехода TEXT_43.
С учетом сказанного ранее, в этом нет ничего
нового: банальное повторение ранее отработанной
стратегии (см. "механику" реализации других пунктов
меню).
Естественно, что с тактическими поправками на то, куда осуществляются переходы.
Если отжатие кнопки "Установка порогов" произойдет во время "высвечивания" надписи
Термодатчик / ВКЛ. ОТКЛ., то произойдет переход в ПП T_DATCHIK (намек на
термодатчик).
Особенность.
Обратите внимание на две команды, выделенные красным цветом.
Если их не будет, то в случае электрически отключенного термодатчика (если он
отсутствует), возможна следующая "бяка".
В случае установки маркера (о маркере - см. ниже) на надписи ВКЛ. (получается, что
программно включен датчик, которого нет) и возврата из меню выбора порогов,
сработает термозащита, рабочая точка "намертво закольцуется" в соответствующем
сценарии и на индикацию будет выведена температурная "кракозябра".
И все это "безобразие" никак нельзя будет прекратить (проверил лично). "Мертвяк".
Пресечь его можно несколькими способами.
Я выбрал, на мой взгляд, самый простой и эффективный.
Организую флаг блокировки 4-го пункта меню (Flag_1,4) и поднимаю его после вывода
на индикацию надписи Термодатчик ОТКЛЮЧЕН.
Во всех остальных случаях, он опущен (в ПП START, Flag_1 сбрасывается в 0).
В начале отработки 4-го пункта меню, анализируется его состояние.
Если флаг опущен (0), то этот пункт меню отрабатывается, а если поднят (1), то
обходится.
Последнее соответствует исключению, из меню выбора порогов, одного пункта (нет его.
Моль съела. 4 пункта вместо 5-ти).
То есть, речь идет о специфическом пункте меню, который можно назвать как бы
"плавающим".
И все это делается автоматически.
То есть, "железяка сама решает", включать в состав меню этот пункт или не включать.
И в самом деле, если этот пункт не работает и от него одни неприятности
(рудимент/атавизм), то зачем он нужен (зачем зайцу лыжи? Одна морока)?
"Вырезать этот аппендицит", и все дела.
14
На мой взгляд, "дешево, мозговито и сердито".
Итак, 1-й этап текущей работы закончен: организован соответствующий пункт меню и
"предприняты упреждающие меры".
2-й этап работы
Нужно "состряпать" ПП T_DATCHIK.
В ней, нужно озаботиться "маркерными делами".
То есть, после перехода в ПП T_DATCHIK, на индикацию должен быть выведен
маркер, указывающий на то, включен датчик или отключен.
Применяется тот же символ маркера, который применялся и ранее.
Я сделал так, что он "высвечивается" либо слева от надписи ВКЛ., либо слева от
надписи ОТКЛ.
Таким образом, речь идет об одной из разновидностей настройки "железяки",
"координаты" которой совсем не грех запомнить в EEPROM-памяти данных
(энергонезависимая настройка).
Так тому и быть.
Получилось сие "творение":
;...................................
;...................................
;22222222222222222222222222222222222222222222222222222222222222222222222222222222
; 2-я СТРАНИЦА ПАМЯТИ ПРОГРАММ.
;22222222222222222222222222222222222222222222222222222222222222222222222222222222
;...................................
;...................................
;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
; Подпрограмма включения/отключения термодатчика.
;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
; Противодребезговая задержка.
;--------------------------------------------------------------------------------
T_DATCHIK call PAUSE_UI_1 ; Переход в ПП PAUSE_UI_1.
;----> Возврат по стеку из ПП PAUSE_UI_1.
;--------------------------------------------------------------------------------
; Чтение, из EEPROM, байта указателя включения/выключения термодатчика.
;--------------------------------------------------------------------------------
call READ_V_O ; Реализация оного.
;----> Возврат по стеку из ПП PAUSE_V_O.
;--------------------------------------------------------------------------------
; Анализ содержимого указателя включения/выключения термодатчика.
;--------------------------------------------------------------------------------
SNOVA_8 btfss Temp_3,0 ; Что в бите №0 ?
goto DAT_VIKL ; Если 0, то датчик выключается.
; Если 1, то датчик включается.
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
; Включение датчика.
;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
; Задание адреса знакоместа, с которого начнется вывод на индикацию.
;-------------------------------------------------------------------
movlw b'11000000' ;
movwf PortB ; 2-я строка, 1-е знакоместо. Адрес 00h.
call ENTER_BF_1 ;
;-------------------------------------------------------------------
; Вывод на индикацию символа активности (маркера).
;-------------------------------------------------------------------
movlw 0DCh ;
movwf PortB ; Вывод на индикацию
bsf PortC,RS ; символа активности ">|".
call ENTER_BF_1 ;
;-------------------------------------------------------------------
; Задание адреса знакоместа, с которого начнется вывод на индикацию.
;-------------------------------------------------------------------
movlw b'11001010' ;
movwf PortB ; 2-я строка, 11-е знакоместо. Адрес 0Ah.
call ENTER_BF_1 ;
;-------------------------------------------------------------------
; Вывод на индикацию символа "пусто".
15
;-------------------------------------------------------------------
movlw 20h ;
movwf PortB ; Вывод на индикацию
bsf PortC,RS ; символа "пусто".
call ENTER_BF_1 ;
;--------------------------------------------------------------------------------
bcf Flag,1 ; Флаг наличия/отсутствия термодатчика
; опускается (все переходы в ПП TERMO будут
; осуществляться).
goto OBHOD_3 ; Обход процедуры выключения датчика.

;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
; Выключение датчика.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
; Задание адреса знакоместа, с которого начнется вывод на индикацию.
;-------------------------------------------------------------------
DAT_VIKL movlw b'11001010' ;
movwf PortB ; 2-я строка, 11-е знакоместо. Адрес 0Ah.
call ENTER_BF_1 ;
;-------------------------------------------------------------------
; Вывод на индикацию символа активности (маркера).
;-------------------------------------------------------------------
movlw 0DCh ;
movwf PortB ; Вывод на индикацию
bsf PortC,RS ; символа активности ">|".
call ENTER_BF_1 ;
;-------------------------------------------------------------------
; Задание адреса знакоместа, с которого начнется вывод на индикацию.
;-------------------------------------------------------------------
movlw b'11000000' ;
movwf PortB ; 2-я строка, 1-е знакоместо. Адрес 00h.
call ENTER_BF_1 ;
;-------------------------------------------------------------------
; Вывод на индикацию символа "пусто".
;-------------------------------------------------------------------
movlw 20h ;
movwf PortB ; Вывод на индикацию
bsf PortC,RS ; символа "пусто".
call ENTER_BF_1 ;
;--------------------------------------------------------------------------------
bsf Flag,1 ; Флаг наличия/отсутствия термодатчика
; поднимается (все переходы в ПП TERMO будут
; обходиться).
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
; Опрос клавиатуры.
;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
; Опрос кнопки "Переключение режимов".
;================================================================================
OBHOD_3 btfsc PortB,0 ; Кнопка "Переключение режимов" нажата
; или отжата ?
goto $+9 ; Если отжата, то переход на опрос кнопки
; "Установка порогов".
; Если нажата, то программа исполняется далее.
;--------------------------------------------------------------------------------
; Вывод на индикацию фиксированной надписи " СЛУШАЮСЬ и / ПОВИНУЮСЬ! ".
;--------------------------------------------------------------------------------
bcf PCLATH,3 ; Выбор 1-й страницы.
call SL_I_POVIN ; Переход в ПП вывода на индикацию
; этой надписи.
;--> Возврат по стеку из ПП SL_I_POVIN.
bsf PCLATH,3 ; Выбор 2-й страницы.
;--------------------------------------------------------------------------------
; Противодребезговая задержка.
;--------------------------------------------------------------------------------
call PAUSE_UI_1 ; Переход в ПП PAUSE_UI_1.
;----> Возврат по стеку из ПП PAUSE_UI_1.
16
;--------------------------------------------------------------------------------
; Ожидание отжатия кнопки.
;--------------------------------------------------------------------------------
btfss PortB,0 ; Кнопка "Переключение режимов" нажата
; или отжата ?
goto $-1 ; Если нажата, то ожидание отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
; Рабочее действие после отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
clrf PCLATH ; Выбор 1-го блока 1-й страницы.
goto INKEY ; После отжатия, выход из режима.
;================================================================================
; Опрос кнопки "Установка порогов".
;================================================================================
btfsc PortB,1 ; Кнопка "Установка порогов" нажата
; или отжата ?
goto SNOVA_8 ; Если отжата, то переход на следующий
; внутренний цикл.
; Если нажата, то программа исполняется далее.
;--------------------------------------------------------------------------------
; Противодребезговая задержка.
;--------------------------------------------------------------------------------
call PAUSE_UI_1 ; Переход в ПП PAUSE_UI_1.
;----> Возврат по стеку из ПП PAUSE_UI_1.
;--------------------------------------------------------------------------------
; Ожидание отжатия кнопки.
;--------------------------------------------------------------------------------
btfss PortB,1 ; Кнопка "Установка порогов" нажата
; или отжата ?
goto $-1 ; Если нажата, то ожидание отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
; Рабочее действие после отжатия.
;OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
incf Temp_3,F ; Смена состояния указателя
; включения/выключения
; термодатчика (Temp_3 + 1 = ...).
;================================================================================
; Запись, в EEPROM-память данных, признака включения/выключения термодатчика.
;================================================================================
bsf Status,RP1 ; Переход
bcf Status,RP0 ; во 2-й банк.
movlw 6 ; Выбор ячейки EEPROM
movwf EEAdr ; с адресом 06h.
movf Temp_3,W ;
movwf EEData ; Temp_3 -> EEData.
bsf Status,RP0 ; Переход в 3-й банк.
bcf EECon1,7 ; Работа с EEPROM.
bsf EECon1,2 ; Разрешение записи.
movlw 0x55 ; Обязательная
movwf EECon2 ; последовательность
movlw 0xAA ; команд
movwf EECon2 ; записи.
bsf EECon1,1 ; Инициализация записи.
bcf EECon1,2 ; Запрещение записи.
btfsc EECon1,1 ; Запись завершена или нет ?
goto $-1 ; Если не завершена, то "плавающая" задержка.
bcf Status,RP0 ; Если завершена, то
bcf Status,RP1 ; переход в 0-й банк.
goto SNOVA_8 ; Переход на следующий внутренний цикл.

;################################################################################
; НИЖНЯЯ "ОБСЛУГА" 2-й СТРАНИЦЫ.
;################################################################################
;...................................
;...................................
;================================================================================
17
; Чтение, из EEPROM, байта указателя включения/выключения термодатчика.
;================================================================================
READ_V_O bsf Status,RP1 ; Переход
bcf Status,RP0 ; во 2-й банк.
movlw 6 ; Выбор ячейки EEPROM
movwf EEAdr ; с адресом 06h.
bsf Status,RP0 ; Переход в 3-й банк.
bcf EECon1,7 ; Работа с EEPROM.
bsf EECon1,0 ; Инициализация чтения.
bcf Status,RP0 ; Переход во 2-й банк.
movf EEData,W ; Считывание байта, из выбранной ячейки
movwf Temp_3 ; EEPROM, в регистр Temp_3.
bcf Status,RP1 ; Переход в 0-й банк.
return ; Возврат по стеку.
;################################################################################
; КОНЕЦ НИЖНЕЙ "ОБСЛУГИ" 2-й СТРАНИЦЫ. ##########################################
;################################################################################
end ; Конец программы.

Под сохранение в EEPROM-памяти, выделена ячейка с адресом 06h.


После "прошивки" ПИКа, в ней записано число .1, что соответствует включению
термодатчика.
Так как речь идет всего-лишь об одном из двух состояний, то используется триггер со
счетным входом (важно только состояние бита №0).
Под него задействован регистр Temp_3.
Процедура типа "чтение – модификация – запись" организована стандартно.
"На влете" в процедуру, производится чтение содержимого ячейки EEPROM-памяти с
адресом 06h (call READ _V_O), а затем и анализ прочитанного (анализ состояния бита
№0 регистра Temp_3).
В зависимости от результата этого анализа, выполняется либо сценарий включения
датчика, либо сценарий его выключения.
Следует пояснить, что в данном случае, речь идет не об электрическом
включении/выключении датчика, а о программном его включении/выключении.
Под это дело задействован, уже имеющийся в наличии, флаг наличия/отсутствия
термодатчика.
Если этот флаг "принудительно" поднять, то в дальнейшем, электрически
подключенный термодатчик, за счет обходов (неисполнений) ПП TERMO, будет
программно выключен.
А если этот флаг "принудительно" опустить, то в дальнейшем, электрически
подключенный термодатчик, за счет исполнений ПП TERMO, будет программно включен.
Что и сделано.
Конкретнее.
В результате отработки сценария выключения датчика, флаг наличия/отсутствия
термодатчика поднимается, и в дальнейшем, ПП TERMO исполняться не будет.
В результате отработки сценария включения датчика, флаг наличия/отсутствия
термодатчика опускается, и в дальнейшем, ПП TERMO исполняться будет.
Изначальный выбор того или иного сценария (а соответственно и положение маркера)
определяется состоянием бита №0 байта, считанного из ячейки EEPROM-памяти с
адресом 06h (см. чтение "на влете" в процедуру).
Активна та надпись (и "привязанный" к ней подрежим), на которую указывает маркер.
Положение маркера изменяется после нажатия/отжатия кнопки "Установка порогов"
(после перехода в ПП T_DATCHIK, функциональность этой кнопки изменяется).
При этом, к содержимому регистра Temp_3 приплюсовывается единица (число, которое
"лежит" в байте не важно. Важно только то, четное оно или нечетное) и происходит
запись содержимого регистра Temp_3 в ячейку
EEPROM-памяти с адресом 06h.
Если после этого выключить питание, а затем опять
его включить, то маркер будет установлен на ранее
выбранной надписи (энергонезависимая память
настройки).

18
На картинках слева, Вы видите оба варианта
установки маркера.
До тех пор, пока не будет нажата/отжата кнопка
"Переключение режимов", работа будет происходить
во внутреннем цикле ПП T_DATCHIK.
То есть, пока кнопка "Переключение режимов" не
будет нажата/отжата, положение маркера можно изменить какое угодно количество раз
(с помощью кнопки "Установка порогов").
Текущим будет последнее положение маркера.
После отжатия кнопки "Переключение режимов" (на время нажатия, "высвечивается"
надпись СЛУШАЮСЬ и ПОВИНУЮСЬ!), произойдет возврат в тот режим работы, из
которого вызывалось меню выбора порогов.
Итак, теперь можно с комфортом выключить/включить термодатчик, с
энергонезависимым запоминанием факта его включения или выключения.
Второй этап текущей работы завершился.
3-й этап работы
Нужно как-то оповестить пользователя о том, заблокирован ли термодатчик или он
разблокирован. Ведь пользователь вполне может забыть про свои предыдущие
"телодвижения".
Из-за этого, могут быть всяческие "оргнеувязки", вплоть до недовольства по отношению
к конструктору.
Значит, нужно "состряпать" какую-то "напоминалку".
"Стряпаю".
Будет вполне логичным "привязаться", к имеющейся в наличии, процедуре определения
электрического подключения/отключения термодатчика.
То есть, в нее нужно осуществить некую "врезку" ("врезки").
Что и имеет место быть.
Получилось это:
;...................................
;...................................
;ОООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООО
; Проверка наличия/отсутствия отклика от термодатчика.
;ОООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООООО
bsf PCLATH,3 ; Выбор текущего блока 2-й страницы.
call DQ_INIT ; Переход в ПП инициализации термодатчика.
;----> Возврат по стеку из ПП DQ_INIT.
;--------------------------------------------------------------------------------
; Чтение, из EEPROM, байта указателя включения/выключения термодатчика.
;--------------------------------------------------------------------------------
call READ_V_O ; Реализация оного.
;----> Возврат по стеку из ПП READ_V_O.
;================================================================================
; Вывод на индикацию, в 1-ю строку, фиксированной надписи " Термодатчик ".
;================================================================================
movlw high TEXT_19; Выбор
movwf PCLATH ; 2-го блока 1-й страницы.
movlw b'10000000' ; Установка курсора в крайнее
call ENTER_BF ; левое знакоместо 1-й строки.
movlw .16 ;
movwf Count ;
movf Count,W ;
sublw .16 ;
call TEXT_19 ; Аналогично, только
bsf PortC,RS ; для TEXT_19.
call ENTER_BF ;
decfsz Count,F ;
goto $-6 ;
;--------------------------------------------------------------------------------
; Анализ состояния флага наличия/отсутствия термодатчика.
;--------------------------------------------------------------------------------
btfsc Flag,1 ; Если флаг поднят, выводится надпись
; " ОТКЛЮЧЕН "

19
goto TERMO_OTKL ; Если флаг опущен, выводится надпись
; " ПОДКЛЮЧЕН ".
;================================================================================
; Вывод на индикацию, во 2-ю строку, фиксированной надписи " ПОДКЛЮЧЕН ".
;================================================================================
TERMO_VKL movlw b'11000000' ; Установка курсора в крайнее
call ENTER_BF ; левое знакоместо 2-й строки.
movlw .16 ;
movwf Count ;
movf Count,W ;
sublw .16 ; Аналогично, только
call TEXT_20 ; для TEXT_20.
bsf PortC,RS ;
call ENTER_BF ;
decfsz Count,F ;
goto $-6 ;
goto OBHOD_4 ; Переход на метку OBHOD_4 (обход).
;================================================================================
; Вывод на индикацию, во 2-ю строку, фиксированной надписи " ОТКЛЮЧЕН ".
;================================================================================
TERMO_OTKL movlw b'11000000' ; Установка курсора в крайнее
call ENTER_BF ; левое знакоместо 2-й строки.
movlw .16 ;
movwf Count ;
movf Count,W ;
sublw .16 ; Аналогично, только
call TEXT_21 ; для TEXT_21.
bsf PortC,RS ;
call ENTER_BF ;
decfsz Count,F ;
goto $-6 ;

bsf Flag_1,4 ; Поднятие флага блокировки 4-го пункта меню


; (в дальнейшем, этот пункт будет обходиться).
;================================================================================
; Формирование звукового сигнала отсутствия термодатчика.
;================================================================================
movlw .15 ; Задание количества "писков"
movwf Temp ; (было 3). ЗАДЕРЖКУ 1 сек УБРАЛ

call PAUSE_UI ; Задержка.


;----> Возврат по стеку из ПП PAUSE_UI.
call MULTI ; Переход в ПП аварийной "пищалки".
;----> Возврат по стеку из ПП MULTI.
decfsz Temp,F ; "Постановка на счетчик"
goto $-3 ; количества "писков".
;-----------------------------------
clrf PCLATH ; Выбор 1-го блока 1-й страницы.
goto START_1 ; Обход сценария программной блокировки
; датчика.
;-----------------------------------
OBHOD_4 btfsc Temp_3,0 ; Датчик включен или выключен ?
goto START_1 ; Если включен, то обход.
bsf Flag,1 ; Если выключен, то флаг наличия/отсутствия
; термодатчика поднимается (все переходы
; в ПП TERMO будут обходиться).
;--------------------------------------------------------------------------------
; 3 "писка" с паузами.
;--------------------------------------------------------------------------------
call MULTI ; Переход в ПП аварийной "пищалки".
;----> Возврат по стеку из ПП MULTI.
call PAUSE_1SEK ; Задержка.
;----> Возврат по стеку из ПП PAUSE_1SEK.
call MULTI ; Переход в ПП аварийной "пищалки".
;----> Возврат по стеку из ПП MULTI.
call PAUSE_1SEK ; Задержка.
20
;----> Возврат по стеку из ПП PAUSE_1SEK.
call MULTI ; Переход в ПП аварийной "пищалки".
;----> Возврат по стеку из ПП MULTI.
;--------------------------------------------------------------------------------
; Вывод на индикацию, в 1-ю строку, фиксированной надписи "но ЗАБЛОКИРОВАН ".
;--------------------------------------------------------------------------------
movlw high TEXT_44; Выбор PCH 1-й команды ПП TEXT_44
movwf PCLATH ; (находится во 2-м блоке 2-й страницы).
call BLOKIR_T ; Переход в ПП BLOKIR_T.
;----> Возврат по стеку из ПП BLOKIR_T.
clrf PCLATH ; Выбор 1-го блока 1-й страницы.
;--------------------------------------------------------------------------------
; Задержки.
;--------------------------------------------------------------------------------
call PAUSE_1SEK ; Задержка.
;----> Возврат по стеку из ПП PAUSE_1SEK.
call PAUSE_1SEK ; Задержка.
;----> Возврат по стеку из ПП PAUSE_1SEK.
;================================================================================
; Предварительное (с глобальным запретом) разрешение прерываний
; по переполнению TMR2.
;================================================================================
START_1
;...................................
;...................................
;...................................
;...................................

;################################################################################
; КОНЕЦ НИЖНЕЙ "ОБСЛУГИ" 1-й СТРАНИЦЫ. ##########################################
;################################################################################
org 801h ; Заполнение 2-й страницы памяти программ
; начинается с 2050-й позиции (см. окно ROM).
;22222222222222222222222222222222222222222222222222222222222222222222222222222222
; 2-я СТРАНИЦА ПАМЯТИ ПРОГРАММ.
;################################################################################
; ВЕРХНЯЯ "ОБСЛУГА" 2-й СТРАНИЦЫ. ###############################################
;################################################################################
;...................................
;...................................
;-----------------------------------
; Надпись " ВКЛ. ОТКЛ."
;-----------------------------------
TEXT_43 addwf PC,F ; -----"-----
dt 0x20,0x42,0x4B,0xA7,0x2E,0x20,0x20,0x20
dt 0x20,0x20,0x20,0x4F,0x54,0x4B,0xA7,0x2E
;================================================================================
; Группа подпрограмм табличных, вычисляемых переходов, формирующих фиксированные
; картинки (расположена во 2-м блоке 2-й страницы памяти программ / PCLATH=.9).
;================================================================================
; Надпись "но ЗАБЛОКИРОВАН "
;-----------------------------------
TEXT_44 addwf PC,F ; -----"-----
dt 0xBD,0x6F,0x20,0xA4,0x41,0xA0,0xA7,0x4F
dt 0x4B,0xA5,0x50,0x4F,0x42,0x41,0x48,0x20
;-----------------------------------
; Надпись " в настройках "
;-----------------------------------
TEXT_45 addwf PC,F ; -----"-----
dt 0x20,0x20,0xB3,0x20,0xBD,0x61,0x63,0xBF
dt 0x70,0x6F,0xB9,0xBA,0x61,0x78,0x20,0x20
;################################################################################
; КОНЕЦ ВЕРХНЕЙ "ОБСЛУГИ" 2-й СТРАНИЦЫ. #########################################
;################################################################################
;...................................

21
;...................................
;...................................
;...................................
;################################################################################
; НИЖНЯЯ "ОБСЛУГА" 2-й СТРАНИЦЫ.
;################################################################################
;...................................
;...................................
;================================================================================
; Вывод на индикацию, в 1-ю строку, фиксированной надписи "но ЗАБЛОКИРОВАН ".
;================================================================================
BLOKIR_T movlw b'10000000' ; Установка курсора в крайнее
call ENTER_BF_1 ; левое знакоместо 1-й строки.
movlw .16 ;
movwf Count ;
movf Count,W ;
sublw .16 ; Аналогично, только
call TEXT_44 ; для TEXT_44.
bsf PortC,RS ;
call ENTER_BF_1 ;
decfsz Count,F ;
goto $-6 ;
;================================================================================
; Вывод на индикацию, во 2-ю строку, фиксированной надписи " в настройках ".
;================================================================================
movlw b'11000000' ; Установка курсора в крайнее
call ENTER_BF_1 ; левое знакоместо 2-й строки.
movlw .16 ;
movwf Count ;
movf Count,W ;
sublw .16 ; Аналогично, только
call TEXT_45 ; для TEXT_45.
bsf PortC,RS ;
call ENTER_BF_1 ;
decfsz Count,F ;
goto $-6 ;
return ; Возврат по стеку.
;================================================================================
;...................................
;...................................
;################################################################################
; КОНЕЦ НИЖНЕЙ "ОБСЛУГИ" 2-й СТРАНИЦЫ. ##########################################
;################################################################################
end ; Конец программы.

То, что было наработано ранее, выделено черным цветом.


То "новое", что наработано на 1-й странице памяти программ, выделено
темно-синим цветом.
То "новое", что наработано на 2-й странице памяти программ, выделено
темно-красным цветом и фиолетовым цветом.

В процедуру проверки наличия/отсутствия отклика от термодатчика осуществлены


"врезки".
Логика всего этого "безобразия" такова.

Термодатчик электрически подключен


1. Если, в настройках, термодатчик разблокирован, то начало работы "железяки" будет
точно таким же, как и ранее: "высветится" надпись
Термодатчик ПОДКЛЮЧЕН,
и без всяких напоминаний/"писков", начнется "рабочий" цикл.
Если, в дальнейшем, работа будет происходить в режиме выключенной защиты, то
в 1-й строке дисплея "высветится" надпись
ЗАЩИТА ВЫКЛ. t = xx

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

Термодатчик электрически отключен


3. В этом случае, после включения питания,на
индикацию всегда будет выводиться надпись
Термодатчик ОТКЛЮЧЕН,
сопровождаемая 15-ю "писками" (их количество я увеличил с 3-х до 15-ти), после чего
начнется "рабочий" цикл.
При этом, 4-й пункт меню автоматически исключается из меню выбора порогов (обход
этого пункта меню).
По этой причине, какое-либо "ручное" воздействие, на флаг наличия/отсутствия
термодатчика, исключено, и в дальнейшем, этот флаг всегда будет находиться в
поднятом состоянии (он поднимается в ПП DQ_INIT).

"Вышележащая" процедура работает так.


После включения питания, на "влете" в процедуру, производится "штатная"
инициализация термодатчика и Чтение, из EEPROM, байта указателя
включения/выключения термодатчика.
Последнее нужно для того, чтобы в дальнейшем произвести анализ бита №0 регистра
Temp_3 (в него записывается результат считывания).
Далее, на индикацию, в 1-ю строку дисплея, выводится надпись Термодатчик (она
общая для обеих последующих сценариев ветвления) и производится анализ состояния
флага наличия/отсутствия термодатчика.
Напоминаю, что он поднимается (в ПП DQ_INIT), в случае необнаружения
электрического подключения датчика к ПИКу.
После этого анализа, происходит ветвление на 2 сценария.

Если электрического подключения датчика к ПИКу не обнаружено (Flag,1 = 1), то


исполняется ПП TERMO_OTKL.
А именно,
1. На индикацию выводится надпись ОТКЛЮЧЕН.
2. Флаг блокировки 4-го пункта меню выбора порогов поднимается (в дальнейшем, этот
пункт будет обходиться).
3. "Железяка" 15 раз "пищит".
4. Осуществляется переход на продолжение ПП START.

Если электрическое подключение датчика к ПИКу обнаружено (Flag,1 = 0), то


исполняется ПП TERMO_VKL (переходов goto/call на нее нет. Указано для обеспечения
комфортной ориентации).
А именно,
1. На индикацию выводится надпись ПОДКЛЮЧЕН,
2. Осуществляется обход всего того, что связано с ПП TERMO_OTKL,
23
3. Производится анализ состояния бита №0 байта, ранее считанного из ячейки
EEPROM-памяти с адресом 06h ("лежит" в регистре Temp_3).
a) Если обнаружена ранее установленная настройка типа "датчик включен" (речь идет
о программном включении/выключении датчика), то осуществляется переход на
продолжение ПП START.
б) Если обнаружена ранее установленная настройка типа "датчик выключен", то флаг
наличия/отсутствия термодатчика поднимается (в дальнейшем, все переходы в ПП
TERMO будут обходиться), после чего производится 3 предупреждающих "писка".
Кроме "пищания", сие "сооружение", "по совместительству", выполняет роль
фиксированной задержки, задающей основную часть интервала времени
"высвечивания" надписи
Термодатчик ПОДКЛЮЧЕН.
Далее, на индикацию выводится надпись
но ЗАБЛОКИРОВАН в настройках.
Далее, отрабатывается фиксированная задержка, задающая интервал времени
"высвечивания" этой надписи.
Далее, осуществляется "линейный" (без goto/call) переход на продолжение ПП
START.

В случае, если датчик электрически подключен и программно разблокирован, интервал


времени вывода на индикацию надписи Термодатчик ПОДКЛЮЧЕН определяется
интервалом времени от начала отработки ПП TERMO (переходы в них осуществляются
в начале обеих основных сценариев) и до вывода на индикацию следующей, текущей
надписи, которая может "дислоцироваться" как в сценарии выключенной защиты, так и
в сценарии включенной защиты (зависит от выбора режима).
Можно упрощенно считать, что в данном случае, интервал времени вывода на
индикацию надписи Термодатчик ПОДКЛЮЧЕН немного больше времени отработки
"одноразовой" задержки (она - самая "массивная").
В случае, если датчик электрически отключен, то интервал времени вывода на
индикацию надписи Термодатчик ОТКЛЮЧЕН, в основном, определяется интервалом
времени отработки той "пищалки", которая "пищит" 15 раз.
Изменяя количество этих "писков", можно изменить величину этого интервала времени.

Следующий момент.
ПП BLOKIR_T "лежит" на 2-й странице памяти программ.
Под нее организованы две ПП вычисляемых переходов: TEXT_44 и TEXT_45
(выделены фиолетовым цветом).
"По закону жанра" (вычисляемые переходы), эти ПП вынесены в верхнюю "обслугу" 2-й
страницы.
При этом, в общей сложности, имеет место быть 19 подпрограмм вычисляемых
переходов, "лежащих" в двух блоках (одного мало).
В данном случае, просто повезло.
В том смысле, что первая команда ПП TEXT_44 пришлась точно на первую ячейку
2-го блока 2-й страницы (подфартило).
В случае же, если такой фортуны не будет, нужно предпринять меры по "загону этих
двух стад" в свои, отдельные "загоны".
При этом можно либо скорректировать "рабочую" часть той директивы org, которая
имеется (менее 800h делать не нужно. Более - можно), либо, "в районе границы"
между блоками, "настукать" соответствующее количество NOPов, либо "состряпать" еще
одну директиву org, либо в комплексе или в какой-то комбинации.
Есть и еще варианты (все перечислять не стал), но смысл один и тот же
(см. два "стада").

О "вентилляторных делах".
В начале и сценария выключенной защиты, и сценария включенной защиты, имеют
место быть две одинаковые процедуры:
;...................................
;...................................
;--------------------------------------------------------------------------------

24
; Опрос флага наличия/отсутствия термодатчика.
;--------------------------------------------------------------------------------
btfsc Flag,1 ; Флаг наличия/отсутствия термодатчика поднят
; или нет ?
goto $+5 ; Если поднят, то обход ПП работы с датчиком.
; Если нет, то ПП TERMO исполняется.
;--------------------------------------------------------------------------------
; Окончание "разгона" вентиллятора.
;--------------------------------------------------------------------------------
bsf PCLATH,3 ; Выбор текущего блока 2-й страницы.
call TERMO ; Переход в ПП работы с датчиком, с целью
;--> Возврат по стеку из ПП TERMO. ; установки текущих оборотов вентиллятора.
clrf PCLATH ; Выбор 1-го блока 1-й страницы.
goto $+3 ; Обход "разгона" вентиллятора.
;================================================================================
; Перевод вентиллятора на заданное количество оборотов
; (в данном случае, на максимальные).
;================================================================================
movlw .255 ;
movwf CCPR1L ; CCPR1L = 11111111
;...................................
;...................................

Если "термодела делаются", то количество оборотов "пропеллера" определяется


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

О прерываниях.
В начале ПП INKEY, прерывания разрешать нельзя.
Их наоборот нужно запретить.
Причина: в сценарии включенной защиты, до начала циклической ПП слежения,
производится чтение порогов U/I.
А это работа во 2-м и 3-м банках.
К тому же, ПП чтения "лежит" на 2-й странице памяти программ.
А ПП прерывания "ориентирована" на работу с 0-м и 1-м банками и с 1-й страницей
памяти программ.
То есть, в случае включения такой процедуры чтения в "зону" разрешения прерываний,
будет стопроцентный "глюк".

О коррекции времени отработки пунктов меню выбора порогов.


Я счел нужным уменьшить значение констант, определяющих величину интервалов
времени вывода на индикацию надписей Uвольт и Iампер, термозащиты и защиты
от КЗ, с .40 до .35, и увеличить значение константы, определяющей величину
интервала времени вывода на индикацию надписи Возврат из режима, с .20 до .35.
Это чисто субъективный фактор.
Если кому-то не понравится мое ощущение времени, то никто не запрещает
произвести эту коррекцию в соответствии со своим ощущением времени.

Сказанное реализовано в программе BP_14.asm (прилагается).


Число 13 не люблю.
Итак, на данный момент, имеется программа с совсем не слабой функциональностью и
"массой" (3111 слов в памяти программ), которая "ваялась" по принципу строго
поэтапного ее усложнения.
25
Именно так, а не с помощью "кавалерийского наскока", создаются относительно
сложные программы.
При этом, на каждом этапе работы, нужно зорко следить за "уровнем черепномозгового
бардака".
Он не должен "зашкаливать" за пределы разумного.
Пределы разумного определяет конкретный человек.
Но критерий один и тот же.
Если человек чувствует, что начинает капитально "запутываться", то нужно, через
не хочу и обуздание буйных желаний/вожделений, приказать себе СТОП – МАШИНА и
навести порядок в том, что "текущенаворочено".
Вплоть до "возврата назад", если это необходимо.
А то ведь бардак, это такая ехидная субстанция, которая, если не предпринять мер по
борьбе с ним, имеет исключительно устойчивую тенденцию к сильнейшему росту.
Вплоть до огромаднейших размеров.
Наведение порядка в мыслях (борьба с бардаком) это одна из важнейших
составляющих успешной работы.
А уж в нашем-то деле, этому нужно учиться не по принципу "тяп-ляп", а на полном
серьезе. Целенаправленно.
Лично я, этому учусь постоянно.
Не могу утверждать, что очень успешно, но всячески стараюсь.
И Вас призываю к тому же.
Продолжение следует.

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

27