Закрыть окно         Список других документов ПЭВМ "Агат"

.сс

.цв

.шп24

РУКОВОДСТВО ДЛЯ ПРОГРАММИСТА

.шп0

.ов

В руководстве для программиста мы расскажем о внутренней архитектуре модуля "Nippel Clock Card", способах доступа и управления им, опишем все соглашения нормального функционирования контроллера, а также приведем рекомендации и примеры программного обеспечения и поддержки некоторых функций модуля. Кроме того, мы приведем текст - пример драйвера для использования в программах на языке ассемблера и комментарии к программе "PrimerClk", демонстрирующей способы использования часов в программах на BASIC. Вы также найдете на диске поставки исходный текст программы "TestClk".

.дс

.шп24

1. Внутренняя структура модуля.

.шп0

В качестве основы модуля "Nippel Clock Card" использована микросхема контроллера часов MC146818 фирмы Motorola, Inc., широко используемая в зарубежных разработках (например, вы можете встретить ее в контроллере часов IBM AT), либо ее аналог КР512ВИ1, производства минского НПО "Интеграл".

С точки зрения программы, микросхема представляет из себя 64 ячейки памяти, в большинство из которых можно производить как запись, так и чтение информации, кроме того, модуль вырабатывает прерывания IRQ (по вектору ¤FFFE-¤FFFF). Первые 14 ячеек (¤00-¤0D) используются непосредственно для работы часов, остальные 50 (¤0E-¤3F) могут свободно использоваться как энергонезависимая память машины, для хранения разных признаков и режимов (эта свобода не является полной, т.к. по принятым соглашениям большинство ячеек зарезервировано).

Для обращения к ячейкам из программ выделены два адреса в области Device Select, т.е. области ¤C0X0-¤C0XF. Чтобы согласовать возможное размещение на одной плате нескольких полезных устройств, таких как контроллеры принтера, мыши и предлагаемых часов, были выбраны непересекающиеся адреса обращения ко всем этим устройствам. Как известно, контроллер принтера использует адреса ¤C0X0-¤C0X3, часам же зарезервировали адреса ¤C0X6 для размещения адреса ячейки, ¤C0X7 для чтения/записи данных.

В таблице 1 представлено распределение системных ячеек часов и указано их назначение:

.дв

.ао0

.гр

Таблица 1
╔═════════╦═══════════════════════════════╗
|  Адрес  |  Данные                       |
╠═════════╬═══════════════════════════════╣
|   ¤00   |  Секунды                      |
|   ¤01   |  Секунды ("будильник")        |
|   ¤02   |  Минуты                       |
|   ¤03   |  Минуты ("будильник")         |
|   ¤04   |  Часы                         |
|   ¤05   |  Часы ("будильник")           |
|   ¤06   |  День недели                  |
|   ¤07   |  Число                        |
|   ¤08   |  Месяц                        |
|   ¤09   |  Год                          |
╠═════════╬═══════════════════════════════╣
|   ¤0A   |  Регистр A                    |
|   ¤0B   |  Регистр B                    |
|   ¤0C   |  Регистр C                    |
|   ¤0D   |  Регистр D                    |
╚═════════╩═══════════════════════════════╝

.тт

.нф

.ао1

Четыре ячейки ¤0A-¤0D, так называемые регистры A-D, предназначены для управления и контроля работы микросхемы. Каждый бит, либо группа битов этих регистров, имеет свое уникальное назначение. В таблице 2 приведено условное обозначение этих битов:

.дв

.ао0

.гр

Таблица 2
╔═════════╦═══════╦═════╦═════╦═════╦══════╦═════╦═══════╦══════╗
|  Адрес  |   D7  |  D6 |  D5 |  D4 |  D3  |  D2 |   D1  |  D0  |
╠═════════╬═══════╬═════╬═════╬═════╬══════╬═════╬═══════╬══════╣
|   ¤0A   |  UIP1 | DV2 | DV1 | DV0 | RS3  | RS2 |  RS1  | RS0  |
╠═════════╬═══════╬═════╬═════╬═════╬══════╬═════╬═══════╬══════╣
|   ¤0B   |  SET  | PIE | AIE | UIE | SQWE |  DM | 24/12 | DSE  |
╠═════════╬═══════╬═════╬═════╬═════╬══════╬═════╬═══════╬══════╣
|   ¤0C   | IRQF1 | PF1 | AF1 | UF1 |  01  |  01 |   01  |  01  |
╠═════════╬═══════╬═════╬═════╬═════╬══════╬═════╬═══════╬══════╣
|   ¤0D   |  VRT1 |  01 |  01 |  01 |  01  |  01 |   01  |  01  |
╚═════════╩═══════╩═════╩═════╩═════╩══════╩═════╩═══════╩══════╝

.тт

Примечание. Из разрядов, помеченных1, процессор может только считывать информацию.

.нф

.ао1

.км .сс Пришлось поставить, т.к. не могу никак заставить

.км следующую строку не оставаться в конце страницы.

.км

.сс

Рассмотрим назначение каждого разряда в отдельности:

.дс

Регистр А:

UIP - Единица в этом разряде означает, что происходит или начнется менее чем через 244 мкс цикл обновления информации о времени. Длительность цикла обновления 1984 мкс при тактовой частоте 32768 Гц или 248 мкс при других тактовых частотах. UIP можно считывать, на него не действуют сигнал СБРОС. Записав единицу в разряд SET регистра B, можно запретить обновление и тем самым сбросить UIP.

DV0-DV2 - Устанавливают режим работы внутреннего делителя частоты в соответствие с используемой тактовой частотой (см. таблицу 3). В "Nippel Clock Card" используется тактовая частота 32768 Гц.

RS0-RS3 - Устанавливают частоту циклических прерываний (таблица 4).

.дв
.ао0
.гр
Таблица 3
╔═════════╦═════════╦═════════╦══════════════════════════╗
|   DV2   |   DV1   |   DV0   |   Тактовая частота, Гц   |
╠═════════╬═════════╬═════════╬══════════════════════════╣
|    0    |    0    |    0    |   4 194 304              |
|    0    |    0    |    1    |   1 048 576              |
|    0    |    1    |    0    |      32 768              |
|    1    |    1    |    1    |   Сброс делителя         |
╚═════════╩═════════╩═════════╩══════════════════════════╝
.тт
.нф
.ао0

.дв
.ао0
.гр
Таблица 4
╔═════════════╦════════════════════════════════════════════════╗
|             |           Тактовая частота, Гц                 |
|             ╠═════════════════════════╦══════════════════════╣
|  RS3 - RS0  | 4 194 304 или 1 048 576 |       32 768         |
|             ╠═════════════════════════╬══════════════════════╣
|             |   Частота прерываний    |  Частота прерываний  |
╠═════════════╬═════════════════════════╬══════════════════════╣
|     ¤0      |           ════          |          ════        |
|     ¤1      |          32 768         |           256        |
|     ¤2      |          16 384         |           128        |
|     ¤3      |           8 192         |         8 192        |
|     ¤4      |           4 096         |         4 096        |
|     ¤5      |           2 048         |         2 048        |
|     ¤6      |           1 024         |         1 024        |
|     ¤7      |             512         |           512        |
|     ¤8      |             256         |           256        |
|     ¤9      |             128         |           128        |
|     ¤A      |              64         |            64        |
|     ¤B      |              32         |            32        |
|     ¤C      |              16         |            16        |
|     ¤D      |               8         |             8        |
|     ¤E      |               4         |             4        |
|     ¤F      |               2         |             2        |
╚═════════════╩═════════════════════════╩══════════════════════╝
.тт

.нф

.ао1

.дс

Регистр B:

SET - Если в этом разряде записан ноль, то каждую секунду выполняется цикл обновления информации о текущем времени и сравнении текущего времени с заданным временем срабатывания "будильника". Единица в этом разряде запрещает обновление, давая возможность записать в регистры времени, календаря и будильника новые значения.

PIE - Единица в этом разряде разрешает прерывания с периодом, задаваемым разрядами RS3-RS0 регистра A. Сбрасывается при подаче сигнала СБРОС.

AIE - Единица в этом разряде разрешает прерывания от будильника. Сбрасывается при подаче сигнала СБРОС.

UIE - Единица в этом разряде разрешает прерывания по окончании цикла обновления. Сбрасывается при подаче сигнала СБРОС.

SQWE - Разрешение выдачи сигнала на выход SQW. Сбрасывается при подаче сигнала СБРОС. В "Nippel Clock Card" не используется.

DM - Единица в этом разряде означает, что данные о времени и дате представлены в двоичном виде, ноль - в двоично-десятичном. Значение этого разряда нельзя изменять без повторной записи начальных значений в ячейки времени и календаря.

24/12 - Устанавливает 24-часовой (1) или 12-часовой (0) режим счета времени. В 12-часовом режиме время после полудня (PM) отмечается единицей в старшем разряде регистра часов (адрес ¤04).

DSE - Разрешение автоматического перехода на летнее время, по правилам принятым в США. Когда в этом разряде записана единица, то в последнее воскресенье апреля после 01 чac 59 мин 59 сeк автоматически устанавливается 03 чac 00 мин 00 сeк, а в последнее воскресенье октября после 01 чac 59 мин 59 сeк следует 01 чac 00 мин 00 сeк.

.дс

Регистр C

IRQF - Флаг запроса прерываний. Устанавливается в единицу, когда сработало хотя бы одно из разрешенных в данный момент прерываний. Другими словами, это означает, что прерывание произошло именно из "Nippel Clock Card". Флаг сбрасывается после чтения регистра C или сигналом СБРОС.

PF - Устанавливается в единицу сигналом от внутреннего делителя частоты, выбранным в соответствии с разрядами RS3-RS0 регистра A. Флаг сбрасывается после чтения регистра C или сигналом СБРОС.

AF - Устанавливается в единицу при совпадении текущего времени с временем, указанным в регистрах будильника. Флаг сбрасывается после чтения регистра C или сигналом СБРОС.

UF - Устанавливается в единицу после окончания цикла обновления (ежесекундно). Флаг сбрасывается после чтения регистра C или сигналом СБРОС.

.дс

Регистр D

VRT - В этом разряде устанавливается ноль при низком уровне на входе PS, входе сбоя питания. Единица устанавливается только считыванием регистра D. В "Nippel Clock Card" не используется.

.дс

.шп24

2. Основные вопросы программирования.

.шп0

Вы, наверное, уже поняли, что часы могут работать в нескольких разных режимах, поэтому для осуществления совместимости разных программ требуется соблюдать некоторые соглашения по представлению и обработке информации в часах.

Итак, в модуле "Nippel Clock Card" используется кварцевый генератор на 32768 Гц (биты DV2-DV0 должны иметь значение :010), данные о времени и дате представляются в двоичном виде (бит DM=1), интервал счета 24 часа (бит 24/12=1), автоматический переход на летнее время не используется (бит DSE=0).

Информация в счетчиках представлена просто двоичными числами. Секунды и минуты могут принимать значения от 0 до 59 (¤0-¤3B), часы от 0 до 23 (¤0-¤17), день недели от 1 до 7 (¤1-¤7), число от 1 до 28..31 (¤1-¤1C..¤1F), в зависимости от месяца и года, месяц от 1 до 12 (¤1-¤C), год от 0 до 99 (¤0-¤63). Если в одну из ячеек будильника записан код с двумя старшими разрядами равными 1 (¤C0-¤FF), эта ячейка переходит в безразличное состояние и не учитывается при сравнении с текущим временем.

Как уже было сказано выше, для доступа к ячейкам микросхемы MC146818 выделены два адреса - ¤C0X6 для установки адреса и ¤C0X7 для чтения/записи данных. Адреса управления формируются по стандартным правилам - т.е. первому разъему соответствуют адреса ¤C096, ¤C097, второму ¤C0A6, ¤C0A7, третьему ¤C0B6, ¤C0B7 и т.д. Адрес в ¤C0X6 нужно устанавливать перед каждым обращением к ¤C0X7, так как после чтения/записи он теряется. Так как у микросхемы MC146818 имеются только 64 ячейки памяти, два старших бита восьмиразрядного адреса ячейки просто игнорируются, поэтому, например, адреса ¤0E и ¤CE аналогичны.

Перед чтением информации о времени нужно проанализировать состояние бита UIP регистра A, и если он покажет, что сейчас идет обновление информации, то читать информацию нельзя, так как ее правильность не гарантируется (это правило не относится к регистрам A-D). Процедура чтения всей нужной информации должна уложиться в 244 мкс, потому что именно за это время до начала обновления бит UIP устанавливается в единицу.

Все изменения в ячейках текущего времени и даты нужно производить, предварительно остановив счет времени, для чего в бит SET регистра B нужно записать 1. Следует отметить, что остановка обновления информации не прерывает работы делителя частоты, отмеряющего секундный интервал. Это означает, что, во-первых, останавливать обновление нужно, дождавшись конца текущего цикла обновления, как при чтении информации, во-вторых, изменения в календаре не будут в этом случае нарушать правильность отсчета секунд, и, в-третьих, для исключения элемента случайности в отсчете первого интервала после коррекции секунд, нужно сбрасывать делитель записав в биты DV0-DV2 значения :111 и после снова :010.

Наиболее удобным способом считывания информации о текущем времени и дате является использование встроенного прерывания, происходящего ежесекундно, в конце каждого цикла обновления (естественно удобство обеспечивается только если логика работы программы не противоречит использованию прерываний). Это прерывание разрешается установкой бита UIE регистра B в единицу и стробируется установкой в единицу бита UF регистра C.

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

Так как во время обработки прерывания бит I процессора (маска прерывания) устанавливается в единицу, программу обработки прерывания уже ничто не прервет. Тем не менее, если в это время пpидeт cигнaл прерывания, он будет запомнен в соответствующем бите-признаке и прервет процессор непосредственно после выполнения команды RTI. Важно только соблюдать, чтобы время выполнения программы обработки прерывания не оказалось больше времени пepиoдa соответствующeгo прерывания, так как в этом случае программа зависнет. По той же причине регистр C должен быть прочитан хотя бы раз программой обработки прерывания. Если программа не совeршит чтения регистра C, то машина зависнет, так как не будут сброшены флаги, и, выполнив команду RTI, процессор сразу же опять прервется.

Например, в программе "TestClock" для реализации такого опасного прервания как 8192 Гц используется операция повторного чтения регистра C непосредственно перед командой RTI, чтобы предотвратить зависание, т.к. время периода этого прерывания (122 мкс) недостаточно для перевывода бегущей строки. Конечно, некоторые из запросов не будут обработаны, и реальная частота вызовов будет меньше 8192 Гц, но прерывания с такой частотой реализованы в этой программе исключительно для проверки всех режимов работы модуля, поэтому реальная частота не имеет значения. Более подробно с этим приемом и другими Вы сможете ознакомиться из исходного текста программы "TestClock".

.ст Описание часов 2

Закрыть окно         Список других документов ПЭВМ "Агат"