11.09. Некоторые дополнительные соображения
В процессе разработки прибора мы, сталкиваясь с различными возможными вариантами элементов аппаратного или программного обеспечения, должны были принять какое-то решение. Во многих случаях выбор варианта не был однозначным. Чаще всего, правда, "наилучшее решение" представлялось очевидным, но иногда альтернативный вариант был ничем не хуже; в таких случаях, как правило, мы старались выбрать решение, отличающееся максимальной простотой или иллюстрирующее наиболее употребительную методику (избегая хитроумных приемов, основанных на тонких особенностях аппаратуры), а также приводящее к упрощению программы. В реальной жизни (в противоположность книгам) вполне естественно использовать особенности аппаратуры; естественно также писать сложные программы. Рассмотрим некоторые элементы нашего проекта, допускающие альтернативные решения.
Чтение состояния органов управления с помощью таблицы. В нашей программе предусмотрен программный блок, выполняющий чтение и анализ различных битов с управляющей панели, а также соответствующую установку программных параметров. Это распространенный и удобный способ настройки программы. Имеется, однако, и другое, не менее удобное решение, и при этом допускающее простую модификацию. Организуется короткий цикл опроса битов управляющей панели, при этом адреса портов, расположение битов и соответствующие им настраиваемые переменные программы описываются с помощью таблиц. Поскольку такая методика требует особых разъяснений и в нашем случае, возможно, привела бы к усложнению программы, мы выбрали более простое решение: включение в программу однозначных строк чтения органов управления. Однако в приложениях с большим числом параметров, особенно, если вам может понадобиться изменять назначение или значения входных битов, удобнее использовать табличную методику.
Одновибратор подсветки. Мы использовали для подсветки луча дисплея "программный импульс" параллельного порта, потому что считали необходимым продемонстрировать эту полезную методику. При этом мы особо подчеркнули, что при включенных прерываниях нельзя получить надежный программный импульс. Другая возможность заключается в использовании (вместо бита параллельного порта) аппаратного импульсного генератора, например, микросхемы одновибратора. Такого рода микросхемы, вообще говоря, применять рискованно, однако для нашего случая прекрасно подходит микросхема 8536 СIO фирмы Zilog, содержащая встроенный одновибратор, с которого можно снять выходной сигнал. Этот одновибратор фактически образуется с помощью одного из трех встроенных таймеров, что позволяет программно управлять длиной его импульса (вы даже можете соединить два таймера последовательно и получить более длинный импульс). В нашем приборе используются не все таймеры; и описываемая методика оказывается весьма удобной. С ее помощью сокращается программа обработчика прерываний и возникает возможность оптимальной настройки длительности Z-импульса подсветки.
"Запоминание 1" для кнопки СТОП. При чтении состояния кнопки СТОП мы воспользовались полезным качеством микросхемы 8536, именно, наличием встроенного триггера "запоминания 1". При инициализации микросхемы 8536 можно придать свойство запоминания 1 любому биту входного порта; этот бит затем устанавливается при кратковременном нажатии на кнопку и удерживает это состояние до программного сброса при выполнении цикла записи в этот бит порта. Для нашего случая это очень удобно, потому что нам надо фиксировать нажатие кнопки СТОП только в конце развертки. Длительность развертки может составлять много секунд, и встроенная память позволяет избежать периодического считывания состояния кнопки СТОП; поэтому в нашей программе состояние бита СТОП анализируется только в конце развертки (см. рис. 11.21).
Большинство микросхем параллельных портов не содержит входной памяти, и вам может понадобиться запланировать в программе действия, которых нам удалось избежать. Сделать надо следующее. Прежде всего определите внутренний программный флаг, который можно назвать stop__at__end (останов в конце); в программе это определение следует поставить после stop__flag. Не забудьте сбросить этот флаг перед входом в цикл приема данных; удобно это сделать после считывания состояния управляющей панели. Далее добавьте в цикл update__loop несколько команд, чтобы периодически проверять вход stop__bit и, если кнопка СТОП нажата, установить флаг stop__at__end. Наконец, измените строки обработчика прерывания так, чтобы в конце каждой развертки проверялась не кнопка СТОП, а этот программный флаг.
Упражнение 11.17. Впишите карандашом предлагаемые изменения в листинг программы.
Обработчик прерывания: несколько точек входа или флаги? В программе обработчика прерываний мы предусмотрели несколько входных точек, по одной на каждое возможное состояние прибора (бездействие, ожидание сигнала запуска, начало развертки, накопление данных). Поскольку обработчик прерываний не является вызываемой подпрограммой, и вход в него осуществляется по вектору, программа при каждом изменении состояния изменяет и точку входа, загружая ее адрес в ячейки вектора (в начале памяти). Очевидно, что вместо этого можно иметь в обработчике одну точку входа, а для передачи управления на требуемый программный блок предусмотреть строки анализа флага. В этом случае программа передает обработчику информацию о требуемых действиях путем изменения состояния программного флага (вместо того, чтобы настраивать вектор прерываний). Такой метод отличается простотой, однако программа выполняется медленнее, поскольку при каждом входе в обработчик осуществляются проверки и переходы. Разница, впрочем, не так уж велика, и вы вполне можете изменять функцию драйвера с помощью флагов, если этот способ вам нравится больше.
Последовательный порт: дамп данных и управление ведомым. Как уже отмечалось в разд. 11.06, наш усреднитель сигналов не обладает важным свойством пересылки усредненных данных на другой компьютер. Программа выполнения этой операции не сложна, однако громоздка, так как должна включать процедуры инициализации (как для микросхемы 8536), упаковки данных, а также квитирования, чтобы приемник данных мог инициировать передачу данных и подтверждать их прием.
Если предположить, что связь с другим компьютером осуществляется через последовательный порт, имеет смысл использовать этот порт и в качестве альтернативной управляющей панели, чтобы внешний компьютер мог настраивать параметры и запускать накопление данных. Для этого специальная программа анализа должна "отлавливать" определенные байты, которые компьютер посылает в усреднитель, чтобы получить управление. С помощью дополнительных байтов определяются сами параметры (ширина канала, число разверток и др.), причем диапазоны изменения параметров не ограничиваются количеством фиксированных положений переключателей, как это имеет место в нашем приборе с управляющей панелью. Разумеется, надо предусмотреть программное обеспечение, переключающее прибор на управление от управляющей панели, если из компьютера не поступает запрос на управление. Это позволит нам и на земле погулять, и в рай попасть: простота настройки с помощью ручек на передней панели будет сочетаться с гибкостью компьютерного управления.
Чтение органов управления с плавной регулировкой. В описываемом микропроцессорном приборе нам удалось избежать сложностей, присущих органам управления с плавной регулировкой, так как мы использовали более простые устройства - переключатели, каждый из которых связан с одним из битов параллельного порта. Нежелание разработчиков усложнять себе жизнь привело к появлению неоправданной тенденции полного отказа от органов плавной регулировки, которые заменяются (например, в генераторе с микропроцессорным управлением) парами кнопок "вверх" и "вниз". Возможно, вы, как и мы, испытываете ностальгическое желание плавно покрутить ручки. Наш усреднитель сильно выиграл бы при наличии ручки, позволяющей выбрать определенный канал и вывести на экран его адрес и число отсчетов в нем.
Простейший способ организации плавного управления в микропроцессорном приборе заключается в использовании АЦП, преобразующего напряжение от переменного резистора, укрепленного на передней панели и подключенного между напряжением +5 вольт (или другим, более удобным) и землей. В продаже имеются небольшие дешевые микросхемы 8-битных АЦП, скомпонованных с 8-битными мультиплексорами и дискретизаторами с памятью; обычно у вас остается несколько свободных входов, которые можно использовать для чтения нескольких органов управления на передней панели. Можно даже с помощью АЦП прочитать состояние "-позиционного поворотного переключателя - достаточно подключить его выводы к цепочке из n - 1 резистора равной величины и подать на АЦП выходное напряжение!
Если вам нужно иметь лучшее разрешение, чем обеспечивает простой 8-битный АЦП, подумайте о многооборотном кодировщике. Он укрепляется на передней панели и имеет размер не больше обычного переменного резистора. Кодировщик содержит пару оптических прерывателей, формирующих, по мере вращения ручки, импульсы, сдвинутые по фазе на 90°. Сдвиг импульсов по фазе дает возможность определить, в каком направлении поворачивается ручка (см. рис. 8.97). В отличие от обычного переменного резистора, многооборотный кодировщик не имеет фиксатора, что и позволяет поворачивать его ось на много оборотов. Типичный узел такого рода серии Bourns EN формирует 256 импульсов на один оборот.