Чтение онлайн

на главную - закладки

Жанры

Искусство схемотехники. Том 3 (Изд.4-е)
Шрифт:

Текст

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

Из текста программы также видно, как мы будем использовать регистры МП 68008. При каждом прерывании мы извлекаем данные из АЦП, добавляем их к текущему содержимому канала и проверяем, не дошли ли мы до конца канала или развертки. Можно было хранить содержимое указателей и счетчиков в памяти (так и пришлось бы поступать при использовании менее совершенного процессора типа 8086), но зарезервировав достаточное число регистров для нужд обработчика прерываний, мы существенно повышаем эффективность режима прерываний. Поэтому мы выделили регистры данных для текущего содержимого канала (D7), обратного счетчика периодов дескретизации (внутри канала) (D6) и обратного счетчика каналов внутри развертки (D5), смещения в массиве DISPLAY (D4), а также регистр для временных данных (D3). Далее, мы зарезервировали адресные регистры для трех массивов (NORM, А6; DATA, А5; DISPLAY, А4) и для наиболее используемых портов (ADC0, A3; СIO [параллельный порт], А2). Главная программа берет на себя обязательство не использовать эти регистры при включенных прерываниях.

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

MOVE.B ADC0, D0

где ADC0 представляет длинный абсолютный адрес (в нашем случае $80000), требует 28 тактов (3,5 мкс в нашем процессоре), в то время как команда

MOVE.B (A3), D0

использующая косвенную адресацию через A3, выполняется всего за 12 тактов. Эта разница обусловлена исключительно процессами на магистрали, где для пересылки каждого байта требуются (в МП 68008) 4 такта. В процессе выполнения первой команды ЦП извлекает из памяти двухбайтовый код операции, четырехбайтовое расширение (длинного) адреса и, наконец, запрошенный байт данных, т. е. всего 7 байт, на что расходуется 28 тактов. Вторая команда требует извлечения двухбайтового кода операции и запрошенного байта данных, т. е. всего 3 байт (12 тактов). Вообще системы с узкими шинами (вроде нашего МП 68008, у которого внутренняя 32-разрядная архитектура должна себя чувствовать как в смирительной рубашке, общаясь с внешним миром через 8-разрядную шину) особенно неэффективны в условиях интенсивных передач данных.

Наконец, началась программа! Первые 8 байт ПЗУ хранят важнейший стартовый вектор: указатель стека

и входную точку программы. Входная точка находится в «истинном» ПЗУ (по адресу $40008), поэтому мы можем немедленно очистить бит BOOT, что приводит к замещению временного образа ПЗУ, используемого при начальной загрузке, оперативной памятью. Теперь мы можем загружать векторы прерываний в начало ОЗУ, в конкретные ячейки, определяемые архитектурой МП 68008 (вся область векторов приведена в табл. 11.5): $68 (INT2), $74 (INT5) и $7С (NMI = INT7). Мы использовали только INT5 (от 100 мкс — таймера в микросхеме параллельного порта); в этот вектор мы загружаем адрес нашего обработчика прерываний. В зависимости от конкретного состояния прибора (ожидание пуска или внешнего сигнала запуска, начало новой развертки, процесс развертки) обработчик прерываний должен выполнять различные функции; поэтому мы написали один грандиозный обработчик со многими точками входа, соответствующими его функциям. На данном этапе мы еще не готовы принимать данные, поэтому в вектор INT5 мы загружаем входную точку idle__int (прерывание простоя). Очень полезно загрузить на всякий случай все неиспользуемые векторы прерываний адресом bad__int (ложное прерывание) (вдруг произойдет деление на нуль, ложное прерывание и т. д.); мы загружаем в них адрес программы, которая зажигает ЭЛД определенным образом (далее будет видно, каким именно).

Теперь наступает утомительный, но существенный этап инициализации портов. БИС периферийных устройств, как, например, 8536, обладают изумительной гибкостью, но за нее приходится платить тщательным планированием. Вы должны продумать, какие управляющие байты следует послать, в какие регистры и в каком порядке, чтобы получить требуемый результат. Для простых параллельных портов в процессе планирования следует выбрать направление, полярность, режим и прерывания, а для таймеров — основание счета, каскадирование, режим запуска, прерывания и проч. В программе 11.3 приведен полный текст инициализации параллельного порта/таймера. Разрешаются параллельные порты А, В и С, причем биты 4–6 порта В назначаются выходными, а остальные - входными (см. рис. 11.15). Таймер-0 настраивается на деление его тактовой частоты 4 МГц на 400 и на непрерывный перезапуск с генерацией прерывания (по INT5) каждые 100 мкс. Заметьте, что все установочные входы мы сделали инверсными, поэтому при замыкании контакта (на который изначально подано +5 В) на землю с него считывается 1, а не 0. На входе, к которому подключена кнопка СТОП, мы использовали опцию «запоминания 1», так что мгновенное нажатие фиксируется, а отрабатывается оно только в конце развертки.

Наконец, мы очищаем массивы в ОЗУ (отметьте использование подпрограммы), инициализируем регистры, разрешаем прерывания и переходим на выполнение «главного» цикла.

Главная программа: главный цикл. Завершив инициализацию, мы входим в бесконечный главный цикл main__loop. Фактически он состоит из двух циклов: цикла ожидания нажатия кнопки ПУСК и цикла непрерывного обновления памяти изображения, на фоне которого осуществляется сбор данных в режиме прерываний. Программа обработки прерываний, завершив последнюю развертку, устанавливает программный «флаг останова» stop__flag, который непрерывно проверяется вторым главным циклом. Обнаружив установленный флаг, главная программа возвращается в первый цикл ожидания нового пуска. Давайте сопоставим структурную схему и программные строки.

Главный цикл (рис. 11.19) начинается с установки на ЭЛД состояния «ожидание». Затем программа ждет нажатия кнопки ПУСК, т. е. ее перехода из разомкнутого в замкнутое состояние. Это сложнее, чем кажется, потому что кнопка не содержит цепей подавления дребезга, в результате чего вы имеете несколько десятков близко расположенных перепадов между уровнями «замкнуто» и «разомкнуто», возникающих на протяжении, возможно, 25 мс. Этого времени может хватить на завершение самого короткого цикла измерений (если вы выбрали 1 развертку и интервал дискретизации 100 мкс), после чего измерения будут ошибочно продолжены, поскольку контакт кнопки все еще колеблется между состояниями «разомкнуто» и «замкнуто». Поэтому мы написали простенькую программу подавления дребезга, которая фиксирует, что кнопка была непрерывно разомкнута в течение приблизительно 50 мс (тем временем многократно выполняется подпрограмма обновления update), а затем переходит в состояние «замкнуто». Наконец мы получили приказ на выступление!

Программа сбрасывает выходной сигнал КОНЕЦ, считывает состояние управляющей панели и использует соответствующим образом полученные значения (устанавливая программные флаги типа auto__loop и параметры вроде dwell__per__bin и num__sweeps). Обратите внимание на использование таблицы decode__tbl (и косвенной адресации с индексацией) для получения значений, соответствующих положениям переключателей.

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

Поделиться:
Популярные книги

На границе империй. Том 7

INDIGO
7. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
6.75
рейтинг книги
На границе империй. Том 7

Темный Лекарь 11

Токсик Саша
11. Темный Лекарь
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Темный Лекарь 11

В семье не без подвоха

Жукова Юлия Борисовна
3. Замуж с осложнениями
Фантастика:
социально-философская фантастика
космическая фантастика
юмористическое фэнтези
9.36
рейтинг книги
В семье не без подвоха

Бастард Императора. Том 3

Орлов Андрей Юрьевич
3. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 3

Честное пионерское! Часть 3

Федин Андрей Анатольевич
3. Честное пионерское!
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Честное пионерское! Часть 3

Бестужев. Служба Государевой Безопасности. Книга четвертая

Измайлов Сергей
4. Граф Бестужев
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга четвертая

Кодекс Охотника. Книга XIX

Винокуров Юрий
19. Кодекс Охотника
Фантастика:
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XIX

Титан империи 8

Артемов Александр Александрович
8. Титан Империи
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Титан империи 8

Имперский Курьер. Том 2

Бо Вова
2. Запечатанный мир
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Имперский Курьер. Том 2

"Сломанная подкова" Таверна у трёх дорог

Скор Элен
1. Попаданка в деле
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Сломанная подкова Таверна у трёх дорог

Законы Рода. Том 10

Андрей Мельник
10. Граф Берестьев
Фантастика:
юмористическая фантастика
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 10

Род Корневых будет жить!

Кун Антон
1. Тайны рода
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Род Корневых будет жить!

Невеста клана

Шах Ольга
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Невеста клана

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12