Занимательная электроника — страница 94 из 128

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

* * *

Если подробности внутреннего функционирования МП нас волнуют не очень (центральный узел — АЛУ — мы уже «изобретали» в главе 15, и этого достаточно, чтобы понимать, что именно происходит внутри процессорного ядра), то обмен с внешней средой нас как раз интересует во всех деталях. Для этого служат порты ввода/вывода (I/O-port, от Input/Output). В этом термине имеется некоторая неопределенность, т. к. те, кто программировал для ПК на ассемблере, помнят, что в ПК портами ввода/вывода (ПВВ) назывались регистры для управления всеми устройствами, кроме непосредственно процессорного ядра. В микроконтроллерах то же самое называют регистрами ввода/вывода (РВВ) — это регистры для доступа ко встроенным компонентам контроллера, внешним по отношению к вычислительному ядру. А это все узлы, которыми непосредственно управляет пользователь: от таймеров и последовательных портов до регистра флагов и управления прерываниями. Кроме ОЗУ, доступ к которому обеспечивается специальными командами, все остальное в контроллере управляется через РВВ, и путать с портами ввода/вывода их не следует.

ПВВ в МК служат для обмена с «окружающей средой» (управляются они, естественно, тоже внутренними регистрами ввода/вывода). На схеме рис. 18.2 показано 3 ПВВ: А, В и С, в реальных МК их может быть и больше, и меньше. Еще важнее число выводов этих портов, которое чаще всего совпадает с разрядностью процессора (но не всегда, как это было у 8086, который имел внутреннюю 16-разрядную структуру, а внешне выглядел 8-разрядным). Если мы заставим 8-разрядные порты «общаться», например, с внешней памятью, то на двух из них можно выставить 16-разрядный адрес, а на оставшемся — принимать данные. А как быть, если портов два или вообще один? (К примеру, в микроконтроллере ATtiny2313 портов формально два, но один усеченный, так что общее число линий составляет 15). Для того чтобы даже в такой ситуации это было возможно, все внешние порты в МП всегда двунаправленные. Скажем, если портов два, то можно сначала выставить адрес, а затем переключить порты на вход и принимать данные. Естественно, для этого порты должны позволять работу на общую шину — т. е. либо иметь третье состояние, либо выход с общим коллектором для объединения в «монтажное ИЛИ».

Варианты для обоих случаев организации выходной линии порта показаны на рис. 18.3, где приведены упрощенные схемы выходных линий микроконтроллеров семейства 8048 — когда-то широко использовавшегося предшественника популярного МК 8051 (например, 8048 был выбран в качестве контроллера клавиатуры в IBM PC). В современных МК построение портов несколько сложнее (в частности, вместо резистора там полевой транзистор), но для уяснения принципов работы это несущественно.



Рис. 18.3.Упрощенные схемы портов ввода/вывода МК 80481: а — портов 1 и 2, б — порта 0


По первому варианту (рис. 18.3, а) в МК 8048 построены порты 1 и 2. Когда в порт производится запись, то логический уровень поступает с прямого выхода защелки на статическом D-триггере на вход схемы «И», а с инверсного — на затвор транзистора VT2. Если этот уровень равен логическому нулю, то транзистор VT1 заперт, а VT2 открыт, на выходе также логический ноль. Если уровень равен логической единице, то на время действия импульса «Запись» транзистор VT1 открывается, а транзистор VT2 запирается (они одинаковой полярности). Если на выходе присутствует емкость (а она всегда имеется в виде распределенной емкости проводников и емкости входов других компонентов), то через открытый VT1 протекает достаточно большой ток заряда этой емкости, позволяющий сформировать хороший фронт перехода из 0 в 1. Как только импульс «Запись» заканчивается, оба транзистора отключаются, и логическая единица на выходе поддерживается резистором R1. Выходное сопротивление открытого транзистора VT1 примерно 5 кОм, а резистора — 50 кОм. Любое другое устройство, подключенное к этой шине, при работе на выход может лишь либо поддержать логическую единицу, включив свой подобный резистор параллельно R1, либо занять линию своим логическим нулем — это, как видите, и есть схема «монтажное ИЛИ». При работе на вход состояние линии просто считывается во время действия импульса «Запись» со входного буфера (элемент В на рис. 18.3, а).

Второй вариант (рис. 18.3, б), по которому устроен порт 0, есть обычный выходной каскад КМОП с третьим состоянием, т. е. такой порт может работать на выход, только полностью занимая линию, остальные подключенные к линии устройства при этом должны смиренно внимать монополисту, воспринимая сигналы. Это обычно не создает особых трудностей и схемотехнически даже предпочтительно ввиду симметрии выходных сигналов и высокого сопротивления для входных. Единственная сложность возникает при сопряжении такого порта с линией, работающей по первому варианту, т. к. при логической единице на выходе могут возникнуть электрические конфликты, если кто-то попытается выдать в линию логический ноль (ток от источника пойдет через два распахнутых транзистора).

Для обеспечения работы трехстабильного порта по схеме «монтажное ИЛИ» применяют хитрый прием: всю линию «подтягивают» к напряжению питания с помощью внешнего резистора (во многих МК существует встроенный отключаемый резистор, установленный аналогично R1 в схеме рис. 18.3, а), и нормальное состояние всех участвующих трехстабильных портов — работа на вход в третьем состоянии. В этом режиме на линии всегда будет логическая единица. На выход же линию переключают только, когда надо выдать логический ноль. В этом случае, даже при одновременной активности нескольких портов, конфликтов не возникнет.


Лечение амнезии

В 1965 году в Иллинойсском университете был запущен один из самых передовых компьютеров по тому времени — ILLIAC–IV. Он стал первым компьютером, в котором использовалась быстрая память на микросхемах, — каждый чип (производства Fairchild Semiconductor) имел емкость 256 битов, а всего было набрано 1 Мбайт. Стоимость этой памяти составила ощутимую часть от всей стоимости устройства, обошедшегося заказчику — NASA — в $31 млн. Через 10 лет один из первых персональных компьютеров Altair 8800 (1975 год), продававшийся в виде набора «сделай сам», при стоимости порядка $500 имел всего 256 байтов (именно байтов, а не килобайт) памяти. В том же году для распространения языка Basic for Altair Биллом Гейтсом и Полом Алленом была создана фирма, получившая первоначальное название Micro-Soft. Одна из самых серьезных проблем, которую им пришлось решать, — нехватка памяти, потому что созданный ими интерпретатор Basic требовал аж 4 Кбайт!

Проблема объемов памяти и ее дороговизна преследовала разработчиков достаточно долго — еще в конце 1990-х стоимость памяти для ПК можно было смело прикидывать из расчета 1 доллар/Мбайт, что при требовавшихся уже тогда для комфортной работы объемах ОЗУ порядка 128–256 Мбайт могло составлять значительную часть стоимости устройства. Сейчас 4 гигабайта памяти в настольном ПК или ноутбуке уже стали фактическим стандартом. Это привело, в частности, к кардинальным изменениям в самом подходе к программированию — если еще при программировании под DOS о компактности программ и экономии памяти в процессе работы нужно было специально заботиться, то теперь это практически не требуется.

Но в программировании для микроконтроллеров это все еще не так. Хотя гейтсовский интерпретатор Basic влезет в большинство современных однокристальных МК, но экономная программа легче отлаживается (а, значит, содержит меньше ошибок) и быстрее выполняется. Три-четыре потерянных на вызове процедуры такта могут стать причиной какой-нибудь трудновылавливаемой ошибки времени выполнения — например, если за это время произойдет вызов прерывания. Поэтому память в МК стоит экономить, даже если вы располагаете заведомо достаточным ее объемом. Этот призыв, конечно, пропадает впустую, когда мы сталкиваемся с программированием на языках высокого уровня, где от нас зависит гораздо меньше, чем от разработчиков компиляторов.

Далее мы рассмотрим основные разновидности памяти, используемые как в составе микроконтроллеров, так и во внешних узлах. И начнем с того, что попробуем сами сконструировать устройство долговременной памяти — ПЗУ (постоянное запоминающее устройство). Как мы увидим, любая память в принципе есть не что иное, как преобразователь кодов.


Изобретаем простейшую ROM

Всем известно сокращение ROM — Read-Only Memory — английское название постоянного запоминающего устройства, ПЗУ. На самом деле это название (память только для чтения) не очень точно характеризует суть дела, отечественное название есть более корректный термин, самое же правильное называть такую память энергонезависимой. Ведь ПЗУ отличается от других типов памяти не тем, что его можно только читать, а записывать нельзя (практически все современные устройства ROM имеют возможность записи), а тем, что информация в нем не пропадает при выключении питания.

Тем не менее, первыми разновидностями ПЗУ, изобретенными еще в 1956 году, были именно нестираемые кристаллы, которые носят наименование ОТР ROM —