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

2-2/1. Что "ваять" будем? Составление первичного плана работы.

Определение
первоочередных задач и их решение.

Ну наконец-то. "Дополз до счастья".


Весь живот в царапинах от "кочек, сучков" и просто от трения.
Но теперь можно "на ноги встать" и ощутить радость соответствующей
функциональности.
То есть, заняться "приложением" того, что "нарыто" ранее, к какой-нибудь реально
востребованной нужности.
Частенько, те люди, которые "вышли на эту специфическую тропу войны", совершают
стратегическую ошибку типа "скачка через N-ступенек" (хочется все и сразу).
После соответствующего "упирания лбом в стену" (напоминаю о "связке" типа "нос -
батарея", а также и про "фингалы"), происходит "откат назад" и дальнейшее,
неумолимое "на колу мочало" (колебательный процесс режима поиска. На "пилу"
похоже).
Сие может повторяться многократно и нудно, причем, неумолимая логика этого
воспитательного (армейского) "действа" такова, что она, так или иначе, просто
насильно (не доходит через голову, дойдет через ноги) заставит последовательно
"пройти по всем ступенькам".
Без каких бы то ни было "прыжков", а заодно и скидок на сильнейшее желание
побыстрее достигнуть желаемого.
"Побыстрее", желаемое достигается совсем не так, а с умом и соответствующим
"предпониманием уставших истин" (банальностей).
То есть, речь идет о "въезде" в общую методологию конструирования устройств на
м/контроллерах, а проще говоря, в "свод правил игры", которые нужно выполнять.
Предположим, что этот "свод правил" сформулирован, осознан и выполняется.
Но этого мало.
В идеале, начиная с первого "крика", оповещающего о "рождении", "карапуз" должен
быть упорно "воспитан" так, чтобы в дальнейшем, из него получился не "человек в
футляре", а "солнечный человек".
Главные атрибуты "солнечного человека" - бесхитростность/понятность (непонятное
настораживает) и уважение к людям.
Что касается первого, то это предполагает скурпулезное "разложение на молекулы" и
добросовестное "вылизывание всего того, что шевелится". Типа "смены подгузников и
вытирания соплей". Без любви к своему "карапузу", будет "каторга".
Что касается второго, то сие есть "таинственная субстанция", которая определяется
воспитанием самого конструктора (миллион аспектов).
"Каков поп (конструктор), таков и приход (результаты его работы)".
Детализировать не решаюсь, так как я даже не Нобелевский лауреат.
И все это "глобально привязано" к такому понятию, как "душа".
В нашем деле, без одухотворенности работы, "выше ремесленника не прыгнешь".
А вот если нули/единицы оживают и становятся родными, то есть реальный шанс
дорасти до мастера.
Понять все это относительно не сложно. Сложно исполнить.
Особенно с учетом того, что все мы разные.
Я же высказываю свое личное мнение, которое намерен "подкрепить нижележащим".
То есть, конкретным примером. Исходя из своего понимания "глобальной" методологии
"воспитания всяческих карапузов".

Что "ваять" будем? Составление первичного плана работы.


"Ваять" буду то, что полезно.
В качестве такового, выбран многофункциональный модуль, предназначенный для
установки в блоки питания.
На форуме, было организовано соответствующее обсуждение.
В результате этого обсуждения, было высказано пожелание о "ваянии" такого модуля
на PIC16F873A и 2-строчном ЖК-модуле.
И в самом деле, при таком "раскладе", обеспечивается комфортное и
"информационноемкое" отображение результатов "жизнедеятельности" устройства, и

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

1. Как минимум, нужно измерить значения Uвых. БП и тока, потребляемого


внешней (по отношению к БП) нагрузкой (Iвых.).
2. Кроме того, ничто не мешает организовать защиту нагрузки от превышения,
Uвых. и/или Iвых., заранее заданных "порогов".

Итак, изначально, имеются две наиглавнейшие функциональности.


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

Определение первоочередных задач


Изначально, среди первоочередных задач, нужно выделить самую главную, то есть,
"царя-батюшку" ("суперважняк").
Вопрос: "Как его идентифицировать и не перепутать с теми, кто рангом помельче"?
Исключительно умный и уважаемый вопрос.
Потому, что ошибки в ответе на него, могут дорого стоить.
Представьте себе состояние бедолаги-конструктора, который успешно решил множество
второстепенных задач, а в конечном итоге, "уперся лбом в царя-батюшку".
Характерной особенностью значительной части "царей-батюшек" является их вредность
и ехидность (в самом наилучшем, для конструктора, случае).
Они очень не любят, когда их "статус" игнорируют.
А если сильно унизить (в упор не замечать), то мстят жестоко.
И так, что мало не покажется.
Могут и "на кол посадить", и "замочить в сортире" (это не я сказал), и т.д.
Элементарно. Вне зависимости от заслуг (власти - немеряно).
Поэтому, напоминаю про "Боже царя храни".
Лучше заранее озаботиться и спеть.
Кстати, "текущий царь-батюшка" именно из этой категории. Причем, из первых рядов.
Поэтому, благоразумно идентифицирую.
Если полностью проигнорировать "пороговые дела", то придраться не к чему, так как с
процедурами АЦП и вывода на индикацию результатов АЦП, никаких проблем нет.
"Подключаю пороги" (мысленно).
Речь идет о защите нагрузки, подключенной к выходу БП.
Наиглавнейший параметр любой защиты - ее инерционность (наихудшее время отклика
на "бяку").
В простейшем (но не самом лучшем) случае, если циклы АЦП будут отрабатываться в
"основном теле" программы, один раз за один полный цикл программы, будут иметь
место быть "мертвые зоны" неприлично большой протяженности (за счет отработки
всего того, что не связано с циклами АЦП), во время отработки которых, защита
просто не будет работать.
2
А если, в начале этого "безобразия", произошла "бяка"?
Очень велика вероятность всяческих "щелчков", "дымов" и прочей гнусности.
Нет уж. Пусть такой защитой пользуются враги.
Значит, если речь идет о программе без прерываний, то нужно организовывать
кольцевой счет в предустановленном таймере, с периодическим анализом его
переполнения и вызовом (call) подпрограммы АЦП (если флаг переполнения поднят).
Это сделать можно, но возникнет куча проблем.
Во-первых, о равномерной периодичности вызова ПП АЦП можно и не мечтать, а
во-вторых, если речь идет о малой инерционности, то в программу нужно "врезать"
(причем, не абы как, а по-умному) такое большое количество проверок, что программа
сильно рискует "превратиться в рогатое и неприличное сооружение".
И т.д. (имеется много "производных").
Короче, "полнейший геморрой".
Если нужно "подложить свинью", то можно посоветовать это.
Вывод: пусть этим пользуются враги, а также и агенты 007.
Значит à прерывания.
Они могут обеспечить и минимальную инерционность отклика и равномерную
периодичность, причем, без организации вышеуказанных проверок.
Ну хорошо. Предположим, что цикл АЦП, вместе с "пороговыми делами", вынесен в
ПП прерывания.
Вопрос: "По чему прерываться"?
Ответ: в принципе, можно "подпрячь" модуль любого таймера, но лучше всего
задействовать специализированный, под это дело, модуль TMR2, работающий в
автономном режиме (см. подраздел 6/4 первой части "Практикума …").
Чудненько.
И ничего придумывать не нужно, так как это придумано ранее (комфорт).
Ну ладно. Предположим, что периодический уход в прерывания по переполнению
TMR2 организован, и рабочая точка программы, строго периодически, с заранее
предустановленным значением периода, "отлучается", из "основного тела" программы, в
ПП прерывания, "делает там свои дела" и возвращается назад.
Какой период задавать?
Время отработки ПП прерывания должно быть меньше периода ухода в прерывания.
Иначе, равномерной периодичности не видать. Это аксиома.
Для начала, период ухода в прерывания, равный 250 мкс., будет в самый раз.
Это больше того, что требуется (перестраховка).
Когда полностью "обозначится" время отработки ПП прерывания, это число можно
соответствующим образом уменьшить.
Теперь, все внимание - на ПП прерывания.
Что касается "АЦПэшных и прочих дел, вершащихся" в ПП прерывания, то никаких
проблем нет.
Что будет "засунуто", то и будет исполнено (если ошибок нет). "Железобетонно".
Проблема - в сохранении и восстановлении содержимого "жизненно важных" регистров.
В первую очередь, регистра W и регистра Status.
Эта проблема обусловлена применением м/контроллера PIC16F873A.
В случае применения м/контроллера PIC16F876A, такой проблемы нет.
Это "безобразие" объясняется тем, что в отличие от PIC16F876A,
в PIC16F873A, ни один из регистров общего назначения 0-го банка не
отображается в 1-м банке.
Примечание: в PIC16F873A, все регистры общего назначения 0-го банка
отображаются во 2-м банке, а все регистры общего назначения 1-го банка
отображаются в 3-м банке.
Например, регистр W_Temp "прописан" в 0-м банке.
Если уход в прерывание произойдет из 0-го банка, то проблем с
сохранением/восстановлением не будет.
А вот если уход в прерывание произойдет из 1-го банка, то будет "глюк" (нужный
регистр не будет найден, а будет найдено "черт знает что").
Это же относится и к сохранению/восстановлению содержимого регистра Status, а
также и других "жизненно важных" регистров, если соответствующие регистры общего

3
назначения, задействованые в процедуре сохранения/восстановления, "прописаны" в 0-м
банке.
Можно "прописать" их и в 1-м банке, но толку от этого - ноль ("от перестановки мест
слагаемых, сумма не меняется").
Просто "глюк переместится" в другой банк.
Но это решаемо.
Самое главное - понять "корень зла", а уж его "выкорчевывание" - дело техники (см.
ниже).
Теперь о ЖК-модуле.
На форуме, был разговор о ЖК-модулях компании МЭЛТ.
Приобрел (MT-16S2D-2YLG, версия 7). Посмотрел. Понравилось.
Особенно - увеличенный размер символов (не матрица 5х7, а матрица 5х8 точек) и
наличие "страсть как русифицированной" (душа радуется), дополнительной страницы
знакогенератора (2 страницы: 0-я и 1-я. Речь идет о 1-й).
Удобно, так как, на 1-й странице, имеется весь русский алфавит.
И не "рваный", а привычный.
Короче, по этому поводу, дружески "жму руку МЭЛТу".
Но для обеспечения совместимости программы с другими, "забугорными" типами ЖК-
модулей, использовать буду 0-ю страницу.
Единственный "пупырь" - сложности с инициализацией.
Сужу по форуму. Да и сам прочувствовал.
Лично мне, совсем не интересно "ваять" то, что преподносится в даташите.
Какое-то это "рогатое" и некрасивое.
Душа этому совсем не радуется. Поэтому и не нравится.
Лично мне, очень интересно "заинициализироваться", с задействованием флага BF.
Это соответствует понятию "хулиган", максимально возможной скорости отработки
процедуры инициализации ЖК-модуля, а значит и наивысшему ее качеству/надежности.
И это не утопия.
Докладываю: флаг BF "срабатывает" на завершающем этапе исполнения любой
инструкции.
И к процедуре инициализации это тоже относится.
Нужно только выяснить специфику. А она имеется (см. ниже).
Теперь об общей стратегии.
Все познается в сравнении.
Поэтому, по "наводке" Альберто, я просмотрел журналы "Радио" №1 за 2005 г. и №7
за 2007 г.
Речь идет о статьях Н. Заеца, в которых описывается устройство защиты с функцией
измерения, аналогичное той "базе", которую я хочу "сваять".
Стратегический просчет автора заключается в том, что его программа организована
таким образом, что между "пачками" циклов измерений, имеются "мертвые зоны" аж по
1000 мкс. каждая (по версии автора), в которых защита просто не работает (во время
вывода данных на индикацию).
Это очень много.
По моему замыслу, в режиме слежения, подобного рода "мертвых зон" не будет, так
как в течение всего времени отработки полного цикла программы, прерывания по
переполнению TMR2 будут разрешены.
В том числе и при отработке процедуры вывода данных на индикацию, и даже при
отработке процедуры инициализации ЖК-модуля (прерывания разрешаются в ПП
START, а далее, в идеале, не запрещаются.).
Если это обеспечить, то максимальное время срабатывания защиты (по напряжению и
по току) будет строго постоянным (без "мертвых зон" типа "вышележащих" 1000 мкс.), и
оно будет равно интервалу времени между двумя соседними уходами в прерывание.
Пока, я задал 250 мкс., но далее, это значение будет уменьшено.
Н. Заец использовал 7-сегментные индикаторы.
Их информативные возможности гораздо ниже средних, и оперативной памяти они
совсем не имеют (не говорю уж о двух строках по 16 символов).
Получилось конечно дешево, но зато "геморройно".
В том смысле, что "по скудоумию" (не Н. Заеца, а 7-сегментных индикаторов), на
индикацию выводятся какие-то "кракозябры", к которым нужно привыкать.
4
ЖК-модуль, это совсем иное качество отображения информации и информативность.
А его оперативная память, это вообще "счастье" для программ, в которых
используются периодические уходы в прерывания.
Имея такую "красатульку", с учетом объема памяти программ PIC16F873A, грешно не
думать о значительном наращивании функциональности.
Короче, речь идет о серьезной "машине". И первыми ее ценителями будете Вы.
Только просьба иметь терпение.
Итак, в результате всех этих "словоблудий", вдруг, откуда не возьмись, возник
следующий список первоочередных задач, которые нужно безотлагательно
решить/воплотить в жизнь:

1. С целью обеспечения периодического ухода в прерывания, с периодом в


250 мкс., нужно задействовать модуль TMR2, работающий в автономном
режиме.
2. "Зона" разрешения прерываний по переполнению TMR2 должна начаться в
ПП START, после чего эти прерывания не запрещаются.
3. С целью обеспечения "безглючной" отработки ПП прерывания, нужно
озаботиться "банковскими делами", в части касающейся процедуры
сохранения/восстановления содержимого регистров W и Status.
4. С целью обеспечения максимальной скорости отработки процедуры
инициализации графического модуля MT-16S2D-2YLG, нужно "сваять
нештатную" процедуру инициализации, с полномасштабным задействованием
флага BF.
5. Нужно озаботиться составлением "проматеринской" принципиальной схемы.

Это и есть достаточно четкий план дальнейшей работы, который нужно реализовать.
По пунктам (порядок в мыслях и анархия не совместимы).
Реализую.

Решение первоочередных задач

1. С целью обеспечения периодического ухода в прерывания, с периодом в


250 мкс., нужно задействовать модуль TMR2, работающий в автономном
режиме.
2. "Зона" разрешения прерываний по переполнению TMR2 должна начаться в
ПП START, после чего эти прерывания не запрещаются.

Эти две задачи решаются так (в комплексе):

;********************************************************************************
; НАЧАЛО ИСПОЛНЕНИЯ ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
START .......................
.......................
Работа в 0-м банке

clrf TMR2 ; Обеспечение начала отсчета TMR2 от 0.


movlw b'00000100' ; Модуль TMR2 включен с Кдел. предделителя = 1
movwf T2CON ; и Кдел. выходного делителя = 1.

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


.......................
.......................
movlw .249 ; Задание периода ухода в
movwf PR2 ; прерывания = 250 мкс. (F = 4 Кгц.).
movlw b'11000000' ; Глобальное разрешение прерываний и
movwf IntCon ; разрешение прерываний от периферийных
; модулей.
movlw b'00000010' ; Разрешение прерываний
5
movwf PIE1 ; по переполнению TMR2.
bcf Status,RP0 ; Переход в 0-й банк.

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

;////////////////////////////////////////////////////////////////////////////////
ДАЛЕЕ, ПРЕРЫВАНИЯ НЕ ЗАПРЕЩАЮТСЯ

См. подраздел 6/4 первой части "Практикума …".


"Передрано" оттуда. И соответствующие объяснения - там же.
Только изменен Кдел. предделителя (вместо 4 à 1) и добавлены команды clrf TMR2
(для порядка) и bcf PIR1,TMR2IF (флаг прерывания по переполнению TMR2 нужно
сбросить).

3. С целью обеспечения "безглючной" отработки ПП прерывания, нужно


озаботиться "банковскими делами", в части касающейся процедуры
сохранения/восстановления содержимого регистров W и Status.

Это выглядит так:


..............................
.............................. ДЛЯ PIC16F873A
;================================================================================
; Регистры общего назачения.
;================================================================================
..............................
..............................
;--------------------------------------------------------------------------------
; Регистры, используемые в ПП прерывания для сохранения содержимого W и Status.
;--------------------------------------------------------------------------------
W_Temp equ 20h ; Регистр сохранения содержимого W
; в 0-м банке.
W_Temp1 equ 0A0h ; Регистр сохранения содержимого W
; в 1-м банке.
Stat_Temp equ 21h ; Регистр сохранения содержимого Status
; в 0-м банке.
Stat_Temp1 equ 0A1h ; Регистр сохранения содержимого Status
; в 1-м банке.
;--------------------------------------------------------------------------------
; Всякая всячина.
;--------------------------------------------------------------------------------
Flag equ 22h ; Регистр флагов:
; бит №7 - флаг признака банка,
..............................
..............................
;================================================================================
..............................
..............................
;================================================================================
org 0 ; Начать выполнение программы с 0 адреса PC.
goto START ; Переход в ПП START.
org 4 ; Назначение вектора прерывания.
;********************************************************************************

;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; ПОДПРОГРАММА ПРЕРЫВАНИЯ. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; Процедура сохранения содержимого регистров Status и W.
;================================================================================
; Определение банка, из которого осуществлен уход в прерывание.
;--------------------------------------------------------------------------------
btfsc Status,RP0 ; Из какого банка осуществлен уход
; в прерывание ?
goto BANK_1 ; Если это 1-й банк.
; Если это 0-й банк, то программа
6
; исполняется далее.
;--------------------------------------------------------------------------------
; Процедура сохранения Status и W в регистрах 0-го банка (Stat_Temp, W_Temp).
;--------------------------------------------------------------------------------
movwf W_Temp ; W -> W_Temp.
swapf Status,W ; Смена п/байтов регистра Status.
; Результат -> W.
movwf Stat_Temp ; W -> Stat_Temp.
bcf Flag,7 ; Установка флага признака банка
; (Flag,7=0: 0-й банк).
; Используется при восстановлении.
goto ZAMER ; Переход на начало АЦП.
;--------------------------------------------------------------------------------
; Процедура сохранения Status и W в регистрах 1-го банка (Stat_Temp1, W_Temp1).
;--------------------------------------------------------------------------------
BANK_1 movwf W_Temp1 ; W -> W_Temp1.
swapf Status,W ; Смена п/байтов регистра Status.
; Результат -> W.
movwf Stat_Temp1 ; W -> Stat_Temp1.
bcf Status,RP0 ; Сброс 0-го банка.
bsf Flag,7 ; Установка флага признака банка
; (Flag,7=1: 1-й банк).
; Используется при восстановлении.
;================================================================================
..............................
.............................. ОСНОВНЫЕ ДЕЛА
..............................
..............................
;================================================================================
; Процедура восстановления содержимого регистров Status, W и выхода из прерывания
;================================================================================
btfss Flag,7 ; Каково состояние флага признака банка ?
goto VOSST_0 ; Если 0-й банк (Flag,7=0), то работа
; с Stat_Temp и W_Temp.
; Если 1-й банк (Flag,7=1), то работа
; с Stat_Temp1 и W_Temp1.
;--------------------------------------------------------------------------------
; Процедура восстановления Status и W из содержимого регистров 1-го банка
; (Stat_Temp1, W_Temp1).
;--------------------------------------------------------------------------------
bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.

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


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

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


retfie ; Возврат из прерывания с 0-м банком (с 0-м
; банком вошли в прерывание, с 0-м банком
; и вышли).
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

7
В начале ПП прерывания, определяется, из какого банка (0-го или 1-го) произошел
уход в прерывание (btfsc Status,RP0).
В зависимости от этого, отрабатывается:
- либо процедура сохранения содержимого регистров Status и W в регистрах
0-го банка,
- либо процедура сохранения содержимого регистров Status и W в регистрах
1-го банка.
В конце этих процедур, флаг признака банка (бит №7 регистра Flag) либо опускается
(признак 0-го банка), либо поднимается (признак 1-го банка).
Это необходимо для того, чтобы в последующем, при восстановлении содержимого
регистров W и Status, программа "сообразила" (см. btfss Flag,7), из какой именно пары
регистров нужно произвести это восстановление.
И процедура сохранения, и процедура восстановления - "штатные".
Только они "клонированные" (хочешь жить - умей вертеться. Народная мудрость).
Вот и вся "прерывательная" специфика для PIC16F873A.
Если этого не сделать, то будет "хенде хох" и "Гитлер капут" вместе взятые, так как
восстановится не то, что нужно, а форменное безобразие.
Проверено жизнью. Через "пинки". Короче, аксиома.
А кто не внял, тому будет "фингал". Однозначно.
Эти пары регистров можно "прописать" как угодно, лишь бы эти пары были
"прописаны" в соответствующих банках.
Примечание: если речь идет хотя бы о более-менее сложной программе, в которой
используются прерывания, то регистры W и Status это святое.
Их содержимое, в ПП прерывания, обязательно нужно сохранить/восстановить.
Следующим по значимости, является регистр PCLATH.
Сохранение/восстановление его содержимого актуально, например, тогда, когда имеются
таблицы вычисляемых переходов, через которые проходит "граница" между блоками
памяти программ или тогда, когда объем программы вышел за "границу" одной
страницы памяти программ.
Если такое имеет место быть, то в ПП прерывания, сохранение содержимого регистра
PCLATH должно производиться последним, а восстановление - первым (по отношению
к "связке" W/Status).
В обеих случаях, используются пары команд movf/movwf.
То же самое относится и к другим "жизненно важным" регистрам.

4. С целью обеспечения максимальной скорости отработки процедуры


инициализации графического модуля MT-16S2D-2YLG, нужно "сваять
нештатную" процедуру инициализации, с полномасштабным задействованием
флага BF.

Результат этого "ваяния" выглядит так:

..............................
.............................. Для ЖК-модуля MT-16S2D-2YLG
;================================================================================
; Универсальная задержка (время задержки определяется предустановленным
; содержимым W).
;================================================================================
PAUSE_X movwf Reg ; Стандартный, вычитающий,
decfsz Reg,F ; однобайтный
goto $-1 ; счетчик.
return ; Возврат по стеку.
;================================================================================
; ПП "плавающей" задержки на основе анализа состояния флага занятости BF
; (вариант для 4-разрядного интерфейса).
;================================================================================
ENTER_BF movwf Mem ; Переправка старшего п/байта регистра W на
movwf PortB ; линии RB4...7.
;-----------------------------------
; Запуск в работу старшего п/байта.

8
;-----------------------------------
nop ; Задержка в 1 м.ц.
bsf PortC,E ; Установка на линии Е "1".
nop ; Задержка в 1 м.ц.
bcf PortC,E ; Установка на линии Е "0".

swapf Mem,W ; Смена п/байтов с сохранением результата


; операции в W.
movwf PortB ; Переправка младшего п/байта регистра W на
; линии RB4...7.
;-----------------------------------
; Запуск в работу младшего п/байта.
;-----------------------------------
nop ; Задержка в 1 м.ц.
bsf PortC,E ; Установка на линии Е "1".
nop ; Задержка в 1 м.ц.
bcf PortC,E ; Установка на линии Е "0".
;-----------------------------------
; Подготовка к проверке флага BF.
;-----------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
movlw b'11110000' ; Запись в W "11110000"
movwf TrisB ; RB4...7 работают на вход, а RB0...3 работают
; на выход.
bcf Status,RP0 ; Переход в 0-й банк.

bcf PortC,RS ; Установка на линии RS "0" (режим команд).


bsf PortC,RW ; Линия RW в "1" (режим чтения данных).
nop ; Задержка в 1 м.ц.
bsf PortC,E ; Установка на лини Е "1".
nop ; Задержка в 1 м.ц.
;-----------------------------------
; Сама проверка.
;-----------------------------------
btfsc PortB,BF ; Проверка состояния флага занятости BF.
goto $-1 ; Если BF=1, то продолжение задержки до тех
; пор, пока BF не установится в "0"
; (программа исполняется далее).
;-----------------------------------
; Завершение процедуры.
;-----------------------------------
clrf PortC ; Сброс в "0" всех защелок порта А
; (RW=0, RS=0, E=0).
bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisB ; Все выводы порта В работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.
return ; Возврат по стеку.
;================================================================================
..............................
..............................
;================================================================================
; Подпрограмма инициализации ЖКИ модуля.
;================================================================================
movlw b'00110000' ; Установка: 8-разрядный интерфейс, 1 строка,
; 5х8 точек, 0-я страница знакогенератора.
call ENTER_BF ; "Плавающая" задержка со стробом
; под команду 00110000.
;----> Возврат по стеку из ПП ENTER_BF.
movlw .15 ;
call PAUSE_X ; Задержка 50 мкс.
;----> Возврат по стеку из ПП PAUSE.
movlw b'00101000' ; Установка: 4-разрядный интерфейс, 2 строки,
; 5х8 точек, 0-я страница знакогенератора.
call ENTER_BF ; "Плавающая" задержка со стробом
; под команду 00101000.
;----> Возврат по стеку из ПП ENTER_BF.
9
movlw b'00101000' ; Установка: 4-разрядный интерфейс, 2 строки,
; 5х8 точек, 0-я страница знакогенератора.
call ENTER_BF ; "Плавающая" задержка со стробом
; под команду 00101000.
;----> Возврат по стеку из ПП ENTER_BF.
movlw b'00000001' ; Установка: очистка дисплея со сбросом
; данных, установка курсора в начало
; 1-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом
; под команду 00000001.
;----> Возврат по стеку из ПП ENTER_BF.
movlw b'00001100' ; Установка: дисплей включен, видимое
; отображение курсора выключено.
call ENTER_BF ; "Плавающая" задержка со стробом
; под команду 00001100.
;----> Возврат по стеку из ПП ENTER_BF.

;////////////////////////////////////////////////////////////////////////////////
; Вывод на индикацию картинки 1-го "кадра".
;////////////////////////////////////////////////////////////////////////////////
..............................
..............................

ПП ENTER_BF - "стандартная" (для 4-разрядного интерфейса).


Ничего нового в ней нет. Просто "передрана" из ранее "нарытого".
В ПП инициализации ЖК-модуля, имеется всего одна фиксированная задержка.
Все остальные - "плавающие".
Наличие фиксированной задержки обусловлено тем, что после отработки инструкции
00110000, флаг BF поднимается, но не в момент окончания ее отработки (как при
исполнении других инструкций), а раньше на несколько мкс.
Это и есть специфика.
Использована фиксированная задержка (50 мкс.), с большим "запасом".
Реально, интервал времени, между поднятием флага BF и окончанием отработки
инструкции 00110000, гораздо меньше.
Можно исполнить инструкцию 00110000 не один раз, а 3 раза (нечетное число раз), но
только в "связке" с фиксированной задержкой.
Если исполнить ее четное количество раз (например, 2 раза), то инициализации не
получится.
Лично я, наблюдал именно такой "расклад".
Но если инициализация нормально проходит в случае отработки одной инструкции
00110000, то зачем исполнять ее 3 раза (так обозначено в даташите)?
Двойное исполнение инструкции 00101000 обусловлено тем, что при "одинарном" ее
исполнении, выбора нулевой страницы знакогенератора не происходит (устанавливается
1-я страница).
По крайней мере, я, наблюдал именно это.
Выбор страницы знакогенератора происходит в бите №1 (0 - 0-я страница, 1 - 1-я
страница).
В бите №3, должна быть установлена 1.
В этом и заключаются "управленческие" различия между одностраничными
ЖК-модулями и двухстраничными.
А в остальных "управленческих делах" - одинаковость.
Эта процедура работает четко. Я не зафиксировал ни одного сбоя.

5. Нужно озаботиться составлением "проматеринской" принципиальной схемы.

Принципиальная схема "проматеринской железяки" показана на рис. 1 (см. ниже).


Аналоговыми входами назначены выводы RA0 и RA1.
На первых порах, к ним подключены "заменители", в виде переменных резисторов
номиналом по 10 Ком.
Подойдет время, подключу и нечто более "солидное", а пока и так сойдет.

10
Сначала, нужно убедиться в "жизнеспособности проматери", а заодно и навести в ней
порядок.
Выбираю диапазон квантования напряжения от GND (0 в.) до +Uпит.
Следовательно, для приведения шага квантования к 5 мв., нужно, чтобы +Uпит. было
равно 5,12 в. (5 х 1024 = 5120 мв. = 5,12 в.)
Это и имеет место быть.

Так как речь идет о "серьезном" измерительном приборе, то задействован кварцевый


генератор.
Пока, применяется кварц на 4 Мгц., но в дальнейшем, его номинал можно и увеличить.
Ранее, я никогда не включал подсветку, но на этот раз включил.
Для достижения ее максимальной яркости, нужно просто соединить вывод +LED с
плюсом источника питания.
Но я сделал это через гасящий резистор. Зачем нужен "прожектор"?
Обратите внимание на отсутствие подстроечного резистора регулировки контрастности.
Вывод Uо просто соединяется с корпусом.
Именно под такое соединение, на заводе-изготовителе, и произведена установка
максимальной контрастности.
Это четко работает вплоть до отрицательных температур, что является несомненным
плюсом. А вот и результат работы этой "железяки":

11
Не обращайте внимания на кривизну картинки. Это "фотоаппаратная бяка".
Я выставил десятичные точки, но в случае чего, их можно и убрать.
Нет проблем.
О программе, результат работы которой Вы видите, речь пойдет в следующем
подразделе.

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

13