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

3/1.

"Нейрохирургическая операция" по чтению из памяти 24С64А


одного байта данных. Детальное объяснение.
Чтение буду "ломать" по такому же принципу, как и запись.
Итак, читаю один байт данных из той же ячейки памяти, что и при записи (адрес
02h).
Для того чтобы "привязаться" к конкретному числу, сначала, в PonyProg, нужно
записать в ячейку памяти 24С64А, с адресом 02h, это "конкретное" число.
Я писал число 1010 1010 (AAh), но можно записать и любое другое число.
Далее "вскакивает" вопрос об индикации считанного.
Под это дело, можно было бы "подпрячь", например, ЖКИ модуль, но, для начала,
это слишком "круто". Может возникнуть совершенно не нужный "напряг".
А посему, пока обойдусь банальными светодиодами.
Вот что получилось:

Индикация значения считанного числа (в стандартном, весовом коде) производится в


линейке из светодиодов.
Светодиод активен - единица ("горит"), а пассивен - ноль (не "горит").
Так как порт В полностью занят, то линии SDA, SCL, кнопку "Пуск чтения" и
светодиод "Окончание чтения", я "посадил" на выводы порта А, который не имеет
подтягивающих резисторов.
Этим и обусловлено наличие внешних подтягивающих резисторов линии SDA и
кнопки "Пуск чтения".
Если в 24С64А предварительно будет записано число 1010 1010, то светодиоды
будут активны "через раз", что удобно.

Принцип "конфигурирования начинки" 24С64А под режим чтения и принцип


чтения.

То, что я говорил ранее (в части касающейся 1-го режимного байта и адресного запроса),
повторять не буду.
Расскажу только о специфике.
Вопрос: "Что происходит после прохождения 2-го режимного байта (того, в
котором бит R/W=1)"?
Ответ (пока, в общем виде): "начинка" 24С64А должна "сконфигурироваться"
(перестроиться) под процедуру чтения.
1
Что должно быть сигналом к этому "конфигурированию"?
Рассуждаю.
Зачем нужен сигнал АСК, вырабатываемый 24С64А?
В части касающейся "технологических" байтов, он нужен для того, чтобы сообщить
"мастеру" об успешном окончании всех подготовительных действий,
осуществляемых внутри 24С64А, а его наличие означает готовность 24С64А к
дальнейшей работе и является условием ее продолжения.
"Глобальный" вывод (и для чтения, и для записи, в части касающейся сигнала
АСК, выдаваемого 24С64А под "технологические" байты): так как сигнал АСК
начинает формироваться только через некоторое время после прохождения
переднего строба импульса 9-го такта (см. рис. 4 первого подраздела 2-го
раздела), то именно этот строб (а не задний строб) должен "запускать" процедуру
"конфигурирования".
Только после этого, при условии успешного завершения "конфигурирования" (в том
числе и установки адреса), 24С64А выдает в линию SDA сигнал АСК (в этом и
заключается смысл его наличия).
Есть ли в этом какая-то "бяка"?
Нет, так как речь идет об обычном электронном, непрограммируемом (в части
касающейся "обслуги" EEPROM памяти) устройстве, в котором одним стробом
может запускаться сразу (а не последовательно, как в устройстве, работающем по
программе) несколько действий (электронщики это прекрасно поймут).
Кроме того, если есть необходимость в формировании разнесенных во времени
стробов, то "дочерний" строб (или несколько "дочерних" стробов) можно получить
из "материнского" строба, при помощи его небольшой задержки (порядка десятков
наносекунд, этого достаточно) аппаратными средствами 24С64А.
Никаких технических проблем в этом нет.
Это уже вопрос конкретной схемотехники ("епархия" разработчиков). На суть не
влияет.
Что понимается под словом "конфигурирование"?
При чтении, в 24С64А, должно быть задействовано некое устройство, из которого,
побитно, будет производиться считывание байта данных, то есть, с его помощью,
должен быть осуществлен переход от внутреннего, параллельного интерфеса к
внутреннему (а затем и внешнему), последовательному интерфейсу.
Устройства такого типа широко известны. Это сдвиговый регистр,
обеспечивающий (на каждом такте) побитный вывод байта, предварительно
записанного в него с 8-ми входов предустановки.
В данном случае (в режиме чтения), именно он является регистром данных.
Внутренний, 8-разрядный, сдвиговый регистр 24С64А имеет 8 входов
предустановки.
В результате адресного выбора ячейки памяти, из которой нужно считать байт
данных, этот байт "выставляется" на входах предустановки.
Затем, через интервал времени порядка десятков наносекунд (формируется в
24С64А аппаратно), на управляющий вход записи сдвигового регистра поступает
"дочерний" строб, по которому байт данных, за очень короткое время,
переписывается с входов предустановки сдвигового регистра в его триггеры.
Итак, выбранный (по адресному запросу) байт данных, записан в триггеры
внутреннего, сдвигового регистра и готов для побитного считывания.
Примечание: вывод битов из сдвигового регистра происходит, начиная с бита №7.
Если бит №7 "лежит" в старшем разряде сдвигового регистра, то это соответствует
сдвигу влево (аналог - команда rlf).
Считывания куда?
В линию SDA.
Посредством чего?
Посредством транзистора оконечного каскада формирователя сигнала АСК, ведь,
в 24С64А, только он работает "на передачу" (альтернативы нет).
Следовательно, выход защелки старшего разряда сдвигового регистра должен
быть подключен к входу оконечного каскада формирователя сигнала АСК.

2
Но если сделать это буквально, то, сразу же после перезаписи байта из ячейки
EEPROM памяти в сдвиговый регистр, на линии SDA выставится значение бита
№7, а тактовый импульс №1 выставит значение бита №6 (а нужно - №7) и т.д., что
есть совсем не "зер гут".
Следовательно, сдвиговый регистр, в своем составе, должен иметь некое
буферное устройство, функция которого примерно такая же, как и функция бита
С регистра Status.
Это буферное устройство представляет собой простейшую однобитную защелку, в
которой предварительно установлен уровень, который, для транзистора АСК,
является закрывающим и которая (защелка) входит в состав сдвигового регистра
на правах "довеска" (что-то типа 9-го разряда регистра).
В этом случае "все мягко и пушисто": в интервале времени между окончанием
формирования сигнала АСК и началом формирования тактового импульса №1, на
линии SDA будет "стоять" единица (с учетом того, что бит R/W=1. Об этом - см.
ниже), а тактовый импульс №1 выставит на линии SDA уровень бита №7
считываемого байта данных (далее, по порядку).
Из контекста сказанного понятно, что, для внутреннего, сдвигового регистра,
тактовым сигналом будет "пачка" тактовых импульсов №№ 1 ... 8, формируемая
"мастером" на линии SCL.
Смена битов на линии SDA осуществляется по передним стробам импульсов этой
"пачки".
На каждом такте, происходит сдвиг содержимого этого регистра влево, чем и
обеспечивается требуемый порядок вывода битов считываемого байта на линию
SDA (№7 ... №0).
После прохождения всех 8-ми тактовых импульсов, внутренний, сдвиговый регистр
"очистится" от всех битов текущего байта считываемых данных и будет готов к
"загрузке" байта данных из следующей ячейки памяти (в случае потокового
чтения).
Причем, то, что, на момент "очищения", в нем будет "лежать", не важно, так как,
при последующей записи (в сдвиговый регистр) следующего байта данных (если
речь идет о потоковом чтении), это "то" уничтожится (запись "по верху").
Итак, "механика" процесса чтения, в общих чертах, более-менее понятна (я
надеюсь на это).
Теперь нужно "провентиллировать" вопросы, связанные с подготовкой к чтению.
Переход в режим чтения должен быть осуществлен в промежутке времени между
передним стробом импульса 9-го такта, вырабатываемого под 2-й режимный байт,
и до начала формирования сигнала АСК, так как сигнал АСК должен начать
формироваться только после успешного завершения этого перехода.
Но сигнал АСК, под 2-й режимный байт, это сигнал АСК, сформированный под
режим записи, в 24С64А, 2-го режимного байта, а речь-то идет о режиме чтения,
установку которого этот сигнал и подтверждает?
Возникает понятийное "бардальеро": вроде как, одновременно, имеет место быть и
режим записи, и режим чтения?
Вот такой "кроссворд"...
Предлагаю Вам свой способ решения этого "кроссворда".
"Собака зарыта" в порядке подключения, к входу оконечного каскада
формирователя сигнала АСК, устройств, его обслуживающих.
При работе 24С64А (по линии SDA) "на вход" (прием "технологических" байтов и
байтов данных, которые нужно записать в память), оконечный каскад
формирователя сигнала АСК управляется устройством, формирующим
соответствующий сигнал сигнал АСК (выдается со стороны 24С64А), а при работе
"на выход" (передача 24С64А байтов, считанных из ее памяти), оконечный каскад
формирователя сигнала АСК управляется упомянутым выше сдвиговым регистром
(через его буферное устройство).
Примечание: при работе 24С64А "на выход", во время передачи в линию SDA
считанных байтов данных, 24С64А вообще не вырабатывает своего сигнала АСК, а
сигнал АСК вырабатывается "мастером".

3
"Кроссворд" можно решить, предположив, что, в интервале времени между
передним стробом импульса 9-го такта, вырабатываемого под 2-й режимный байт,
и началом формирования импульса АСК, "конфигурирование" 24C64А под режим
чтения происходит, но это "конфигурирование", хотя оно и выполнено почти в
полном объеме (о чем свидетельствует сигнал АСК), но является не
окончательным, а является предварительным.
Все основное сделано, но не хватает одной "чисто технологической детальки" -
подключения, к входу оконечного каскада формирователя сигнала АСК, выхода
буферного устройства, входящего в состав сдвигового регистра.
Это подключение происходит по заднему стробу импульса 9-го такта,
вырабатываемого под 2-й режимный байт. Другого просто не дано.
По этому стробу, заканчивается формирование сигнала АСК, вырабатываемого
24С64А под 2-й режимный байт, и одновременно, полностью завершается
"конфигурирование начинки" 24С64А под режим чтения.
Проще говоря, после формирования заднего строба импульса 9-го такта,
вырабатываемого под 2-й режимный байт, можно читать.
Что происходит, после этого, с выходом устройства формирования сигнала АСК
24С64А?
Он может быть, по тому же заднему стробу, на все время считывания байтов
данных из памяти, либо установлен в Z-состояние (что вероятнее всего), либо, при
помощи внутреннего, электронного коммутатора, отключен от входа оконечного
каскада формирователя сигнала АСК.
Это уже вопрос не принципиальный, и пусть этим "забивают себе головы"
разработчики.
Принципиально важно то, что оконечный каскад формирователя сигнала АСК
управляется только внутренним, сдвиговым регистром, и по факту, в данном
случае, после завершения "конфигурирования", речь идет не о формировании
сигнала АСК (хотя и задействуется оконечный каскад формирователя сигнала
АСК), а о считывании байтов данных, из памяти 24С64А, в линию SDA,
посредством задействования оконечного каскада формирователя сигнала АСК.
Еще раз напоминаю, что, в данном случае (режим чтения), после завершения
"конфигурирования" и в процессе считывания байтов данных из памяти 24С64А,
сигналы АСК будут вырабатываться не 24С64А, а "мастером". Это важно.
То что Вы прочитали, на мой взгляд, является единственно разумным
объяснением.
А теперь более детально о процессах, происходящих во время прохождения
импульса 9-го такта, вырабатываемого "мастером" после 2-го режимного байта.
По переднему стробу импульса 9-го такта, 24С64А быстро соображает, что бит
R/W=1 и нужно "сконфигурироваться" под процедуру чтения, после чего,
внутренний коммутатор, образно выражаясь, пропускает импульс 9-го такта через
свою "проходную" в то "место", где можно "от души сконфигурироваться".
Естественно, что на "проверку пропуска" требуется некоторое время, и по этой
причине, передний строб импульса 9-го такта, на время "проверки пропуска",
несколько подзадержится.
Это означает то, что внутри 24С64А, по "материнскому" стробу, вырабатывается (с
задержкой во времени) "дочерний" строб, который и запускает процесс
"конфигурирования".
С учетом малого времени этой задержки и для обеспечения простоты объяснения,
я пренебрегу этой задержкой и далее буду считать, что ее не было (но имейте
сказанное ввиду).
В том месте, где можно "от души сконфигурироваться" (в "начинке" 24С64А,
обслуживающей работу EEPROM памяти), происходит следующее:
1. Передний строб импульса 9-го такта запускает в работу следующие аппаратные
процедуры:
- Запись, в счетчик адреса, адреса, указанного в адресном запросе.
Это означает очень быстрое считывание байта, из выбранной (по адресному
запросу) ячейки памяти, на внутреннюю, 8-разрядную шину (по внутреннему,

4
быстрому, параллельному интерфейсу), "намертво" подключенную к входам
предустановки внутреннего, сдвигового регистра.
То есть, на входах предустановки внутреннего, сдвигового регистра,
устанавливается байт, предназначенный для дальнейшей записи в этот сдвиговый
регистр.
- На выходе буферного устройства, входящего в состав внутреннего, сдвигового
регистра, заранее (до коммутации выхода буферного устройства на вход
оконечного каскада формирователя сигнала АСК) установливается уровень,
соответствующий закрыванию транзистора оконечного каскада формирователя
сигнала АСК.
2. Так как, во избежание ошибок, запись байта данных, с входов предустановки
внутреннего, сдвигового регистра, в его триггеры, нужно производить только после
гарантированно надежной установки и фиксации байта данных на этих входах
предустановки, то, инициировать эту запись передним стробом импульса 9-го такта
нельзя.
Следовательно, аппаратными средствами 24С64А, производится аппаратная
задержка переднего строба импульса 9-го такта на время необходимое для
гарантированно надежной установки и фиксации байта данных на входах
предустановки внутреннего, сдвигового регистра.
Величина этой задержки очень мала и с аппаратной точки зрения, в ее
реализации, никакой сложности нет.
Таким образом, имеется 2 строба - "материнский" и "дочерний".
Соответственно, они, с разнесением во времени, "обслуживают" последовательное
исполнение 2-х групп действий.
Сначала исполняются действия, которые инициируются "материнским" стробом
(см. пункт 1), а затем исполняется действие, о котором идет речь в этом пункте.
Задержка "дочернего" строба относительно "материнского", аппаратно, может быть
организована несколькими способами.
В стратегическом смысле, для конструктора, это не важно. Пусть это определяют
разработчики, это их хлеб.
Важно только то, что эта задержка есть, и она обеспечивает безошибочную запись
считываемого байта данных в триггеры внутреннего, сдвигового регистра.
3. Во время исполнения указанных выше действий, логическое устройство 24С64А
постоянно анализирует уровни на подключенных, к его входам, "контрольных
точках".
После успешного завершения исполнения всех необходимых действий (в части
касающейся основных действий по "конфигурированию начинки" 24С64А под
режим чтения), логическое устройство разрешает формирование сигнала АСК.
Сигнал АСК будет выдаваться в линию SDA (со стороны 24С64А) до обнаружения
его "мастером".
После этого, "мастер" формирует задний строб импульса 9-го такта.
По этому стробу:
- завершается формирование сигнала АСК, вырабатываемого 24С64А,
- завершается процесс "конфигурирования начинки" 24С64А под процедуру чтения,
то есть, выход буферного устройства, входящего в состав внутреннего, сдвигового
регистра, подключается к входу оконечного каскада формирователя сигнала АСК,
после чего на линии SDA устанавливается 1.
Эта единица будет присутствовать на линии SDA вплоть до формирования
"мастером" переднего строба импульса 1-го такта, как за счет подтягивающего
резистора линии SDA (во время пассивных состояний), так и за счет того, что бит
R/W=1.
Теперь можно читать.
Установка на линии SDA того или иного значения битов читаемого байта
происходит по передним стробам тактовых импульсов №№ 1 ...8.
Если говорить в общем виде, то после надежной фиксации, на линии SDA, уровня
текущего бита, "мастер" определяет (идентифицирует) его значение, после чего
"закладывает это значение в закрома" своей оперативной памяти (в регистр

5
общего назначения).
Это последовательно будет происходить до тех пор, пока в эти "закрома" не
"заложится" весь байт.
Итог: из выбранной ячейки памяти считан байт данных.
То, что Вы прочитали, есть основа понимания принципа чтения одного байта
данных.
А теперь, когда с принципом чтения, в общем виде, все понятно, "ухожу в
программный сектор", с целью "воплощения его в жизнь".

Принцип побитного чтения байта.

Группа команд побитного чтения байта данных является основой ПП чтения байта
данных.
Эта ПП, в соответствии с количеством битов в байте, является 8-цикловой (один
ее полный цикл равен 8-ми внутренним циклам).
Биты считываются с линии SDA, по передним стробам тактовых импульсов №№
1 ... 8, начиная с бита №7.
После считывания текущего бита, начинается следующий цикл считывания бита
более младшего разряда.
Считывание происходит правее "границ" между битами считываемого байта, то
есть, в моменты гарантированно надежной фиксации уровней битов на линии SDA.
Считанные с линии SDA биты, постепенно "накапливаются" в сдвиговом регистре,
организуемом программно (не путать с внутренним, сдвиговым регистром
24С64А!).
После завершения полного цикла побитного считывания байта, считанные с линии
SDA 8 битов, полностью заполнят этот сдвиговый регистр, причем, в порядке - бит
№7 ... бит №0, что и требуется.
А дальше, можно делать с этим байтом данных все, что угодно.
В предлагаемом Вашему вниманию проверочном устройстве (см. рис. 1), я вывел
считанный байт данных в порт В, с целью примитивной индикации его числового
значения.
Можно "состряпать" и что-то другое. Вариантов - тьма.
"Вгрызаюсь в сердцевину".
Вопрос: "Как программно организуется сдвиговый регистр"?
Ответ: при помощи назначенного, под это дело, регистра общего назначения,
содержимое которого периодически сдвигается на 1 разряд, в результате
обращения к нему команды циклического сдвига (rlf или rrf). Результат сдвига
должен быть сохранен в регистре.
В данном случае, для обеспечения требуемого порядка расположения битов в
байте (№7 ... №0), требуется сдвиг влево и нужно применить команду rlf.
Команды циклического сдвига работают в "связке" с битом С регистра Status,
значит и он тоже должен быть "при деле".
Какова, в данном случае, функция бита С?
По определению, в результате каждого сдвига, из него, в бит №0 (при применении
команды rlf), должен "выпихиваться" "лежащий" в нем (в бите С) бит. Другого не
дано.
Вывод: биты, последовательно считываемые с линии SDA, нужно, также
последовательно, записывать в бит С.
Но как записывать, ведь команды, организующей "прямую" запись бита, с линии
SDA в бит С, нет?
Вспомните ПП досчета (аналогия). В ней, примерно, такая же "петрушка".
Как была решена проблема?
Проблема была решена "через задний проход", то есть, при помощи не прямого, а
косвенного воздействия на байт, "лежащий" в предделителе.
В нашем же случае, еще проще, так как речь идет не о байте, а о "паршивом" бите.
Таким образом, с "неизбежностью мировой революции", напрашивается вывод о
том, что, при анализе (а как же без него?) состояния линии SDA, должна быть

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

Сдвиговый регистр программно организован на регистре общего назначения Read.


Цикл чтения бита начинается со сброса бита С в 0.
Далее, при помощи бит-ориентированной команды ветвления, анализируется
состояние линии SDA.
Соответственно, будут иметь место быть 2 сценария "развития событий":
1. Если на линии SDA обнаружен 0, то, проще говоря, ничего не происходит, и в
бите С так и останется "лежать" установленный ранее 0.
Этот 0, после сдвига (смещения всех битов регистра Read влево), и перепишется в
самый младший разряд регистра Read.
2. Если на линии SDA обнаружена 1, то в бит С записывается 1.
Эта 1, после сдвига (смещения всех битов регистра Read влево), и перепишется в
самый младший разряд регистра Read.
Как видите, подобным, на изумление простым, способом, организовано косвенное
воздействие на состояние бита С, выражающееся в однозначной "привязке"
состояния бита С к состоянию линии SDA (на момент анализа).
Какова "участь" битов того байта, который был побитно считан в регистр Read в
предыдущем цикле считывания?
Эта "участь" называется "Гитлер капут": хотя они, после сдвига, и "вытесняются"
(из самого старшего разряда регистра Read) в бит С, но толка от этого никакого,
так как, в начале цикла чтения бита данных, происходит сброс бита С в 0.
Итак, есть все необходимое, чтобы "сваять" учебную программу чтения одного
байта данных из памяти 24С64А.
Эта программа называется Read_1.asm.
;
*************************************************************************
*******
; Read_1.asm ЧТЕНИЕ ИЗ 24С64А ОДНОГО БАЙТА ДАННЫХ
; (учебная, одноцикловая программа).
;
*************************************************************************
*******
; "Практикум по конструированию устройств на PIC контроллерах".
; Автор: Корабельников Евгений Александрович
; http://ikarab.narod.ru karabea@lipetsk.ru

7
; Эта программа входит в состав 1-го подраздела 3-го раздела.
;
*************************************************************************
*******
; "Мастер" - PIC16F84A.
; "Помощник" - 24C64A.
; Кнопка пуска чтения подключена к выводу RA0.
; Светодиод (индицирует конец цикла чтения) подключен к выводу RA1.
; Вывод RA2 подключен к линии такта (SCL).
; Вывод RA3 подключен к линии данных (SDA).
; Порт В задействован под индикацию числового значения считанного байта
; в двоичном, весовом коде (светодиод активен - 1, не активен - 0).
; Кварц 4 Мгц. (1м.ц.=1мкс.).
; Объем программы: 78 команд.
;
*************************************************************************
*******
LIST p=16F84A ; Установка типа микроконтроллера.
__CONFIG 03FF5H ; Бит защиты выключен, WDT включен,
; стандартный XT генератор.
;============================================================================
; Определение положения регистров специального назначения.
;============================================================================
OptionR equ 01h ; Регистр OptionR - 1-й банк.
Status equ 03h ; Регистр Status.
TrisA equ 05h ; Регистр TrisA - 1-й банк.
TrisB equ 06h ; Регистр TrisB - 1-й банк.
PortA equ 05h ; Регистр управления защелками порта A.
PortB equ 06h ; Регистр управления защелками порта В.
;============================================================================
; Определение названий и положения регистров общего назначения.
;============================================================================
Temp equ 0Ch ;Регистр обработки данных при передаче байта.
Count equ 0Dh ; Счетчик битов байта.
Read equ 0Eh ;Регистр обработки данных при чтении байта.
;============================================================================
;"Привязка" названий битов регистров специального назначения к номерам битов.
;============================================================================
RP0 equ 5 ; Бит выбора банка.
C equ 0 ; Бит флага переноса-заёма.
SCL equ 2 ;Бит регистра PortA, который формирует такт.
SDA equ 3 ;Бит регистра PortA, который формирует данные
;============================================================================
; Определение места размещения результатов операций.
;============================================================================
F equ 1 ; Результат направить в регистр.
W equ 0 ; Результат направить в аккумулятор.
;============================================================================
org 0 ; Начать выполнение программы с нулевого
; адреса PC.
;****************************************************************************

;****************************************************************************
; "РАБОЧАЯ ЧАСТЬ" ПРОГРАММЫ.
;****************************************************************************
; Подготовительные операции.
;============================================================================
bsf Status,RP0 ; Переход в 1-й банк.
movlw b'00000001' ;RA0(кнему подключена кнопка) работает "на
movwf TrisA ; вход", остальные RA...работают на выход.
clrf TrisB ; Все RB... работают на выход.
movlw b'11111101' ; Предделитель с Кдел.=32 подключен к WDT,
movwf OptionR ;подтягивающие резисторы порта В
; отключены.

8
bcf Status,RP0 ; Переход в 0-й банк.

movlw b'00001100' ;На линиях SDA и SCL выставляются единицы,


movwf PortA ; светодиод погашен.

clrf PortB ; "Гашение" светодиодов, подключенных к


; RB0...7.
;---------------------------------------------------------
; Ожидание нажатия кнопки.
;---------------------------------------------------------
KNOPKA_NO clrwdt ; Сброс WDT.
btfsc PortA,0 ; Если кнопка отжата, то уход в
goto KNOPKA_NO ; "вечное кольцо" ПП KNOPKA_NO.
; Если кнопка нажата, то программа
; исполняется далее.
;****************************************************************************
; ПРОЦЕДУРА ЧТЕНИЯ
;****************************************************************************
; Формирование старт-условия.
;============================================================================
bcf PortA,SDA ; SDA=0.
bcf PortA,SCL ; SCL=0.
;============================================================================
; "Администраторская" ПП (без названия), "рулящая" очередностью обработки
байтов.
;============================================================================
; Задание числового значения режимного байта (для записи).
;---------------------------------------------------------
movlw B'10100000' ;Запись в регистр Temp режимного байта
; (1010- код функциональности,
movwf Temp ; 000–адрес м/схемы, 0–режим записи).
call BAIT_WR ; Условный переход в ПП передачи байта
; BAIT_WR.
;-----> Возврат по стеку из ПП BAIT_WR.
;---------------------------------------------------------
; Задание числового значения старшего байта адреса.
;---------------------------------------------------------
movlw .0 ; Запись в регистр Temp
movwf Temp ; старшего байта адреса.
call BAIT_WR ; Условный переход в ПП передачи байта
; BAIT_WR.
;-----> Возврат по стеку из ПП BAIT_WR.
;---------------------------------------------------------
; Задание числового значения младшего байта адреса.
;---------------------------------------------------------
movlw .2 ; Запись в регистр Temp
movwf Temp ; младшего байта адреса.
call BAIT_WR ; Условный переход в ПП передачи байта
; BAIT_WR.
;-----> Возврат по стеку из ПП BAIT_WR.
;===========================================================================
; Формирование стоп-условия.
;============================================================================
bcf PortA,SDA ; SDA=0.
bsf PortA,SCL ; SCL=1.
bsf PortA,SDA ; SDA=1.
nop ; Задержка на 1 м.ц.
;----------------------------------------------------------------------------
; Формирование старт-условия.
;============================================================================
bcf PortA,SDA ; SDA=0.
bcf PortA,SCL ; SCL=0.
;---------------------------------------------------------
; Задание числового значения режимного байта (для чтения).

9
;---------------------------------------------------------
movlw B'10100001' ; Запись в регистр Temp режимного байта
; (1010- код функциональности,
movwf Temp ; 000–адрес м/схемы, 1–режим чтения).
call BAIT_WR ; Условный переход в ПП передачи байта
; BAIT_WR.
;-----> Возврат по стеку из ПП BAIT_WR.

;***************************************************************************
; Подпрограмма приема байта (без названия. Можно как-нибудь назвать).
;***************************************************************************
movlw .8 ; Запись в счетчик битов количества
movwf Count ; битов в одном байте.

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


bsf TrisA,SDA ; Вывод SDA работает на вход.
bcf Status,RP0 ; Переход в 0-й банк.
;============================================================================
; Прием текущего бита.
;============================================================================
SNOVA_1 bcf Status,C ; Сброс в 0 флага переноса-заема (С).

bsf PortA,SCL ; SCL=1

btfsc PortA,SDA ; На линии SDA 0 или 1?


bsf Status,C ; Если 1, то С=1.
bcf PortA,SCL ; Если 0, то С=0 (см. выше), а SCL=0.

rlf Read,F ;Циклический сдвиг влево. Этим обеспечивается


; обработка битов байта, начиная с бита
; старшего разряда (№7...№0).
decfsz Count,F ; Декремент счетчика битов (Count-1=...).
goto SNOVA_1 ; Если результат не=0, то переход на
; чтение следующего бита.
;----------------------------------------------------------------------------
; Формирование сигнала АСК (вырабатывает "мастер").
;---------------------------------------------------------------------------
bcf PortA,SDA ; SDA=0

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


bcf TrisA,SDA ; Вывод SDA работает на выход.
bcf Status,RP0 ; Переход в 0-й банк.
;=========================================================================
; Вывод считанного байта в PortB (на индикацию).
;===========================================================================
movf Read,W ;Вывод считанного байта (через регистр W) на
movwf PortB ; индикацию (на светодиоды, подключенные
; к RB0...7).
;============================================================================
; Формирование стоп-условия.
;============================================================================
bsf PortA,SCL ; SCL=1.
bsf PortA,SDA ; SDA=1.
;============================================================================
; Завершение полного цикла программы.
;============================================================================
bsf PortA,1 ; "Загорание" светодиода окончания чтения.
clrwdt ; Сброс WDT.
goto $-1 ; Уход в "мертвое", "вечное кольцо" до
;выключения и последующего включения питания.
;****************************************************************************

10
; Подпрограмма передачи байта.
;****************************************************************************
BAIT_WR movlw .8 ; Запись в счетчик битов количества
movwf Count ; битов в одном байте.
;============================================================================
; Передача текущего бита
;============================================================================
SNOVA rlf Temp,F ;Циклический сдвиг влево. Этим обеспечивается
; обработка битов байта, начиная с бита
; старшего разряда (№7...№0).
bcf PortA,SDA ; SDA=0.

btfsc Status,C ; Что "ушло" в бит С?


bsf PortA,SDA ; Если в бите С 1, то SDA=1.
bsf PortA,SCL ; SCL=1. (Если в бите С 0, то предыдущая
; команда не исполняется. Вместо нее –
; "виртуальный" NOP).
bcf PortA,SCL ; SCL=0.
decfsz Count,F ; Декремент счетчика битов (Count-1=...).
goto SNOVA ; Если результат не=0, то переход на
; обработку следующего бита.
;****************************************************************************
;Группа команд формирования импульса 9-го такта и анализа состояний флага
;АСК.
;****************************************************************************
; Начало формирования импульса 9-го такта.
;----------------------------------------------------------------------------
bsf PortA,SCL ; Формируется строб (перепад от 0 к 1)
; импульса 9-го такта.
;----------------------------------------------------------------------------
; Подготовка к анализу состояний флага АСК (перестройка направления работы
; вывода RA3).
;----------------------------------------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
bsf TrisA,SDA ; Вывод SDA работает на вход.
bcf Status,RP0 ; Переход в 0-й банк.
;============================================================================
; Анализ состояний флага АСК ("плавающая" задержка).
;============================================================================
ACK btfsc PortA,SDA ; На линии SDA 0 или 1 ?
goto ACK ; Если 1, то снова анализ (задержка до
; появления 0).
;----------------------------------------------------------------------------
; Конец формирования импульса 9-го такта.
;----------------------------------------------------------------------------
bcf PortA,SCL ; Если 0, то формируется спад импульса
; 9-го такта.
;----------------------------------------------------------------------------
; Обратная перестройка направления работы вывода RA3.
;----------------------------------------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
bcf TrisA,SDA ; Вывод SDA работает на выход.
bcf Status,RP0 ; Переход в 0-й банк.

return ;Возврат по стеку в "администраторскую" ПП.


;****************************************************************************
end ; Конец программы.

Работа программы Read_1.asm.

По сравнению с ранее рассмотренными программами, в текст программы Read_1.asm


внесены коррективы в части касающейся портов.
Весь порт В задействован под индикацию считанного байта, а все остальное

11
"переброшено" на выводы порта А (см. рис. 1).
Соответственно, в подготовительных операциях, от выводов порта В отключены
подтягивающие резисторы.
Их можно и включить. От этого "не жарко и не холодно", так как все выводы порта
В работают только "на выход".
Все остальные подготовительные операции аналогичны ранее рассмотренным
(при "разборках" с записью), только с учетом задействования порта А.
Перед входом в ПП ожидания нажатия кнопки, все светодиоды, подключенные к
выводам порта В, принудительно гасятся (clrf PortB).
"Механизм" обработки "технологических" байтов, вплоть до обработки младшего
байта адреса (включительно) такой же, как и "механизм" программы Write_3.asm.
А вот далее пошла специфика.
Чтобы 24С64А "восприняла" 2-й режимный байт именно как режимный байт, нужно
сформировать старт-условие.
Но для того чтобы сформировать старт-условие, сначала нужно сформировать
стоп-условие.
Это Вы и видите: сначала формируется стоп-условие, а после окончания его
формирования, формируется старт-условие (стоп-старт).
Далее, 24С64А будет "ждать" режимный байт, который и формируется точно таким
же способом, как и 1-й режимный байт, но с одним отличием: в бите №0
выставляется 1 (R/W=1 - режим чтения).
ПП приема байта во многом похожа на ПП передачи байта (в программе
Read_1.asm есть и то, и другое, можно сравнить), но принципиальные отличия,
естественно, есть.
ПП приема байта начинается с задания количества "колец" полного цикла этой ПП.
Это мы уже проходили.
Далее, "мастер" перестраивает свой вывод, подключенный к линии SDA, с работы
"на выход" на работу "на вход".
И это понятно, так как речь идет о чтении байта данных.
Далее, начинается считывание бита №7.
В соответствии с принципом побитного чтения байта (см. рис. 2), в бите С регистра
Status выставляется 0 (bcf Status,C), после чего формируется передний строб
тактового импульса №1 (bsf PortA,SCL).
По этому стробу, происходит сдвиг влево байта данных, записанного в сдвиговом
регистре 24С64А, и в линию SDA, со стороны 24С64А, выдается бит №7,
считываемого из памяти 24С64А, байта.
Далее, в соответствии с рис. 2, "мастер" производит анализ состояния линии SDA
(btfsc PortA,SDA) и "уходит" в один из двух сценариев.
Если на линии SDA обнаружена 1, то в бит С записывается 1 (bsf Status,C), после
чего завершается формирование тактового импульса №1 (bcf PortA,SCL).
Если на линии SDA обнаружен 0, то состояние бита С не меняется (С=0), вместо
команды bsf Status,C исполняется "виртуальный NOP", после чего завершается
формирование тактового импульса №1 (bcf PortA,SCL).
Теперь можно "двигать" влево содержимое регистра Read, что и происходит (rlf
Read,F).
После этого сдвига, содержимое бита С (а это и есть бит №7 считываемого с линии
SDA байта данных) перепишется в бит №0 регистра Read, а в бит С запишется бит
№7 регистра Read.
Последнее не существенно, так как, в начале считывания следующего бита
данных, бит С "принудительно" устанавливается в 0 (bcf Status,C).
Далее происходит декремент содержимого счетчика битов (decfsz Count,F), с
дальнейшим переходом на следующий цикл чтения бита с линии SDA (goto
SNOVA_1), и все повторяется снова, только для бита данных №6.
Вся эта "свистопляска" будет продолжаться до тех пор, пока с линии SDA не будет
считан бит №0.
В результате последующего декремента содержимого счетчика битов, в нем будет
обнаружен 0, что означает окончание считывания, с линии SDA, текущего байта

12
данных.
Рабочая точка программы, "отмотав" 8 "колец" ("витков") в подпрограмме приема
байта, выходит из нее.
Что далее?
А далее, "мастер" должен выдать в линию SDA нулевой уровень сигнала АСК (bcf
PortA,SDA).
Есть такая команда, но толка от нее пока нет, так как вывод SDA "мастера"
работает "на вход".
Следовательно, для того чтобы был этот толк, нужно перестроить направление
работы этого вывода с работы "на вход" на работу "на выход", что и имеет место
быть.
Примечание: команду bcf PortA,SDA лучше поставить до этой перестройки, а не
после нее, так как, в последнем случае, на линии SDA, при условии, что бит №0
считанного байта =0, будет сформирован совершенно не нужный, "паразитный"
импульс, наличие которого обусловлено тем, что бит №0 2-го режимного байта был
равен единице (R/W=1), и эта единица сохраняется в защелке, "привязанной" к
линии SDA, в течение всего времени считывания с линии SDA первого байта
данных.
После того, как "мастер" установил на линии SDA нулевой уровень сигнала АСК,
можно либо продолжить чтение следующего байта данных (о потоковом чтении
будет рассказано в следующем подразделе), либо "сотворить" что-нибудь со
считанным байтом, "лежащим" в регистре Read.
В данном случае, этот байт выводится на индикацию в линейку светодиодов,
подключенных к выводам порта В (movf Read,W и movwf PortB).
Все, "миссия" закончена.
Теперь можно "подпалить" светодиод окончания чтения (bsf PortA,1),
сформировать стоп-условие и уйти в "мертвое, вечное кольцо".
Ниже Вы видите детальную "разрисовку" того, что сказано.
То, что имеет место быть до бита R/W 2-го режимного байта, я "разрисовывать" не
стал, так как не хочу повторяться. "За кадром" остался только стоп-старт,
предшествующий началу формирования 2-го режимного байта, но он настолько
прост и незамысловат, что Вы без труда с этим разберетесь самостоятельно (см.
текст программы).

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

14