Микроконтроллеры AVR в радиолюбительской практике
   

Программы
Книги
Статьи



Сайт управляется системой uCoz
Микроконтроллеры AVR в радиолюбительской практике
Скачать книгу  

Содержание


Уважаемые читатели..................................................................................10
Глава 1. Микроконтроллер ATiny2313/V фирмы ATMEL................12
1.1. Основные характеристики и возможности...........................................13
Основные характеристики.............................................................................13
Блок-схема микроконтроллера......................................................................15
Особенности микросхемы ATtiny2313............................................................ 15
Описание выводов...............................................................:........................19
1.2. AVR — центральное ядро процессора.,................................................21
Введение.......................................................................................................21
Краткая характеристика архитектуры............................................................21
АЛУ — арифметико-логическое устройство...................................................24
Регистр статуса.............................................................................................24
Файл регистров общего назначения..............................................................26
Х-регистр, Y-регистр и Z-регистр..................................................................27
Указатель стека.............................................................................................28
Память ATtiny2313.........................................................................................29
Системная перепрограммируемая Rash-память программ...........................29
Память данных SRAM.....................................................................................31
Память данных EEPROM................................................................................32
Процесс чтения/записи EEPROM...................................................................32
Регистр адреса EEPROM —EEAR...................................................................33
Регистр данных EEPROM — EEDR.................................,................................34
Регистр управления EEPROM — EECR...........................................................34
Атомарное программирование байта............................................................36
Раздельное программирование байта...........................................................37
Стирание.......................................................................................................37
Запись............................................~v............................................................37
Предотвращение ошибок при работе с EEPROM...........................................38
Регистры ввода—вывода...............................................................................39
Регистры ввода—вывода общего назначения................................................40
1.3. Тактовый генератор.............................................................................41
Система синхронизации и варианты ее конфигурирования...........................41
Источники тактового сигнала.........................................................................42
Источник сигнала по умолчанию....................................................................43
Кварцевый резонатор....................................................................................44
Встроенный перестраиваемый RC-генератор...............................................46
Регистр калибровки генератора — OSCCAL...................................................47
Внешний тактовый сигнал.............................................................................49
Внутренний генератор на 128 кГц..................................................................50
Регистр предварительного делителя частоты — CLKPR.................................51
Управления питанием и режимы сна..............................................................53
Регистр управления микроконтроллером — MCUCR......................................53
Режим Idle.....................................................................................................54
Режим Power-down........................................................................................55
Режим Standby..............................................................................................56
Советы по уменьшению потребляемой мощности.........................................57
1.4. Система управления и сброса.............................................................59
Начальный сброс микроконтроллера AVR......................................................59
Источники сигнала сброса.............................................................................59
Сброс при включении питания.......................................................................61
Внешний сброс.............................................................................................62
Сброс при снижении напряжения питания.....................................................63
Сброс от сторожевого таймера.....................................................................65
Регистр статуса системы сброса — MCUSR...................................................66
1.5. Сторожевой (охранный) таймер..........................................................67
Особенности.................................................................................................67
Блок-схема....................................................................................................67
Режимы работы.............................................................................................68
Регистр управления сторожевым таймером — WDTCSR (WDTCR)..................70
1.6. Прерывания..........•...............................................................................73
1.7. Порты ввода—вывода..........................................................................74
Введение.......................................................................................................74
Использование портов для цифрового ввода—вывода..................................76
Конфигурация выводов.................................................................................76
Переключение значения разряда порта.........................................................78
Переключение между выводом и вводом.......................................................78
Чтение значения на выводе порта..................................................................79
Разрешение цифрового ввода и режимы низкого потребления (режимы сна) 82
Дополнительные функции портов..................................................................83
Регистр управления микроконтроллером — MCUCR......................................86
Альтернативные функции порта А..................................................................86
Альтернативные функции порта В.................................................................86
Детальное описание альтернативных функций каждого из выводов..............87
Альтернативные функции порта D..................................................................91
Подробное описание альтернативных функций.............................................91
Описание управляющих регистров портов ввода—вывода............................93
1.8. Внешние прерывания..........................................................................95
Назначение и режимы работы.......................................................................95
Регистр управления микроконтроллером — MCUCR......................................96
Главный регистр маски прерываний — GIMSK...............................................98
Регистр флагов внешних прерываний — E1FR................................................99
Регистр маски прерываний по изменению на любом из контактов — PCMSK100
1.9. Восьмиразрядный таймер/счетчик с поддержкой режима ШИМ.......101
Назначение и особенности..........................................................................101
Упрощенная блок-схема.............................................................................. 101
Регистры.....................................................................................................101
Используемые обозначения........................................................................103
Источники тактового сигнала таймера/счетчика..........................................104
Модуль счета.....'..........................................................................................105
Модуль совпадения.....................................................................................106
Принудительное изменение состояния выхода совпадения........................108
Блокировка режима совпадения в момент записи регистра TCNT0..............108
Использование модуля совпадения.............................................................108
Модуль вывода сигнала совпадения............................................................109
Режим вывода сигнала совпадения и генерация сигналов...........................110
Режимы работы...........................................................................................111
Режим «Normal»...........................................................................................111
Режим сброса при совпадении (СТС)...........................................................112
Режим Fast PWM (быстрый ШИМ)................................................................113
ШИМ, корректный по фазе (Phase Correct PWM)..........................................115
Регистр А управления таймера/счетчика 0 — TCCR0A................................. 117
Регистр В управления таймера/счетчика 0 — TCCR0B.................................121
Счетный регистр таймера/счетчика 0 — TCNT0...........................................123
Регистр совпадения (канал A) —OCR0A......................................................123
Регистр совпадения (канал В) — OCR0B......................................................124
Регистр маски таймера/счетчика 0 — TIMSK...............................................124
Регистр флагов таймера/счетчика 0 — TIFR................................................. 125
Предварительные делители таймера/счетчика 0 и таймера/счетчика 1....... 126
Внутренний источник тактового сигнала...................................................... 126
Сброс предварительного делителя............................................................. 126
Внешний источник тактового сигнала.....................................................'.... 127
Главный регистр управления Таймерами — GTCCR...................................... 129
1.10. 16-разрядный таймер/счетчик (таймер/счетчик 1)..........................130
Основные особенности...............................................................................130
Условные обозначения................................................................................130
Регистры.....................................................................................................131
Терминология.............•.................................................................................134
Совместимость...........................................................................................134
Доступ к 16-разрядным регистрам..............................................................135
Источники тактового сигнала таймера/счетчика..........................................136
Модуль счета...............................................................................................136
Модуль захвата...........................................................................................138
Источники сигнала запуска в режиме захвата..............................................140
Схема подавления помех.............................................................................141
Использование модуля захвата...................................................................141
Модуль совпадения.....................................................................................142
Принудительное изменение сигнала на выходе совпадения........................145
Блокировка режима совпадения в момент записи регистра TCNT1..............145
Использование модуля совпадения.............................................................146
Модуль вывода сигнала совпадения............................................................146
Режимы работы 16-разрядного таймера/счетчика......................................148
Режим Normal..............................................................................................148
Режим сброса при совпадении (СТС)...........................................................149
Режим Fast PWM..........................................................................................150
Режим phase correct PWM............................................................................153
Режим phase and frequency correct PWM......................................................156
Регистр А управления таймером/счетчиком — TCCR1A...............................156
Регистр В управления таймером/счетчиком — TCCR1В...............................160
Регистр С управления таймером/счетчиком-TCCR 1С.................................161
Счетный регистр таймера/счетчика 1 — TCNT1HnTCNT1L..........................162
Регистр совпадения A —OCR 1 АН и OCR 1AL................................................163
Регистр совпадения В —OCR 1ВН и OCR 1BL............................................... 163
Регистр захвата — ICR1H и ICR1L................................................................ 164
Регистр маски прерываний таймера/счетчика —TiMSK.............................. 165
Регистр флагов таймера/счетчика 1 — TIFR................................................. 166
1.11.USART..............................................................................................167
Особенности............................................................................................... 167
Краткий обзор............................................................................................. 167
Совместимость режимов AVRUSART и AVRUART......................................... 169
Тактовый генератор.....................................................................................170
Внутренняя генерация тактового сигнала — генератор скорости передачи
информации.................................................................................................172
Режим удвоенной скорости (U2X)................................................................173
Внешний тактовый сигнал...........................................................................174
Синхронизация процесса передачи данных.................................................175
Форматы кадра...........................................................................................175
Расчет значения бита четности....................................................................177
Инициализация USART................................................................................178
Передача данных — передатчик USART.......................................................180
Посылка кадра данных длиной от 5 до 8 бит.................................................180
Посылка кадра данных длиной 9 бит............................................................181
Флаги и прерывания передатчика...............................................................182
Генератор сигнала четности........................................................................183
Отключение передатчика.............................................................................183
Прием данных — приемник USART..............................................................184
Прием кадра данных длиной от5до8 битов................................................184
Прием кадра данных длиной 9 бит...............................................................185
Флаг готовности приемника и вызов прерывания........................................187
Флаги ошибки приемника............................................................................187
Схема контроля четности............................................................................189
Выключение приемника...............................................................................189
Освобождение буфера приемника..............................................................189
Асинхронный прием данных........................................................................190
Восстановление тактового сигнала в асинхронном режиме........................190
Восстановление данных в асинхронном режиме..........................................192
Допустимые отклонения в асинхронном режиме........................................194
Режим мультипроцессорного обмена..........................................................196
Регистр ввода—вывода USART — UDR........................................................197
Регистр «А» статуса и управления USART — UCSRA.....................................198
Регистр «В» статуса и управления USART — UCSRB.....................................200
Регистр С статуса и управления USART — UCSRC........................................202
Регистры скорости обмена информации USART — UBRRLn UBRRH............204
1.12. Универсальный последовательный интерфейс — USI......................204
Назначение и особенности..........................................................................204
Краткое описание........................................................................................205
Описание принципа работы в трехпроводном режиме................................207
Пример операции SPI для ведущего устройства..........................................210
Пример операции SP1 для ведомого устройства.........................................212
Принцип действия в двухпроводном режиме...............................................212
Схема обнаружения стартового условия.....................................................216
Альтернативное использование USI.........................................,...................217
Полудуплексная асинхронная передача данных...........................................217
Регистр данных USI — USIDR.......................................................................217
Регистр состояния USI — USISR..................................................................219
Регистр управления USI — USICR................................................................221
1.13. Аналоговый компаратор..................................................................225
Назначение и особенности..........................................................................225
Регистр статуса и управления аналогового компаратора — ACSR...............225
Регистр отключения цифрового ввода — DIDR............................................228
1.14. Встроенная система отладки программ debugWIRE........................229
Основные особенности встроенной системы отладки.................................229
Назначение.................................................................................................229
Физический интерфейс...............................................................................230
Точки останова программы..........................................................................231
Ограничения режима debugWIRE.................................................................231
Специальный регистр ввода—вывода предназначенный для debugWIRE .... 232
Регистр данных debugWire — DWDR.............................................................232
Автоматическое перепрограммирование памяти программ........................232
Стирание страницы.....................................................................................234
Загрузка страницы (заполнение данными временного буфера)...................234
Запись страницы.........................................................................................235
Адресация памяти программ при автоматическом перепрограммировании 235 Регистр статуса и управления загрузкой программной памяти — SPMCSR . 237
Запись в EEPROM и работа с регистром SPMCSR....................................7... 238
Чтение состояния fuse-переключателей и битов блокировки программным
путем...........................................................................................................239
Предотвращение ошибок при программировании Flash-памяти..................240
Время программирования Flash-памяти при использовании команды SPM. 241
1.15. Программирование памяти.............................................................242
Биты защиты памяти данных и программ.....................................................242
Fuse-лереключатели...................................................................................243
Фиксирование значений fuse-переключателей............................................245
Байты идентификации.................................................................................245
Байт калибровки..........................................................................................245
Размер страницы........................................................................................246
Глава 2. Написание программ для микроконтроллеров AVR.........247
2.1. Музыкальная шкатулка......................................................................248
Постановка задачи......................................................................................248
Схема..........................................................................................................249
Алгоритм.....................................................................................................249
Кодируем мелодии......................................................................................251
Алгоритм работы музыкальной шкатулки.....................................................252
Программа на Ассемблере..........................................................................253
Описание программы (листинг 2.1).............................................................258
Процедура вычисления адреса....................................................................259
Текст программы «шаг за шагом»................................................................259
Особенности программы.............................................................................259
Подрограмма формирования задержки......................................................263
Программа на языке СИ..............................................................................265
Описание программы (листинг 2.2).............................................................267
2.2. Кодовый замок..................................................................................271
Постановка задачи......................................................................................271
Алгоритм.....................................................................................................272
Схема..........................................................................................................275
Программа на Ассемблере..........................................................................276
Описание программы (листинг 2.3).............................................................281
Процедура записи ключевой комбинации в EEPROM...................................293
Процедура проверки кода...........................................................................294
Процедура открывания замка......................................................................295
Программа на языке СИ..............................................................................296
Описание программы (листинг2.4).............................................................296
2.3. Кодовый замок с музыкальным звонком............................................309
Постановка задачи......................................................................................309
Алгоритм.....................................................................................................309
Схема..........................................................................................................310
Программа на Ассемблере..........................................................................311
Программа на языке СИ..............................................................................323
ПРИЛОЖЕНИЕ.....................................................................329
Список литературы................!.................................................................337
Список полезных ссылок на ресурсы Интернет........................................337

Микроконтроллеры AVR в радиолюбительской практике

Данная книга представляет собой справочник, в котором представлено полное и подробное описание одной конкретной микросхемы - микроконтроллера ATiny2313 семейства AVR фирмы Atmel. Описание построено на основе оригинальной технической документации на микросхему и содержит описание всех регистров, всех видов памяти и всех внутренних систем микроконтроллера.
Имеется и практический раздел для радиолюбителей. Книга содержит описание нескольких практических схем, выполненных с применением данного микроконтроллера. Каждая схема снабжена подробным описанием и примером управляющей программы. Программы приведены в двух вариантах: на Ассемблере и языке СИ. Все программы также подробно описаны.
Книга рассчитана на широкий круг читателей. Она будет полезна разработчикам электронных устройств, работникам ремонтных организаций, радиолюбителям и студентам технических ВУЗов.

Уважаемые читатели
Современную микроэлектронику трудно представить без такой важной составляющей, как микроконтроллеры. Микроконтроллеры незаметно завоевал весь мир. В последнее время на помощь человеку пришла целая армия электронных помощников. Мы привыкли к ним, поэтому часто даже не подозреваем, что во м ногах таких устройствах работает микроконтроллер. Микроконтроллерные технологии очень эффективны.
Одно и то же устройство, которое раньше собиралось на традиционных элементах, будучи собрано с применением микроконтроллеров» становится проще, не требует регулировки и меньше по размерам. Кроме того, с применением микроконтроллеров появляются практически безграничные возможности по добавлению новых потребительских функций и возможностей к уже существующим устройствам. Достаточно просто поменять программу!
Мировая промышленность выпускает огромную номенклатуру микроконтроллеров. Специализированные контроллеры предназначенны для применения в какой-либо одной конкретной области, например:
■ контроллер для телевизора;
■ контроллер для модема;
■ контроллер для компьютерной мышки и т. п.
Особый же класс составляют универсальные микроконтроллеры. Они не имеют конкретной специализации и могут применяться в самых различных областях микроэлектроники. В частности, при желании их с успехом можно применить для создания перечисленных выше устройств. Но главное в том, что можно создать любое, может даже принципиально новое устройство.
Одна из самых популярных серий универсальных микроконтроллеров — это микроконтроллеры AVR выпускаемые американской фирмой Atmei. Микросхемы AVR широко используются в самых различных конструкциях, описание которых вы можете найти в журналах по микроэлектронике либо в Интернете.
Конечно, можно просто бездумно повторить любую из этих схем. Но гораздо полезнее научится самому разрабатывать микропроцессорные устройства. Для тех, кто хочет:
■ изучить основные принципы работы микропроцессоров;
я понять основы внутренней архитектуры микроконтроллеров серии AVR, рекомендую приобрести новое издание Самоучителя по микропроцессорной технике [3].
Для тех, кто хотел бы получить практический урок разработки схем и программ для микроконтроллеров, рекомендую новую книгу Александра Белова "Создаем устройства на микроконтроллерах" [4].
Для тех, кто прочитал обе вышеперечисленные книги, либо для тех, кто и так знаком с основами, предлагается данная книга. Книга представляет собой полное и подробное описание микроконтроллера ATiny2313 семейства AVR. Книга составлена на основе фирменной документации на данный микроконтроллер и поможет наиболее полно применить все его особенности и свойства.
Описанию микроконтроллера посвящена первая глава. Подробно описываются все регистры микроконтроллера, их свойства, назначение и приемы работы. Описываются все встроенные системы (таймеры, каналы ввода/вывода, память, система прерываний и т. п.). Кроме того, даны советы по правильному применению и хитрости, позволяющие оптимизировать потребляемую энергию, быстродействие и другие параметры.
Во второй главе приведено несколько конкретных примеров применения микроконтроллера. Это несколько практических схем с подробным описанием и примером программ. Причем каждая программа написана в двух вариантах: на Ассемблере и на языке СИ. Все схемы и каждая из программ снабжены подробным описанием. В качестве примеров используются авторские разработки (музыкальная шкатулка и кодовый дверной замок).
Издательство надеется, что настоящая книга будут полезна широкому кругу начинающих конструкторов электронной техники, радиолюбителей и студентов технических вузов. Автор будет благодарен за любые замечания и комментарии по книге. Все замечания прошу высылать Александру Белову:
■ по почте: Украина, г. Симферополь, ул. Русская, 194;
■ или по E-mail: avbeIov@by.ru.
Дополнительную информацию об этой, а так же о других книгах Александра Белова, вы можете почерпнуть на специальном сайте поддержки его книг по адресу: http://book.microprocessor.by.ru/.
Ознакомиться с новинками и приобрести книги из любой страны мира можно через официальный сайт и Интернет-магазин издательства Наука и Техника www.nit.com.ru.
Удачи Вам во всем!
Сергей Корякин-Черняк, Главный редактор
2.1. Музыкальная шкатулка
Постановка задачи
И так, начинаем ряд примеров, в которых будет не только представлено описание неких схем на микроконтроллере, но и описан процесс их разработки. Все три примера, приведенные в этой книге специально разработаны автором, и предназначены для обучения начинающих программистов и являются заключительным этапом урока по про¬граммированию, подробно представленного в [4].
В первом примере мы покажем процесс разработки простого микро¬процессорного устройства, предназначенного для автоматического воспроизведения нескольких простейших мелодий. Причем все эти мелодии мы жестко "зашьем" в память микроконтроллера. Удобнее всего для этого использовать программную память контроллера. То есть, ту же самую память, куда записывается управляющая програм¬ма. Можно было бы, конечно, для хранения мелодий использовать и EEPROM. Но объем EEPROM в микросхеме ATiny2313 составляет всего 128 байт, а объем памяти программ - 2 килобайта. Поэтому память программ в данном случае предпочтительнее.
Сформулируем задачу следующим образом: «Разработать уст¬ройство, предназначенное для воспроизведения простых одноголосых мелодий, записанных в память программ на этапе программирования. Устройство должно иметь семь управляющих кнопок. Каждой из кнопок должна соответствовать своя мелодия. Мелодия воспро¬изводится при нажатии и удержании кнопки. При отпускании всех кнопок воспроизведение мелодий прекращается».


С1.С2 22
+5В

248

Рис. 2.1. Принципиальная электрическая схема музыкальной шкатулки

начале сохраняет (строки 111—114), а в конце — восстанавливает (строки 131—134) все используемые регистры.
Рассмотрим, как работает эта подпрограмма. Сначала определяется длительность задержки. Для этого извлекается соответствующий эле¬мент из таблицы tabz. Номер элемента соответствует коду задержки, находящемуся в регистре dnota. Извлечение значения из таблицы производится уже знакомым нам образом. Команды, реализующие вычисление адреса нужного элемента таблицы, находятся в строках 115—118. Затем в строках 119 и 120 производится чтение элемента таблицы. Прочитанный код задержки помещается в регистровую пару Y.
Теперь наша задача: сформировать задержку, пропорциональную со¬держимому регистровой пары Y. Так как микроконтроллер Atiny2313 имеет только один шестнадцатиразрядный таймер, который уже занят формированием звука, будем формировать задержку программным путем. Но в данном случае цикл формирования задержки построен немного по-другому.
Вообще-то, способов построения подобных подпрограмм может быть бесконечное множество. Все зависит от изобретательности програм¬миста. Использованный в данном примере способ более удобен для формирования задержки переменной длительности, пропорциональ¬ной заданному коэффициенту. Главной особенностью нового способа является шестнадцатиразрядный параметр цикла.
Для хранения этого параметра используется регистровая пара Z. Перед началом цикла задержки в нее записывается ноль. Затем начи¬нается цикл, на каждом проходе которого содержимое регистровой пары Z увеличивается на единицу. После каждого такого увеличения производится сравнение нового значения Z с содержимым регистро¬вой пары Y.
Заканчивается цикл тогда, когда содержимое Z и содержимое Y окажутся равны. В результате число, записанное в регистровой паре Y, будет определять количество проходов цикла. Поэтому и время задержки, формируемое этим циклом, будет пропорционально константе задержки. Однако это время будет слишком мало для получения приемлемого темпа воспроизведения мелодий. Для того, чтобы увеличить время до нужной нам величины, внутрь главного цикла задержки помещен еще один цикл, имеющий фиксированное количество проходов.
264

Описанная выше процедура задержки занимает строки 121—135. В строках 121, 122 производится запись нулевого значения в регист¬ровую пару Z. Большой цикл задержки занимает строки 123—130. Малый внутренний цикл занимает строки 124—125. Для хранения параметра малого цикла используется регистр loop. В строке 123 в него записывается начальное значение. Строки 124,125 выполняются до тех пор, пока содержимое loop не окажется равным нулю.
В строке 126 содержимое регистровой пары Z увеличивается на еди¬ницу. В строках 127—130 производится сравнение содержимого двух регистровых пар Y и Z. Сравнение производится побайтно. Сначала сравниваются младшие байты (строка 127). Если они не равны, оператор условного перехода в строке 128 передает управление на начало цикла.
Если младшие байты равны, сравниваются старшие байты (строка 129). Если старшие байты неодинаковы, оператор brne в строке 130 опять заставляет цикл начинаться с начала. И только когда оба опе¬ратора сравнения дадут положительный результат (не вызовут пере¬хода), цикл заканчивается, и подпрограмма формирования задержки переходит к завершающей фазе (к строкам 131—135).
Программа на языке СИ
Возможный вариант программы на языке СИ приведен в листинге 2.2. В данном случае использована модификация языка поддердиваемая программной средой CodeVision. Описание программы расчитано на читателей, знакомых с языком СИ. Если вы не владеете этим языком или у вас вызывает проблему конкретная реализация языка, рекомендую обратиться к [4], где представлен подробный урок этого языка для начинающих.
Теперь рассмотрим подробнее программу с самого начала.
265

Схема
Принципиальная электрическая схема устройства, уовлетворяющая сформулированным выше требованиям приведена на рис. 2.1. Кнопки S1...S7 предназначены для выбора мелодий. Для воспроизведения мелодии используется звуковой излучатель VF1, сигнал на который поступает с выхода РВЗ микроконтроллера. В качестве усилителя сигнала используется электронный ключ Rl, VT1.
Алгоритм
Для начала нам нужно придумать, как мы будем хранить мелодии в памяти. Для того, чтобы в памяти можно было что-либо хранить, нужно сначала это что-то каким-либо способом закодировать. Любая мелодия состоит из нот. Каждая нота имеет свой тон (частоту) и дли¬тельность звучания. Для того, чтобы закодировать тон ноты, можно просто все ноты пронумеровать по порядку. Удобнее нумеровать, начиная с самого низкого тона. На клавиатуре клавишного инстру¬мента это будет слева направо.
Известно, что весь музыкальный ряд делится на октавы. Если вы ду¬маете, что в каждой октаве семь нот, то вы плохо знаете физические основы музыкального ряда. На самом деле в современном музыкаль¬ном ряду каждая октава делится на 12 нот. Семь основных нот (белые клавиши) и пять дополнительных (черные клавиши).
Деление на основные и дополнительные ноты сложилось историче¬ски. В настоящее время используется музыкальный строй, в котором все 12 нот одной октавы равнозначны. Частоты любых двух соседних нот отличаются друг от друга в одинаковое количество раз. При этом частоты одноименных нот в двух соседних октавах отличаются ровно в два раза. Более подробно об этом вы можете прочитать в [3].
Для нас же важно то, что коды всем этим нотам мы должны присваи¬вать в порядке возрастания частоты. И начнем мы с ноты «До» первой октавы. Для музыкальной шкатулки более низкие ноты не нужны. В табл. 2.1 показаны коды для всей первой октавы. Следующая, вторая октава продолжает первую и по кодировке, и по набору частот. Так нота «До» второй октавы будет иметь код 13, а частоту f12=fox2. А нота «Ре» второй октавы будет иметь код 14 и частоту f]3=f|x2. И так далее.
249

Описание программы (листинг 2.1)
Описание программы удобнее начать с конца. Начиная со строки 136 программы располагается описание так называемых таблиц данных. На самом деле каждая из этих "таблиц" представляеет собой цепоч¬ку кодов, записываемых в программную память микроконтроллера и предназначенных для кодирования того либо иного вида данных. Для описания этих данных используются как операторы db, так и операторы dw.
Первая таблица содержит коэффициенты задержки для формирования всех вариантов музыкальной длительности. Таблица начинается с ад¬реса, соответствующего метке tabz. Вся таблица занимает одну строку программы (строка 136). Так как в нашей программе мы будем приме¬нять лишь семь вариантов длительности, таблица имеет 7 элементов. Каждый элемент записывается в память как двухбайтовое слово.
В строках 137—140 описывается таблица коэффициентов деления для всех нот. Начало таблицы соответствует метке tabkd. Каждый элемент этой таблицы также имеет размер в два байта. Первый элемент таблицы равен нулю. Это неиспользуемый элемент. Ноты номер ноль у нас не существует. Ноль мы использовали для кодирования паузы.
В паузе не формируется звуковой сигнал, поэтому и коэффициент деления там не имеет смысла. Поэтому значение нулевого элемента массива несущественно. Описание таблицы разбито на строки. Для удобства каждая строка описывает коэффициенты деления для одной октавы. Нулевая нота выделена в отдельную строку. Последняя октава неполная, так как наша шкатулка будет использовать всего 32 ноты.
В строках 143—200 описана таблица мелодий. Вернее, это не одна таблица, а семь таблиц (своя таблица для каждой из мелодий). Каждая таблица помечена своей отдельной меткой (те 11, те 12 — те 17). Значение каждой метки — это адрес начала соответствующей ме¬лодии. Каждое значение таблицы мелодий записывается в память в виде одного байта. Поэтому все строки, кроме последней, для каждой таблицы имеют четное число значений.
В строках 141,142 описана таблица начал всех мелодий. Начало этой таблицы отмечено меткой tabm. Таблица используется для того, чтобы программа могла найти адрес начала нужной мелодии по ее номеру. В качестве элементов массива выступают удвоенные значения меток mell,mel2 —me!7. Применение удвоенных значений обусловлено необходимостью перевода адресов из основной адресации в альтер-
258

нативную. При трансляции программы вместо меток в память будут записаны конкретные адреса.
Подробнее об основной и альтернативной адресации читайте в [3] и [4].
Процедура вычисления адреса
Большое количество таблиц в нашей программе заставляет позабо¬титься о процедуре вычисления адреса.
Однотипные вычисления удобно оформить в виде подпрограммы. Эта подпрограмма занимает строки 78—84. Вызов подпрограммы производится по имени addw. Подпрограмма получает номер элемента таблицы и адрес ее начала. Номер элемента передается в подпрограм¬му при помощи регистра YL, а адрес — через регистровую пару Z.
Используя эти данные, подпрограмма вычисляет адрес нужного эле¬мента. Для этого она сначала удваивает номер элемента (строка 79). Затем дополняет полученное значение до шестнадцатиразрядного путем записи в YH нулевого байта (строка 80). И, наконец, производит сложение двух шестнадцатиразрядных величин, находящихся к этому моменту в регистровых парах Y и Z (строки 81, 82). Результат вычис¬лений при этом попадает, в регистровую пару Z. Назначение команд push и pop (строки 78, 83), по-видимому, уже объяснять не нужно.
Текст программы «шаг за шагом»
Теперь рассмотрим текст программы с самого начала. В строках 3...10 расположен модуль описания переменных (рабочих регистров). В строках 13...31 располагается модуль переопределения векторов прерываний, в строках 32...41 — модуль команд инициализации.
Особенности программы
Процедура, расположенная в строках 45—52 программы, сканирует клавиатуру и находит код первой из нажатых кнопок. Найденый код находится в регистре count. Затем управление переходит к строке 53. С этого места начинается процедура выбора мелодии (строки 53—58). Суть процедуры — прочитать из таблицы tabm значение
259

адреса начала этой мелодии. То есть прочитать элемент таблицы, номер которого равен коду нажатой клавиши.
Прежде чем прочитать элемент, необходимо найти его адрес. Для вычисления адреса используем подпрограмму addw. Перед тем, как вызвать подпрограмму, подготовим все данные. Номер нажатой клавиши помещаем в регистр YL (строка 53). Адрес начала таблицы записываем в регистровую пару Z (строки 54, 55). И лишь затем в строке 56 вызывается подпрограмма addw.
После выхода из подпрограммы в регистровой nape Z находится ре¬зультат вычислений — адрес нужного нам элемента таблицы tabm. Следующие две команды (строки 57 и 58) извлекают тот элемент (адрес начала мелодии) и помещают его в регистровую пару X. Там этот адрес будет храниться все время, пока воспроизводится именно эта мелодия.
Следующий этап — воспроизведение мелодии. Воспроизведением мелодии занимается процедура, расположенная в строках 59—77. Для последовательного воспроизведения нот нам понадобится указа¬тель текущей ноты. В качестве указателя текущей ноты используется регистровая пара Z. В самом начале процедуры воспроизведения мелодии в регистровую пару Z помещается адрес начала мелодии их регистровой пары X (строки 59, 60).
Затем начинается цикл воспроизведения (строки 61—77). В этом цикле программа извлекает код ноты по адресу, на который указывает наш указатель, выделяет из кода ноты код тона и код длительности, воспроизводит ноту, а затем увеличивает значение указателя на еди¬ницу. Затем весь цикл повторяется.
Этот процесс происходит до тех пор, пока код очередной ноты не окажется равным 255 (метка конца мелодии). Прочитав этот код, программа передает управление на строку 62, где в регистр Z сно¬ва записывается адрес начала мелодии. Воспроизведение мелодии начнется сначала. Этот процесс должен прерваться лишь в одном случае — при отпускании управляющей кнопки.
Для проверки состояния кнопок в цикл воспроизведения мелодии включена специальная процедура (строки 61—63). Процедура упро¬щенно проверяет состояние сразу всех кнопок. Она считывает содер¬жимое порта PD (строка 61) и сравнивает его с кодом 0x7F (строка 62). Прочитанное из порта значение может быть равно 0x7F только
260

в одном случае — если все кнопки отпущенны. Если хотя бы одна кнопка нажата, то при чтении порта мы получим другое значение.
Проверкой вышеописанного условия занимается оператор breq в строке 63. Если все кнопки оказались отпущены, этот оператор завершает цикл воспроизведения мелодии и передает управление на метку ml, то есть на самое начало основного цикла программы. Там происходит выключение звука, а затем новое сканирование клавиатуры.
Если хотя бы одна кнопка окажется нажатой, то цикл воспроизведения звука продолжается дальше, и управление переходит к строке 64, где происходит извлечение кода ноты. Так как адрес этой ноты находится в регистровой паре Z (указатель текущей ноты), то для извлечения ноты просто используется команда 1pm.
В строке 65 происходит проверка признака конца мелодии. Только что прочитанный код ноты сравнивается с кодом OxFF. Оператор breq в строке 66 передает управление по метке т4, если мелодия действительно закончилась (условие выполняется). Если код ноты не равен OxFF, перехода не происходит, и управление переходит к строке 67.
В строках 67—75 происходит обработка кода ноты. То есть из кода ноты выделяется код тона и код длительности. Сначала на код ноты накладывается маска, которая оставляет пять младших разрядов, а три старших сбрасывает (строка 67). Под действием маски в регистре temp остается код тона, который затем помещается в регистр f not а (строка 68).
Теперь нам нужно найти код длительности ноты. Для этого нам заново придется извлечь код ноты из памяти программ. Так как до этого момента мы не изменяли положение указателя текущей ноты, то для извлечения нет никаких препятствий. В строке 69 мы повторно извлекаем код ноты из памяти программ. Но на этот раз значение указателя увеличивается. Теперь можно приступать к выделению кода длительности. Как вы помните, длительность кодируется тремя младшими битами кода ноты. Для выделения этих битов нам также нужно использовать маску. Но одной маской нам не обойтись. Нам нужно не просто выделить три старших разряда, а сделать их млад¬шими, как это показано на рис. 2.2.
261

0 0 0 d4 d3 d2 d1 dO
1 ' | ' A ' A ' A

d7 d6 d5 d4 d3 d2 d1 dO

0 0 0 0 0 d2 d1 dC

0 0 0 0 0 d2 d1 dO

Рис. 2.2. Разложение кода ноты
Процедура выделения кода длительности занимает строки 70—74.
Сначала программа производит многократный циклический сдвиг кода ноты до тех пор, пока три старших разряда не станут тремя млад¬шими. Для сдвига используется команда го 1. Так как сдвиг происходит через ячейку признака переноса, то нам понадобится четыре команды сдвига. Эти команды занимают в программе строки 70—73.
Затем в строке 74 на полученное в результате сдвигов число накла¬дывается маска, которая выделяет три младшие бита, а пять старших сбрасывает в ноль. Полученный таким образом код длительности записывается в регистр dnota (строка 75).
Когда код тона и код длительности определены, производится вызов подпрограммы воспроизведения ноты (строка 76). Оператор г jmp в строке 77 передает управление на начало цикла воспроизведения мелодии, и цикл повторяется для следующей ноты.
Подпрограмма воспроизведения ноты занимает строки 85—110. Она выполняет следующие действия:
■ извлекает из таблицы tabkd коэффициент деления, соответ¬ствующий коду ноты;
■ программирует таймер и включает звук;
■ затем выдерживает паузу и звук выключает.
Если код тона равен нулю (нужно воспроизвести паузу без звука), из¬влечение коэффициента деления и включение звука не выполняется. Подпрограмма сразу переходит к формированию паузы.
Начинается подпрограмма воспроизведения ноты с сохранения всех используемых регистров (строки 85—88). Затем производится проверка кода ноты на равенство нулю (строка 89). Если код ноты
262

равен нулю, то оператор breq в строке 90 передает управление по метке ntl, то есть к строке, где происходит вызов процедуры фор¬мирования задержки.
Если код ноты не равен нулю, то программа приступает к извлечению коэффициента деления. Для вычисления адреса элемента таблицы tabkd, где находится этот коэффициент, снова используется под¬программа addw.
Код тона помещается в регистр YL (строка 91), а адрес начала таб¬лицы — в регистровую пару Z (строки 92, 93). Вызов подпрограммы addw производится в строке 94. В регистровой паре Z подпрограмма возвращает адрес элемента таблицы, где находится нужный нам ко¬эффициент деления. В строках 95, 96 из таблицы извлекается этот коэффициент. А в строках 97,98 он помещается в регистр совпадения таймера. В строках 99,100 включается звук.
В строке 104 вызывается специальная подпрограмма, предназначен¬ная для формирования задержки. Подпрограмма называется wait и формирует задержку с переменной длительностью. Длительность за¬держки зависит от значения регистра dnota. По окончании задержки звук выключается (строки 102,103).
На этом можно было бы закончить процесс воспроизведения ноты. Однако это еще не все. Для правильного звучания мелодии между двумя соседними нотами необходимо обеспечить хотя бы неболь¬шую паузу. Если такой паузы не будет, ноты будут звучать слитно. Это исказит мелодию, особенно если подряд идет несколько нот с одинаковым тоном. Формирование паузы между нотами происходит в строках 104,105.
Вспомогательная пауза формируется при помощи уже знакомой нам подпрограммы задержки. В строке 104 коду паузы присваивается нулевое значение (выбирается самая минимальная пауза). Затем в строке 105 вызывается подпрограмма wait. После окончания паузы остается только восстановить содержимое всех сохраненных регистров из стека (строки 106—109) и выйти из подпрограммы (строка ПО).
Подрограмма формирования задержки
И последнее, что нам еще осталось рассмотреть, — это подпрограм¬ма формирования задержки. Текст подпрограммы занимает строки 111—135. Как и любая другая подпрограмма, подпрограмма wait в
263