Юрий Ревич - Занимательная электроника
Рис. 19.1. Окно типового состояния конфигурационных ячеек в нормальном режиме работы ATmega8535
В этом окне сейчас приведено безопасное рабочее состояние конфигурационных ячеек для ATmega8535, причем выпуклая кнопка означает единичное состояние ячейки, а нажатая — нулевое (и не путайтесь с этим самым «запрограммированным» состоянием!). Для разных моделей набор fuse битов различный, но означают они одно и то же, потому мы рассмотрим типовое их состояние на этом примере.
Перед первым программированием нового кристалла просто один раз установите эти ячейки в нужное состояние, дальше их уже менять не потребуется.
Самые необходимые пункты тут такие. По умолчанию любая микросхема семейств Mega или Tiny запрограммирована на работу от внутренней RC-цепочки, за что разработчикам большое спасибо, иначе было бы невозможным первичное программирование по SPI — только через параллельный программатор. Для работы с обычным «кварцем», присоединенным по типовой схеме, как мы говорили в главе 18, требуется установить все ячейки CKSELO-3 в единицы (что согласно логике разработчиков означает незапрограммированное их состояние). Заметим, что это и ведет к критической ошибке — решив при поверхностном чтении написанного по-английски руководства, что установка всех единиц означает запрограммировать все ячейки, пользователь смело устанавливает их на самом деле в нули, отчего микросхема переходит в состояние работы от внешнего генератора, и разбудить ее через SPI-интерфейс уже невозможно. Легче всего в этом случае переустановить fuse биты с помощью параллельного программатора либо, за неимением такового, попробовать-таки подключить внешний генератор, как описано в руководстве.
Это самая крупная ошибка, которую можно допустить, но есть и другие менее распространенные. Ячейка SPIEN разрешает/запрещает последовательное программирование по SPI и должна оставаться в нулевом состоянии, иначе МК не «разбудишь» никак, только опять же с помощью параллельного программатора (говорят, правда, через SPI ее и отключить невозможно). Ячейка S8535C (в других моделях она будет иметь другое название или вовсе отсутствовать) — очень важна и определяет режим совместимости с семейством Classic (в данном случае с AT90S8535).
Если ее установить в нулевое состояние, то МК семейства Mega перейдет в режим совместимости. В популярном ATtiny2313, потомке «классического» AT90S2313, такого бита совместимости нет (но, как мы увидим, это не очень существенно). При использовании режима совместимости следует учесть, что состояния МК нельзя перемешивать: если fuse бит совместимости запрограммирован (равен 0), то программа компилируется полностью, как для семейства Classic (в том числе с использованием соответствующего inc-файла, см. далее), иначе она может не заработать.
Еще одна важная ячейка — EESAVE, которая на рис. 19.1 установлена в единицу (режим по умолчанию), но ее целесообразно перевести в нулевое состояние — тогда при программировании памяти программ не будет стираться содержимое EEPROM.
Ячейки SUT определяют длительность задержки сброса, и в большинстве случаев принципиального значения их состояние не имеет.
Наконец, для нас в дальнейшем будет иметь значение состояние ячеек BODEN и BODLEVEL. Первая, будучи установлена в ноль, разрешает работу так называемой схемы BOD (Brown-out Detection), которая сбрасывает контроллер при снижении питания ниже допустимого порога. Ячейка BODLEVEL и определяет этот самый порог — при установленной в 0 ячейке он равен 4 В, при установленной в 1–2,7 В.
При питании 5 В надо выбирать первое значение, при питании 3,3 В — второе. Это предохраняет контроллер от «недопустимых операций» при выключении питания, но для обеспечения полной сохранности содержимого EEPROM таких мер может оказаться недостаточно, и приходится производить дополнительные действия (см. также главу 18). Все остальные ячейки следует оставить по умолчанию (и тем более ни в коем случае не трогать Lock биты, при установке которых доступ к программе и fuse битам вообще отключается навсегда!). Только учтите, что в разных контроллерах одни и те же узлы могут программироваться по-разному. Так, в рассматриваемом далее ATtiny2313 (и некоторых других, в основном из тех, что способны работать при напряжении питания до 1,8 В) схема BOD устроена иначе: ячеек BODLEVEL там целых три, причем упомянутая ранее BODLEVEL соответствует BODLEVEL0, а при тех же значениях порога ячейки BODLEVEL2: BODLEVEL1 должны быть в состоянии 10. Ячейки BODEN там нет, а выключенному состоянию схемы BOD соответствуют все единицы во всех трех ячейках. Зато там есть любопытный fuse бит CKOUT, который при программировании (установке в ноль) подключает к выводу 6 (PD2) выход тактового генератора, и еще бит CKDIVS, который в том же случае снижает тактовую частоту в восемь раз (например, при кварце 8 МГц МК заработает, как от 1 МГц, что снижает потребление). Поэтому для каждого конкретного контроллера следует сверяться с техническим описанием.
Пожалуй, это все, что нужно знать до того, как вы приступите, собственно, к программированию. Данные, относящиеся к конкретным контроллерам и программаторам, вы доберете из руководств к ним, которые придется изучать так или иначе.
Примеры программированияНаписание программ — целое искусство, поэтому здесь можно на нескольких примерах попытаться дать только общее представление о том, как это делается, — заостряя внимание на специфических особенностях программирования для МК, а не программирования вообще. Полного обзора команд и даже комментариев по каждой встречающейся команде вы также здесь не увидите — это потребовало бы отдельной книги (см. [19, 20], а также книгу автора [21]).
Самая простая программа
Давайте напишем сначала самую простую программу, которая будет включать светодиод сразу при включении питания и больше ничего не делать. Для примера возьмем контроллер ATtiny2313, схема подключения которого вместе с программирующим разъемом показана на рис. 19.2.
Рис. 19.2. Схема подключения ATtiny2313
* * *
Подробности
Обратим внимание на RC-цепочку (R1 и С1), которая подсоединена к выводу Reset. Она служит для более надежного сброса контроллера при не слишком качественном источнике питания, если установление напряжения затягивается. В техническом описании указано, что по выводу Reset уже имеется встроенный фильтр дребезга с «подтягивающим» резистором, так что эта цепочка оказывается вроде бы и ненужной (ее установка рекомендовалась для семейства Classic, где фильтра не было). Тем не менее, для более надежной работы МК рекомендуется во всех случаях устанавливать резистор R1 с номиналом 3–5 кОм (встроенный резистор имеет слишком большой номинал). Что касается конденсатора С1, то если для управления сбросом применяется внешний монитор питания, как описано в главе 18, то, разумеется, он будет только мешать, в остальных случаях он необязателен, но делает работу схемы более стабильной. Резисторы R2-R4 при наличии программирующего разъема устанавливать обязательно, в противном случае надежность схемы снижается.
Заметим, что в схеме на рис. 19.2 показана только небольшая часть функциональности входных/выходных линий, которые все, включая даже Reset и выводы подсоединения кварца (кроме, конечно, выводов питания), имеют как минимум две, а большинство даже три функции. Подробно обо всех этих функциях можно узнать из технического описания, частично вы с ними познакомитесь из дальнейшего изложения.
* * *
Светодиод мы сразу взяли двухцветный — в целях дальнейшего усовершенствования схемы. Светодиод L56 (можно также взять L57 или малогабаритный L36) светится зеленым, если плюс питания находится со стороны ключа (скоса на корпусе), и красным — если наоборот. Здесь мы его подключили к выводам PD5 и PD6 порта D. Таким образом, если на этих выводах будет одинаковый уровень (неважно, единица или ноль), то светодиод погашен, если разный — то в зависимости от того, на каком выводе единица, светодиод будет гореть красным или зеленым. Токоограничивающий резистор R5 при логическом уровне на выходе порта примерно 4,5 В обеспечит ток через светодиод около 5 мА.
Пусть мы для начала хотим просто зажечь светодиод при включении питания, демонстрируя, что контроллер работает. Для определенности выберем зеленое свечение. Тогда нам необходимо создать программу, которая делает следующее:
1. Конфигурирует нужные выводы порта D (PD5 и PD6) на выход.
2. Устанавливает на выводе PD6 логическую единицу (логический ноль на выводе PD5 устанавливается по умолчанию).
И что, программа будет состоять всего из двух команд? Увы, не все так просто.