/
Author: Мартин Т.
Tags: электротехника микрорадиоэлектронная аппаратура микроэлектроника электроника микроконтроллеры
ISBN: 5-94120-104-4
Year: 2006
Text
PHILIPS
Тревор Мартин
СЕРИЯ
Компакт-диск
внутри!
Микроконтроллеры ARM7
Семейство LPC2000
компании Philips
Вводный курс
hitexMM
DEVELOPMENT TOOLS
SOFTWARE
МИКРОКОНТРОЛЛЕРЫ ARM7
Семейство LPC2000
компании Philips
Вводный курс
ОДЭКА
Trevor Martin
The Insider's Guide
To The Philips
ARM7-BASED
MICROCONTROLLERS
An Engineer’s Introduction
To The LPC 2000 Series
hftexBHM
DEVELOPMENT TOOLS
Серия «МИРОВАЯ ЭЛЕКТРОНИКА»
Тревор Мартин
МИКРОКОНТРОЛЛЕРЫ ARM7
Семейство LPC2000
компании Philips
Вводный курс
Перевод с английского
Москва
Издательский дом «Додэка-ХХ1»
2006
ОАЭКА
УДК 621.316.544.1(035.5)
ББК 32.844.1-04я2
М29
Мартин Т.
М29 Микроконтроллеры ARM7. Семейство LPC2000 компании Philips.
Вводный курс/Пер. с англ. — М.: Издательский дом «Додэка-ХХ1», 2006. —
240 с.: илл. + CD. — (Серия «Мировая электроника»).
ISBN 5-94120-104-4
Семейство микроконтроллеров LPC2000 компании Philips — первый представитель
нового поколения микроконтроллеров, построенных на базе 16/32-битного RISC-про-
цессора ARM7 TDMI.
Эта книга — введение в архитектуру процессора ARM7 TDMI и микроконтроллеров
семейства LPC2000. Она основана на материалах однодневных семинаров, которые про-
водятся для профессиональных инженеров, заинтересованных в быстром изучении мик-
роконтроллеров семейства LPC2000. В ней рассматриваются следующие вопросы: введе-
ние в процессор ARM7, средства разработки программного обеспечения, системная ар-
хитектура LPC2000, периферийные устройства LPC2000. Кроме того, в книгу включено
полное учебное пособие, где на практических примерах закрепляются вопросы, изло-
женные в основном тексте. Изучая теоретический материал и выполняя сопутствующие
упражнения, вы быстро освоите процессор ARM7 и микроконтроллеры семейства
LPC2000.
На компакт-диске, прилагающемся к книге, имеются ознакомительные версии попу-
лярной интегральной среды разработки ЦVISION и компилятора Си от компании Keil
Elektronik, а также исходный код для всех упражнений как в версии для компилятора
Keil, так и в версии для компилятора GCC. На диске также содержатся руководства поль-
зователя по ядру ARM7, микроконтроллерам семейства LPC2000, различные специфика-
ции и другие материалы.
Предназначена для разработчиков радиоэлектронной аппаратуры, инженеров, сту-
дентов технических вузов и радиолюбителей.
УДК 621.316.544.1(035.5)
ББК 32.844.1-04я2
Все права защищены. Никакая часть этого издания не может быть воспроизведена в любой
форме или любыми средствами, электронными или механическими, включая фотографирова-
ние, ксерокопирование или иные средства копирования или сохранения информации, без
письменного разрешения издательства.
ISBN 5-94120-104-4
© Hitex (UK) Ltd, 2005
© Издательский дом «Додэка-XXI», 2006
® Серия «Мировая электроника»
СОДЕРЖАНИЕ
Введение.................................................................11
Глава 1. Процессорное ядро ARM7..........................................13
Основные положения.......................................................13
Конвейер.................................................................13
Регистры.................................................................14
Регистр текущего состояния программы.....................................16
Режимы обработки исключительных ситуаций.................................18
Набор команд ARM7........................................................21
Команды ветвления....................................................23
Команды обработки данных.............................................24
Команда обмена...........................................................26
Изменение регистров состояния............................................27
Программное прерывание...................................................28
Модуль МАС...............................................................28
Набор команд THUMB.......................................................29
Резюме...................................................................32
Глава 2. Разработка программного обеспечения.............................33
Основные положения.......................................................33
Какой из компиляторов?...................................................33
ИСР ц VISION.........................................................35
Учебное пособие......................................................35
Стартовый код............................................................36
Взаимодействие кода ARM и THUMB..........................................38
Библиотека STDIO.........................................................41
Организация доступа к периферийным устройствам...........................42
Подпрограммы обработки прерываний........................................42
Программное прерывание...................................................44
Размещение кода в ОЗУ....................................................45
Встраиваемые функции...........................................................46 5
СОДЕРЖАНИЕ
Поддержка операционных систем............................................47
Размещение объектов по фиксированным адресам.............................47
Встроенный ассемблер.....................................................47
Аппаратные средства отладки..............................................47
Важное замечание!....................................................49
Еще более важное замечание!..........................................49
Резюме...................................................................50
Глава 3. Системные периферийные устройства...............................51
Основные положения.......................................................51
Внутренние шины..........................................................51
Организация памяти.......................................................52
Программирование регистров...............................................54
Модуль ускорения работы памяти...........................................55
Пример конфигурирования модуля МАМ...................................58
Программирование FLASH-памяти............................................59
Управление картой распределения памяти...............................60
Загрузчик............................................................60
Внутрисхемное программирование (ISP).................................62
Внутрипрограммное программирование (IAP).............................63
Интерфейс внешней шины...................................................64
Интерфейс внешней памяти.............................................65
Использование интерфейса внешней шины................................68
Загрузка из ПЗУ..........................................................70
Схема ФАПЧ...............................................................71
Делитель шины VPB........................................................73
Управление электропитанием...............................................75
Система прерываний LPC2000.............................................. 77
Блок управления выводами.............................................77
Выводы внешних прерываний............................................78
Структура прерываний.................................................78
Прерывание FIQ.......................................................79
Выход из прерывания FIQ..............................................80
Векторные прерывания IRQ.............................................81
Выход из прерывания IRQ..............................................84
Невекторные прерывания...............................................85
Выход из невекторного прерывания IRQ.................................86
Вложенные прерывания.................................................88
Резюме...................................................................90
Глава 4. Периферийные устройства общего назначения.......................91
Основные положения.......................................................91
Порты ввода/вывода общего назначения.....................................91
Таймеры общего назначения................................................92
& Модуль ШИМ.................................................................96
СОДЕРЖАНИЕ
Часы реального времени..................................................100
Сторожевой таймер.......................................................104
Универсальный асинхронный приемопередатчик..............................105
Интерфейс I2C...........................................................111
Интерфейс SPI...........................................................117
Аналого-цифровой преобразователь........................................119
Цифро-аналоговый преобразователь........................................123
Контроллер интерфейса CAN...............................................123
Семиуровневая модель ISO............................................124
Структура узла сети CAN.............................................125
Объекты сообщений CAN...............................................126
Арбитраж на шине CAN................................................128
Тактовая синхронизация..............................................129
Передача сообщений CAN..............................................131
Ограничение распространения ошибок..................................133
Прием сообщений CAN.................................................138
Фильтрация сообщений................................................139
Полноскоростной интерфейс USB 2.0.......................................143
Введение в USB......................................................143
Физическая организация шины USB.....................................144
Логическая организация шины USB.....................................146
Скорость передачи данных............................................147
Каналы шины USB.....................................................147
Распределение полосы пропускания шины...............................150
Транзакции на шине USB..............................................150
Ограничение распространения ошибок..................................152
Конфигурация устройства.............................................152
Дескриптор устройства...............................................153
Дескриптор конфигурации.............................................154
Дескриптор интерфейса...............................................155
Дескриптор конечной точки...........................................155
Нумерация...........................................................156
Резюме..................................................................170
Глава 5. Учебное пособие по средствам разработки компании Keil..........171
Установка...............................................................171
Использование ИСР pVISION компании Keil.................................172
Упражнение 1. Использование пакета программ компании Keil...........173
Использование программы отладки.........................................181
Использование аппаратного JTAG-отладчика ULINK..........................185
Установка отладчика ULINK...........................................185
Упражнение 2. Стартовый код.........................................188
Упражнение 3. Использование кода THUMB..............................189
Упражнение 4. Использование библиотек STDIO.........................191
7
СОДЕРЖАНИЕ
Упражнение 5. Простое прерывание..................................192
Упражнение 6. Программное прерывание..............................194
Упражнение 7. Модуль МАМ..........................................196
Упражнение 8. Внутрипрограммное программирование..................198
Упражнение 9. Интерфейс внешней шины..............................199
Упражнение 10. Схема ФАПЧ.........................................203
Упражнение 11. Быстрое прерывание.................................204
Упражнение 12. Векторное прерывание...............................204
Упражнение 13. Невекторное прерывание.............................206
Упражнение 14. Вложенные прерывания...............................207
Упражнение 15. Порты ввода/вывода общего назначения...............208
Упражнение 16. Функция захвата (capture)..........................208
Упражнение 17. Функция совпадения (match).........................209
Упражнение 18. Генерация симметричного ШИМ-сигнала................212
Упражнение 19. Часы реального времени.............................214
Упражнение 20. UART...............................................215
Упражнение 21. Интерфейс I2C......................................215
Упражнение 22. Интерфейс SPI......................................217
Упражнение 23. Аналого-цифровой преобразователь...................217
Упражнение 24. Цифро-аналоговый преобразователь...................218
Упражнение 25. Передача данных по интерфейсу CAN..................218
Упражнение 26. Прием данных по интерфейсу CAN.....................219
Глава 6. Учебное пособие по средствам разработки GNU..................221
Основные положения....................................................221
Стартовый код GCC.....................................................221
Взаимодействие кода ARM/THUMB.........................................221
Организация доступа к периферийным устройствам........................222
Подпрограммы обработки прерываний.....................................222
Программное прерывание............................................222
Встраиваемые функции..................................................223
Упражнение 1. Использование инструментальных средств компании Keil
совместно с компилятором GNU......................................223
Упражнение 2. Стартовый код.......................................229
Упражнение 3. Использование кода THUMB............................230
Упражнение 4. Использование библиотек GNU.........................233
Упражнение 5. Простое прерывание..................................233
Упражнение 6. Программное прерывание..............................235
Приложение............................................................237
Список литературы.....................................................237
Ссылки................................................................237
Инструментальные средства и ПО....................................237
Оценочные платы и модули..........................................237
Материалы, размещенные на компакт-диске...............................238
Благодарности
Автор хотел бы поблагодарить
сотрудников компании
Philips Semiconductors
Киса ван Севентера и Криса Дэвиса
за помощь в создании
этой книги
Введение
Эта книга представляет собой практическое руководство для тех, кто собира-
ется использовать в своих новых разработках тот или иной микроконтроллер се-
мейства LPC2000 компании Philips. Данная книга не является ни справочником,
ни учебным пособием. Предполагается, что читатель имеет некоторый опыт в об-
ласти программирования микроконтроллеров для встраиваемых систем и знаком
с языком программирования Си. Основной объем технической информации со-
держится в четырех первых главах книги, поэтому, если вы совершенно не знако-
мы с семейством LPC2000 и, в частности, с процессорным ядром ARM7, вам не-
обходимо внимательно прочитать эти главы.
В первой главе рассматриваются основные характеристики процессорного
ядра (ЦПУ) ARM7. После прочтения этой главы вы будете знать достаточно,
чтобы начать писать программы для любых устройств, построенных на базе
ядра ARM7. Если же вы хотите расширить свои знания, к вашим услугам име-
ется несколько прекрасных книг, описывающих эту архитектуру, часть из ко-
торых указана в списке литературы. Во второй главе рассказывается о том, как
следует писать программы на языке Си для процессора ARM7. По существу, в
этой главе описываются специфические расширения стандарта ANSI С, тре-
буемые для программирования встраиваемых систем. Все примеры, встречаю-
щиеся в книге, были написаны с использованием коммерческого компилято-
ра, однако в настоящее время на платформу ARM перенесен и бесплатный па-
кет программ GCC.
В главе 6 подробно описаны особенности компилятора GCC, специфические
для ARM. После прочтения первых двух глав книги вы должны хорошо разби-
раться в процессоре и средствах разработки для него. Третья глава посвящена
системной периферии семейства LPC2000. В ней рассказывается о системной ар-
хитектуре микроконтроллеров семейства и рассматривается вопрос конфигури-
рования микросхем для достижения наибольшей производительности. В четвер-
той главе мы познакомимся со встроенными периферийными устройствами этих
микроконтроллеров и узнаем, как их необходимо конфигурировать при исполь-
зовании в своих программах.
11
Введение
На протяжении всех четырех глав вам будут встречаться различные упражне-
ния. Все эти упражнения подробно рассматриваются в пятой главе, посвященной
практическим занятиям. Упражнения можно выполнить, используя ознакоми-
тельные версии компилятора и симулятора, имеющиеся на компакт-диске, кото-
рый прилагается к книге. В продаже также имеется недорогой стартовый набор
разработчика (starter kit), используя который вы можете загрузить учебную про-
грамму в реальный микроконтроллер и удостовериться, что она действительно
работает. Я искренне надеюсь, что, читая эту книгу и выполняя упражнения, вы
быстро освоите микроконтроллеры семейства LPC2000.
Глава 1_______________________
ПРОЦЕССОРНОЕ ЯДРО ARM7
Основные положения
Все микроконтроллеры семейства LPC2000 построены на основе ЦПУ ARM7.
Вообще говоря, чтобы использовать эти микроконтроллеры, вам совершенно не
нужно быть экспертом в области программирования процессора ARM7, поскольку
заботу о большинстве сложных моментов берет на себя компилятор языка Си. Тем
не менее, чтобы разработать надежное устройство, вы должны иметь хотя бы об-
щее представление о том, как работает ЦПУ и какие у него имеются особенности.
В этой главе мы рассмотрим основные характеристики ядра ARM7 вместе с
его моделью программирования, а также обсудим набор команд, используемый
этим процессором. В результате вы получите всю необходимую информацию о
процессоре, являющемся «сердцем» семейства LPC2000. Для более углубленного
изучения процессоров ARM рекомендую обратиться к книгам, указанным в спис-
ке литературы.
Ключевой принцип, лежащий в основе процессора ARM, — простота. Ядро
ARM7 является RISC-машиной, предполагающей использование небольшого
числа команд и соответственно состоящей из относительно небольшого количест-
ва логических элементов. Благодаря этому процессор ARM7 идеально подходит
для использования во встраиваемых системах. Он имеет высокую производитель-
ность, низкое энергопотребление и занимает небольшую часть общей площади
кристалла.
Конвейер
Основной элемент ЦПУ ARM7 — конвейер команд, который используется
для обработки команд, считанных из памяти программ. Конкретно, в ядре ARM7
реализован трехступенчатый конвейер (Рис. 1.1).
Трехступенчатый конвейер является самой простой разновидностью конвей-
еров и не подвержен возникновению различных опасных ситуаций, таких как
«чтение раньше записи», которые встречаются в конвейерах с большим числом
ступеней. Конвейер имеет три аппаратно-независимые ступени, благодаря кото-
рым одновременно с выполнением одной команды осуществляется декодирова-
ние второй и выборка третьей. Он настолько эффективно ускоряет прохождение
13
Глава 1. Процессорное ядро ARM7
команд через ЦПУ, что большинство команд ARM может выполняться за один
такт. Конвейер наиболее эффективен при выполнении линейного кода При об-
наружении перехода конвейер сбрасывается, и для возобновления выполнения
программы с максимальной скоростью он должен сначала заполниться Позже
мы с вами увидим, что набор команд процессора ARM имеет несколько интерес-
ных особенностей, позволяющих исключить из кода короткие переходы для
улучшения прохождения кода по конвейеру Поскольку конвейер является со-
ставной частью ЦПУ. он полностью скрыт от программиста. 1ем не менее, важно
помнить, что значение счетчика команд (Program Counter — PC) на 8 байт превы-
шает значение адреса текущей выполняемой команды В связи с этим необходи-
мо аккуратно подходить к вычислению смещений в случае относительной адреса-
ции с использованием счетчика команд.
Например, команда:
0x40000 LDR PC,[PC,#4]
загрузит в счетчик команд PC содержимое, находящееся по адресу PC + 4 По-
скольку PC опережает текущую команду на 8 байт, в него будет загружено содер-
жимое по адресу 0х400С, а не 0x4004.
Регистры
Процессор ARM7 имеет архитектуру «load-and-store» (загрузка — сохра-
нение), поэтому для выполнения любой обработки данных необходимо сначала
перенести эти данные из памяти в определенные регистры, выполнить команду
обработки данных и затем записать полученные значения обратно в память
(Рис. 1.2).
Основной регистровый файл состоит из 16 пользовательских регистров
R0...R15 (Рис. 1.3). Каждый из этих регистров является 32-битным^. Регистры
R0...R12 предназначены исключительно для нужд пользователя и не выполняют
никаких других функций, в то время как регистры R13...R15 имеют дополнитель-
отечественной литературе принято пользоваться понятиями «разряд», «разрядный».
В данном издании мы будем придерживаться зарубежной терминологии («бит», «битный»), что
14 более соответствует современной тенденции в цифровой технике. — Прим, редактора.
Регистры
Рис. 1.2. Обработка данных
ЦПУ ARM 7 имеет
архитектуру
«load-and-store».
Все команды обработки
данных могут работать
только с основным
регистровым файлом
ГВ основной регистровый файл входят'
шестнадцать 32-битных регистров
и один дополнительный регистр ЦПУ,
который называется регистром
текущего состояния программы.
R0...R12 — пользовательские
регистры, а регистры R13...R15
^выполняют специальные функции
Рис. 1.3. Структура основного регистрового файла
ные функции. Регистр R13 используется в качестве указателя стека (Stack
Pointer — SP). Регистр R14 называется регистром связи (Link Register — LR). При
вызове подпрограммы адрес возврата автоматически запоминается в регистре
связи, откуда затем считывается при возврате. Такое решение позволяет быстро
переходить к «концевым» функциям (функции, которые не вызывают других
функций) и возвращаться из них. Если же функция входит в состав «ветви», т.е.
вызывает другие функции, содержимое регистра связи необходимо сохранять в
стеке (R13). Наконец, регистр R15 выполняет функции счетчика команд (PC).
Что интересно, многие команды могут работать с регистрами R13...R15, как
с обычными пользовательскими регистрами.
15
Глава 1. Процессорное ядро ARM7
Регистр текущего состояния
программы
Наряду с банком регистров в ЦПУ имеется дополнительный 32-битный ре-
гистр, который называется регистром текущего состояния программы (Current
Program Status Register — CPSR). Регистр CPSR содержит набор флагов, которые
управляют функционированием ЦПУ ARM7 и отображают его состояние
(Рис. 1.4).
3130292827
876543210
N Z О V I F Т м 4 М 3 М 2 М 1 М 0
Разрешение прерываний:
I — IRQ
Флаги условий:
N — отрицательный результат
Z — нулевой результат
С — перенос
V — переполнение
F Набор команд Thumb
Регистр CPSR содержит флаги условий,
отображающие результат выполнения команд
обработки данных, а также набор
пользовательских флагов, определяющих режим
работы процессора и управляющих прерываниями.
Флаг Т предназначен только для чтения
Режим работы
процессора:
10000-User
10001 -FIQ
10010-IRQ
10011 — Supervisor
10111-Abort
11011 — Undefined
11111 — System
Puc. 1.4. Регистр текущего состояния программы
В старших четырех битах регистра CPSR хранятся флаги условий, значения
которых определяются процессором. Эти флаги отражают результат выполнения
очередной команды обработки данных. Благодаря им вы можете узнать, не было
ли получено в результате выполнения команды отрицательное или нулевое значе-
ние, а также не произошел ли перенос или переполнение. Младшие восемь битов
регистра CPSR содержат флаги, значения которых прикладная программа может
изменять. Биты 7 и 8 являются флагами I и F соответственно. Эти флаги исполь-
зуются для разрешения и запрещения двух линий прерываний, являющихся
внешними по отношению к ЦПУ ARM7. Как мы с вами увидим позже, все пери-
ферийные модули микроконтроллеров LPC2000 подключены к этим двум лини-
ям прерываний. При работе с данными битами нужно соблюдать осторожность,
поскольку для запрещения любого из источников прерываний в соответству-
ющий бит необходимо записать 1, а не 0, как можно было бы предположить. Пя-
тый бит регистра является флагом THUMB.
ЦПУ ARM7 поддерживает два набора команд — 32-битный набор команд
ARM и 16-битный набор команд THUMB. Соответственно флаг Т показывает,
какой из наборов команд используется. Учтите, что программа не должна пытать-
16 ся напрямую устанавливать или сбрасывать этот флаг для переключения между
Регистр текущего состояния программы
наборами команд. Корректный механизм смены текущего набора команд мы рас-
смотрим чуть позже. Последние пять битов регистра CPSR являются флагами ре-
жима. В общей сложности процессор ARM7 поддерживает 7 режимов работы.
Прикладные программы, как правило, выполняются в режиме User. В этом режи-
ме программа может обращаться к регистрам R0...R15 и CPSR. Однако при воз-
никновении исключительных ситуаций (таких как прерывание, ошибка памяти
или выполнение команды генерации программного прерывания) режим работы
процессора изменяется. При этом регистры R0...R12 и R15 остаются теми же са-
мыми, а регистры R13 (LR) и R14 (SP) заменяются новой парой регистров, уни-
кальной для каждого режима. Таким образом, каждый режим имеет собственные
регистр связи и указатель стека. Более того, в режиме быстрых прерываний (F1Q)
дублируются и регистры R7...R12. Это позволит вам сразу же приступить к обра-
ботке прерывания FIQ, не тратя время на сохранение регистров в стеке.
В каждом из режимов, за исключением режима User, имеется дополнитель-
ный регистр, называемый регистром сохраненного состояния программы (Saved
Program Status Register — SPSR). Если в момент возникновения исключительной
ситуации программа находилась в режиме User, то происходит смена режима, и
текущее содержимое регистра CPSR сохраняется в регистре SPSR. После обра-
ботки исключительной ситуации (при возврате из обработчика) содержимое ре-
гистра CPSR восстанавливается из SPSR, обеспечивая возобновление выполне-
ния прикладной программы. Режимы работы процессора показаны на Рис. 1.5.
ЦПУARM"7 имеет 6различных рабочих режимов, которые используются
для обработки исключительных ситуаций. Затененные регистры представляют собой
дублирующие регистры, которые «включаются» при изменении режима работы.
Регистр SPSR используется для сохранения содержимого регистра CPSR
^при переключении режимов ______
System & User FIQ Supervisor Abort IRQ Undefined
RO RO RO RO RO RO
R1 R1 R1 R1 R1 R1
R2 R2 R2 R2 R2 R2
R3 R3 R3 R3 R3 R3
R4 R4 R4 R4 R4 R4
R5 R5 R5 R5 R5 R5
R6 R6 R6 R6 R6 R6
R7 R7 R7 R7 R7
R8 R8 R8 R8 R8
R9 R9 R9 R9 R9
R10 R10 R10 R10 R10
R11 R11 R11 R11 R11
R12 R12 R12 R12
R13 R14 R13~svc R14_svc R13_abt R14 abt R13_und R14_und
R15 (PC) R15 (PC) R15 (PC) R15 (PC) R15 (PC)
| CPSR CPSR CPSR SPSR_svc CPSR SPSR_abt 1 CPSR CPSR SPSRjjnd
Рис. 1.5. Режимы работы процессора
17
Глава 1. Процессорное ядро ARM7
Режимы обработки
исключительных ситуаций
При возникновении исключительной ситуации изменяется режим работы
ЦПУ, и в PC загружается адрес соответствующего вектора прерывания (Табл. 1.1).
Таблица векторов начинается с нулевого адреса, первым в таблице расположен
вектор сброса, а за ним остальные векторы (по 4 байта на каждый).
Таблица 1.1. Адреса векторов прерываний
Исключительная ситуация Режим Адрес вектора Каждому режиму работы соответствует свой вектор прерывания. При смене процессором режима производится переход по этому вектору. Обратите внимание! Вектор по адресу 0x00000014 отсутствует!
Reset (сброс) Supervisor 0x00000000
Undefined instruction (неопределенная команда) Undefined 0x00000004
SWI (программное прерывание) Supervisor 0x00000008
Prefetch Abort (ошибка обращения к памяти при выборке команды) Abort 0x0000000C
Data Abort (ошибка обращения к памяти при доступе к данным) Abort 0x00000010
IRQ (прерывание) IRQ 0x00000018
FIQ (быстрое прерывание) FIQ 0x0000001С
Замечание. В таблице векторов имеется «дырка», поскольку вектор с адресом
0x00000014 отсутствует. Этот адрес использовался в ранних версиях процес-
соров ARM, а в процессоре ARM7 он сохранен, чтобы обеспечить программную
совместимость между различными архитектурами ARM. Однако, как мы уви-
дим позже, в микроконтроллерах семейства LPC2000 эти четыре байта игра-
ют очень важную роль.
При одновременном возникновении нескольких исключительных ситуаций
используется метод приоритетов. Приоритеты прерываний приведены в Табл. 1.2.
Таблица 1.2. Приоритеты прерываний
Приоритет Исключительная ситуация
Высший 1 Reset
2 Data Abort
3 FIQ
4 IRQ
5 Prefetch Abort
Низший 6 Undefined instruction SWI
Каждый источник
исключительной ситуации
имеет фиксированный
приоритет. Встроенные
периферийные устройства
обслуживаются
прерываниями FIQ и IRQ.
Приоритеты прерываний
от периферийных устройств
можно назначать внутри
этих групп
18
Режимы обработки исключительных ситуаций
Когда возникает исключительная ситуация, например прерывание IRQ, про-
цессор выполняет следующие действия (Рис. 1.6). Во-первых, адрес следующей
выполняемой команды (PC + 4) сохраняется в регистре связи. Затем регистр
CPSR копируется в регистр SPSR конечного режима (в нашем случае SPSR_irq).
После этого в PC заносится адрес вектора прерывания режима исключительной
ситуации. Для режима IRQ этот адрес — 0x00000018. В то же время режим работы
процессора меняется на IRQ, в результате чего регистры R13 и R14 заменяются
соответствующими регистрами этого режима. При входе в режим IRQ устанавли-
вается флаг I регистра CPSR, что приводит к отключению линии IRQ. Если тре-
буется использовать вложенные прерывания, то вы должны вручную разрешить
прерывание IRQ в программе и занести содержимое регистра связи в стек, чтобы
сохранить исходный адрес возврата. С вектора прерывания программа перейдет к
выполнению подпрограммы обработки прерываний. Первое, что необходимо
сделать в данной подпрограмме, — сохранить в стеке IRQ все регистры из диапа-
зона R0...R12, которые будут в ней использоваться. Затем можно приступать
собственно к обработке исключительной ситуации.
1. РС сохраняется
в регистре связи
2. CPSR сохраняется
в SPSR_excep
R13
R14
R15
CPSR
Рис. 1.6. Обработка исключительной ситуации
После завершения обработки исключительной ситуации необходимо вер-
нуться в режим User и продолжить выполнение программы с прерванного места.
Однако в наборе команд ARM отсутствуют команды типа «возврат» или «возврат
из подпрограммы», поэтому манипуляции со счетчиком команд РС необходимо
осуществлять, используя обычные команды. Ситуация осложняется тем, что су-
ществует несколько различных вариантов возврата.
Для начала взглянем на команду SWI. При выполнении этой команды адрес
следующей выполняемой команды сохраняется в регистре связи, после чего про-
изводится обработка исключительной ситуации. Все, что нам нужно сделать для
возврата из исключительной ситуации, — это загрузить содержимое регистра свя-
зи обратно в РС, и программа продолжит свое выполнение. Однако, чтобы ЦПУ
при этом переключился обратно в режим User, необходимо использовать специ-
альную команду пересылки MOVS (более подробно мы рассмотрим ее чуть позже).
Таким образом, команда возврата из программного прерывания будет следующей:
MOVS - R15,R14 ; Скопировать регистр связи в РС и переключить режимы 19
Глава 1. Процессорное ядро ARM7
А при возникновении исключительной ситуации по прерываниям FIQ и IRQ
текущая выполняемая команда сбрасывается и выполняется переход к обработ-
чику исключительной ситуации. При возврате из исключительной ситуации в ре-
гистре связи находится адрес отброшенной команды плюс 4. Чтобы возобновить
выполнение программы с нужного места, мы должны уменьшить значение, хра-
нящееся в регистре связи, на 4. В данном случае для уменьшения содержимого
регистра связи и сохранения результата в PC мы используем специальную коман-
ду вычитания, восстанавливающую также и режим работы ЦПУ. Таким образом,
команда возврата из режимов FIQ, IRQ и Abort выглядит следующим образом:
SUBS R15,R14,#4
В случае, если произошла ошибка обращения к памяти, исключительная си-
туация возникнет через одну команду после той, выполнение которой явилось ее
причиной. В идеале, в этом случае мы должны перейти к подпрограмме обработ-
ки прерывания Data Abort, выяснить и устранить причину затруднений и снова
попытаться выполнить команду, которая привела к возникновению исключи-
тельной ситуации. Соответственно, мы должны «отмотать» PC назад на две
команды — отброшенную и вызвавшую возникновение исключительной ситуа-
ции. Другими словами, нам нужно вычесть из регистра связи число восемь и со-
хранить результат в PC. Таким образом, команда возврата из прерывания Data
Abort имеет вид:
SUBS R15,R14,#8
При выполнении команды возврата модифицированное содержимое регистра
связи загружается в счетчик команд, ЦПУ переключается обратно в режим User, а
содержимое регистра SPSR переписывается обратно в CPSR. В случае возникно-
вения исключительных ситуаций FIQ или IRQ дополнительно разрешаются соот-
ветствующие прерывания. В результате всех этих действий процессор выходит из
привилегированного режима и возвращается к выполнению пользовательской
программы (Рис. 1.7).
20
1.CPSR
восстанавливается
из SPSR_excep
2. PC
восстанавливается
из регистра связи
R13
R14
R15
CPSR
Рис. 1.7. Завершение обработки исключительной ситуации
Набор команд ARM7
Набор команд ARM 7
Теперь, когда мы получили общее представление о ядре ARM7, его модели
программирования и режимах работы, пришла пора познакомиться с его набо-
ром или, точнее, наборами команд. Поскольку все примеры в книге написаны на
Си, вам нет необходимости быть экспертом в области программирования на ас-
семблере ARM7. Однако, чтобы разрабатывать действительно эффективные
программы, очень важно понимать машинный код, скрывающийся за строками
программы на языке высокого уровня. Прежде чем мы приступим к изучению ко-
манд ARM7, необходимо отметить, что на самом деле ЦПУ ARM7 поддерживает
два набора команд: набор команд ARM с 32-битными командами и набор команд
THUMB с 16-битными командами. Далее в книге слово ARM будет означать
32-битный набор команд, а слово ARM7 — собственно ЦПУ.
Ядро ARM7 было разработано таким образом, чтобы его можно было исполь-
зовать как в качестве процессора с обратным порядком байтов (big-endian
processor), так и в качестве процессора с прямым порядком байтов (little-endian
processor). В первом случае старший бит (Most Significant Bit — MSB) 32-битного
слова располагается в начале слова, а во втором случае — в конце (Рис. 1.8). Ду-
маю, вы обрадуетесь, узнав, что в семействе LPC2000 используется только прямой
порядок байтов (т.е. MSB является самым старшим битом адреса), что значитель-
но облегчает работу с процессором. Однако используемый вами компилятор для
ARM7 должен уметь компилировать код в обоих форматах. В связи с этим необ-
ходимо удостовериться, что формат слов задан правильно, в противном случае
полученный код будет «вывернут наизнанку».
MSB
LSB
Прямой порядок
Бит О
Бит 31
MSB
LSB
Обратный порядок
Бит О
Бит 31
ЦПУARM7 поддерживает как прямой,
так и обратный порядок байтов.
Тем не менее,
в микроконтроллерах Philips
используется только прямой
порядок байтов (little endian)
Рис. 1.8. Прямой и обратный порядок байтов
Одна из наиболее интересных особенностей набора команд ARM заключается
в том, что каждая команда поддерживает условное выполнение. В традиционных
микроконтроллерах единственными условными командами являются команды
условных переходов, и, быть может, ряд других, таких как команды проверки ли-
бо изменения состояния отдельных битов. А в наборе команд ARM старшие 4 би-
та кода команды всегда сравниваются с флагами условий в регистре CPSR
(Рис. 1.9). Если их значения не совпадают, команда не выполняется и проходит
через конвейер как команда NOP (нет операции).
21
Глава 1. Процессорное ядро ARM7
31 28
УСЛОВИЕ
Каждая команда ARM (32-битная) является условно
выполняемой. Между 4 старшими битами кода
команды и флагами условий регистра CPSR
производится операция «Логическое И». Если значения
не совпадают, выполняется команда NOP
Рис. 1.9. Расположение битов сравнения в команде ARM
Таким образом, можно выполнить какую-либо команду обработки данных,
изменяющую флаги условий в регистре CPSR. Затем, в зависимости от результа-
та, следующая команда может быть выполнена, а может и нет. К базовым мнемо-
ническим обозначениям команд ассемблера, таким как MOV или ADD, можно
добавить любой из шестнадцати префиксов, определяющих тестируемые состоя-
ния флагов условий (Табл. 1.3).
Таблица 1.3. Префиксы команд
Префикс Флаги Значение К обозначению любой команды ARM (32-битной) можно добавить один из 16 префиксов, определяющих тестируемые флаги условий. Соответственно существует 16 вариантов каждой команды
EQ Z установлен Равно
NE Z сброшен Не равно
CS С установлен Выше или равно (беззнаковое)
сс С сброшен Ниже (беззнаковое)
MI N установлен Отрицательный результат
PL N сброшен Положительный результат или 0
VS V установлен Переполнение
VC V сброшен Нет переполнения
HI С установлен, Z сброшен Выше (беззнаковое)
LS С сброшен, Z установлен Ниже или равно (беззнаковое)
GE N равен V Больше или равно (знаковое)
LT N не равен V Меньше (знаковое)
GT Z сброшен И (N равен V) Больше (знаковое)
LE Z установлен ИЛИ (N не равен V) Меньше или равно (знаковое)
AL (игнорируются) Безусловное выполнение
К примеру:
EQMOV R1, #0x00800000
означает, что загрузка числа 0x00800000 в регистр R1 будет произведена только в
том случае, если результат выполнения последней команды обработки данных
был «равно» и соответственно установлен флаг Z регистра CPSR. Целью такого
условного выполнения команд является обеспечение непрерывности потока ко-
манд через конвейер, т.к. при каждом выполнении команд перехода конвейер
22
Набор команд ARM7
сбрасывается, и на его повторное заполнение требуется время, что резко снижает
общую производительность. На практике существует некоторый порог, при кото-
ром принудительное «проталкивание» команд NOP через конвейер оказывается
эффективнее выполнения традиционных команд условного перехода и связанно-
го с этим повторным заполнением буфера. Этот порог равен трем командам, по-
этому короткий переход, такой как:
if(x < 100)
{
х++;
}
при использовании условно выполняемых команд ARM будет реализован более
эффективно.
Все множество команд ARM можно разбить на 6 основных групп: команды вет-
вления, команды обработки данных, команды передачи данных, команды переда-
чи блоков данных, команды умножения и команда программного прерывания.
Команды ветвления
Базовая команда перехода (В), как следует из ее названия, позволяет выпол-
нять переход в диапазоне до 32 Мбайт как вперед, так и назад. Модифицирован-
ная версия команды, команда перехода с сохранением адреса (BL), выполняет ту
же операцию, однако при этом сохраняет в регистре связи текущее значение PC,
увеличенное на четыре (Рис. 1.10).
0x400
0x8000
0x400
0x8000
Команда перехода имеет несколько
разновидностей. Обычная команда
перехода (В) осуществляет переход
по заданному адресу. Команда перехода
с сохранением адреса (BL)
осуществляет переход по заданному
адресу, сохраняя при этом адрес
возврата в регистре R14
Рис, 1.10. Команды перехода В и BL
Таким образом, команда перехода с сохранением адреса используется в качест-
ве команды вызова подпрограмм, сохраняющей адрес возврата в регистре связи.
Для возврата из подпрограмм можно использовать команду обычного перехода,
выполняющую переход по адресу, находящемуся в регистре связи. Используя
флаги условий, мы можем выполнять условные переходы и условные вызовы под-
программ. Существует еще две разновидности команды перехода: «переход со
сменой состояния» (ВХ) и «переход со сменой состояния и сохранением адреса»
(ВЕХ). Эти команды выполняют те же операции, что и предыдущие команды, но 23
Глава 1. Процессорное ядро ARM7
при этом еще и выполняют переключение с набора команд ARM на THUMB и
обратно (Рис. 1.11).
0x400
0x8000
0x400
0x8000
Команды перехода
со сменой состояния (ВХ)
и перехода со сменой состояния
и сохранением адреса (BLX)
выполняют те же операции,
что и обычные команды перехода
и перехода с сохранением адреса (Ви BL),
дополнительно осуществляя
переключение между наборами команд
ARM и THUMB
Рис, 1,11, Команды перехода ВХ и BLX
Это единственный способ, который вы должны использовать для изменения
используемого набора команд, т.к. непосредственные манипуляции с флагом Т
регистра CPSR могут привести к непредсказуемым результатам.
Команды обработки данных
Обобщенный формат всех команд обработки данных приведен на Рис. 1.12.
В каждой команде имеется регистр результата и два операнда. Первый операнд
обязательно должен быть регистром, тогда как второй может быть и регистром, и
константой.
Операнды
32-битный сдвиг
Код операции
Cond
R1,R2, R3
Ся8иг I
Используемый формат
команд обработки данных
позволяет реализовать
в одном такте условное
выполнение, логический сдвиг
на величину до 32-х битов
и обработку данных
Условное выполнение
Разрешить изменение флагов условий
Рис, 1,12, Формат команд обработки данных
Помимо всего прочего, в ЦПУ ARM7 имеется многорегистровое устройство
циклического сдвига (barrel shifter), позволяющее при выполнении команды
сдвигать значение 2-го операнда на величину до 32-х битов. Бит S используется
для управления флагами условий. Если этот бит установлен, флаги условий изме-
няются в соответствии с результатом выполнения команды. Если этот бит сбро-
шен, состояние флагов условий не изменяется. Однако если при установленном
бите S в качестве регистра результата указан счетчик команд (R15), производится
копирование содержимого регистра SPSR текущего режима в регистр CPSR. Эта
24 возможность используется для восстановления РС и переключения в исходный
Набор команд ARM7
режим в конце обработки исключительных ситуаций. Не пытайтесь выполнить
такую команду в режиме User, поскольку в этом режиме отсутствует регистр SPSR
и соответственно результат выполнения этой команды невозможно предсказать.
Мнемокод Описание команды
AND EOR Логическое побитовое «И» Логическое побитовое «исключающее ИЛИ»
SUB RSB ADD Вычитание Обратное вычитание Сложение
ADC SBC RSC TST TEQ CMP Сложение с учетом переноса Вычитание с заемом Обратное вычитание с заемом Проверка битов Побитовое сравнение Сравнение
CMN Сравнение с отрицанием
ORR MOV BIC Логическое побитовое «ИЛИ» Пересылка Сброс битов (маскирование)
MVN Пересылка с инверсией
Эти особенности предоставляют нам богатый набор команд обработки дан-
ных, который, с одной стороны, позволяет создавать очень эффективные про-
граммы, а с другой — является источником ночных кошмаров для разработчиков
компиляторов. Вот пример использования типовой команды ARM.
Результатом компиляции выражения
if(Z == 1)
Rl = R2 + (R3 X 4) ;
может быть следующая команда:
EQADDS R1,R2,R3,LSL #2
Копирование регистров
Следующую группу составляют команды передачи данных. ЦПУ ARM7 поддержи-
вает команды загрузки/сохранения, позволяющие пересылать знаковые и беззна-
ковые числа разного размера (слово, полуслово, байт) в/из заданного регистра.
Мнемокод Описание команды
LDR Загрузить слово
LDRH Загрузить полуслово
LDRSH Загрузить полуслово со знаком
LDRB Загрузить байт
LDRSB Загрузить байт со знаком
STR Сохранить слово
STRH Сохранить полуслово
STRSH Сохранить полуслово со знаком
STRB Сохранить байт
STRSB Сохранить байт со знаком
25
Глава 1. Процессорное ядро ARM7
Поскольку набор команд полностью ортогонален, можно загружать 32-бит-
ное значение непосредственно в PC, осуществляя, таким образом, переход в пре-
делах всего адресного пространства процессора. Если конечный адрес лежит вне
диапазона команды перехода, можно просто загрузить сохраненную константу
в счетчик команд.
Групповое копирование регистров
Помимо команд загрузки/сохранения содержимого отдельных регистров, в
наборе команд ARM имеются команды для загрузки (LDM) и сохранения (STM)
групп регистров (Рис. 1.13). Таким образом, с помощью одной команды можно
скопировать в память весь блок регистров или его часть, а с помощью другой —
восстановить его содержимое.
Рис. 1.13. Команды LDM и STM
Команды групповой
загрузки/сохранения
позволяют одной командой
сохранятъ/восстанавливать
содержимое всего
регистрового файла
или любого подмножества
регистров
Команда обмена
В наборе команд ARM имеется также команда обмена (SWP), благодаря кото-
рой обеспечивается поддержка семафоров реального времени. Эта атомарная ко-
манда осуществляет одновременный обмен содержимого регистра и памяти
(Рис. 1.14). Благодаря такому решению предотвращается прерывание процесса
обмена критическими данными при возникновении исключительной ситуации.
Команда обмена (SWP) позволяет
переставлять местами содержимое
двух регистров. Эта операция
выполняется за два такта,
однако обрабатывается как одна
элементарная команда.
Поэтому прерывание не может
нарушить процесс обмена
Рис. 1.14. Команда обмена
Эта команда недоступна из языка Си и поддерживается встроенными функ-
26 циями библиотеки компилятора.
Изменение регистров состояния
Изменение
регистров состояния
Как уже было отмечено в разделе, посвященном архитектуре ARM7, регистры
CPSR и SPSR являются регистрами ЦПУ, однако не входят в состав основного
банка регистров. Напрямую обращаться к этим регистрам могут только две ко-
манды ARM — MSR и MRS. Эти команды обеспечивают пересылку содержимого
регистра CPSR или SPSR в/из заданного регистра (Рис. 1.15). Например, чтобы
запретить прерывания IRQ, необходимо скопировать содержимое регистра CPSR
в рабочий регистр, установить флаг I (путем выполнения операции «И» между
этим регистром и числом 0x00000080) и загрузить полученное значение обратно в
регистр CPSR.
Регистры CPSR и SPSR не отображены
на память и не входят в состав
основного банка регистров.
Единственными командами,
оперирующими с этими регистрами,
являются команды MSR и MRS.
Когда ЦПУ находится в режиме User,
эти команды недоступны
MRS
R15
Рис. 1.15. Изменение регистров состояния
Команды MSR и MRS доступны во всех режимах процессора, за исключением
режима User. Таким образом, менять рабочий режим процессора и разрешать/за-
прещать прерывания можно, только находясь в привилегированном режиме.
После входа в режим User вы можете выйти из него только при возникновении
исключительной ситуации, сбросе, генерации прерываний FIQ и IRQ или же в
результате выполнения команды SWI.
27
Глава 1. Процессорное ядро ARM7
Программное прерывание
Команда программного прерывания SWI генерирует исключительную ситуа-
цию, в результате чего процессор переключается в режим Supervisor, а в счетчик
команд заносится значение 0x00000008. Как и все остальные команды ARM, ко-
манда SWI содержит в четырех старших битах флаги условного выполнения, за
которыми располагается код операции (Рис. 1.16). Остальная часть слова коман-
ды остается свободной. Однако в этих неиспользуемых битах может храниться
число. Эти биты можно проверять в начале подпрограммы обработки прерыва-
ния, чтобы определить, какую именно часть подпрограммы следует выполнять.
Таким образом, с помощью команды SWI можно переключаться в защищенный
режим для выполнения привилегированных участков программы или системных
вызовов.
Команда программного прерывания (SWI) переключает ЦПУ
в режим Supervisor и переходит по адресу вектора SWL
Биты 0...23 не задействованы, однако в них можно передавать
значения, определяемые пользователем
31 28 27 24 23
Условие 1111 Число
Рис. 1.16. Команда SWI
После компиляции команды
SWI #3
в неиспользуемых битах слова команды будет записано число 3. В подпрограмме
обработки прерывания SWI мы можем проверить значение слова команды следу-
ющим образом (текст написан на псевдокоде):
switch( * (R14 - 4) & OxOOFFFFFF)
{
// Вернуться на 4 байта назад
// Замаскировать старшие 8 битов и
// выполнить переход
// в соответствии с результатом
case (SWI-1)
В зависимости от используемого компилятора, вам придется реализовывать
такую проверку самостоятельно или же компилятор автоматически вставит необ-
ходимые команды в код программы.
Модуль МАС
Наряду с многорегистровым устройством циклического сдвига в ядре ARM7
имеется встроенный модуль умножителя/сумматора (МАС). Модуль МАС
поддерживает умножение чисел типа integer и long integer. Команды умножения
28
Набор команд THUMB
чисел типа integer выполняют умножение двух 32-битных регистров и помещают
результат в третий 32-битный регистр. Команда умножения с накоплением вы-
полняет умножение и прибавляет произведение к промежуточной сумме* Коман-
ды умножения чисел типа long integer перемножают содержимое двух 32-битаых
регистров и помещают 64-битный результат в два регистра. Аналогично имеется
команда длинного умножения с накоплением.
Мнемокод Описание команды Разрешение
MUL Умножение 32-битный результат
MULA Умножение с накоплением 32-битный результат
UMULL Беззнаковое умножение 64-битный результат
UMLAL Беззнаковое умножение с накоплением 64-битный результат
SMULL Знаковое умножение 64-битный результат
SMLAL Знаковое умножение 64-битный результат
с накоплением
Набор команд THUMB
Несмотря на то что ARM7 является 32-битным процессором, он подде-
рживает еще один набор команд (16-битный), называемый THUMB
(Рис. 1.17). На самом деле, этот набор команд является сжатой формой набора
команд ARM.
Рис, 1.17. Набор команд THUMB
За счет этого команды, сохраненные в 16-битном формате, распаковываются
в команды ARM, а затем выполняются. Хотя команды THUMB обеспечивают
меньшую производительность по сравнению с командами ARM, благодаря им
достигается более высокая плотность кода. Таким образом, для создания ком-
пактных программ, размещаемых в небольших однокристальных микроконтрол- 29
Глава 1. Процессорное ядро ARM7
лерах, код программ необходимо компилировать в виде совокупности функций
THUMB и ARM. Этот процесс называется interworking и элементарно под-
держивается всеми компиляторами. При компиляции с использованием набора
команд THUMB вы получите 30-процентную экономию памяти программ, в то
время как этот же код, скомпилированный с использованием команд ARM, будет
выполняться на 40% быстрее.
Набор команд THUMB гораздо больше похож на наборы команд традицион-
ных микроконтроллеров. В отличие от команд ARM, команды THUMB не под-
держивают условного выполнения (за исключением команд условных переходов).
Команды обработки данных имеют двухадресный формат, причем в качестве ре-
гистра результата используется один из регистров-источников:
Команда ARM
ADD RO,RO,R1
Команда THUMB
ADD RO,R1
Действие
RO = RO + R1
Команды THUMB не имеют полного доступа ко всем регистрам регистрового
файла (Рис. 1.18). С регистрами R0...R7 (т.н. «младшими регистрами») могут ра-
ботать все команды обработки данных.
А к регистрам R8....R12 («старшие регистры») могут обращаться только 3 из
них:
30 MOV, ADD, CMP
Набор команд THUMB
В наборе команд THUMB отсутствуют команды MSR и MRS, поэтому изме-
нять регистры CPSR и SPSR можно только с помощью косвенной адресации. Ес-
ли вам требуется изменить какие-либо пользовательские биты в регистре CPSR,
необходимо переключиться в режим ARM. Изменять режимы можно с помощью
команд ВХ и BLX (Рис. 1.19). Кроме того, автоматическое переключение в режим
ARM происходит при сбросе или при входе в режим обработки исключительной
ситуации.
Исключительная ситуация
Конец обработки
исключительной ситуации
После сброса ARM7 будет выполнять
команды ARM (32-битные).
Набор команд можно сменить в любой
момент, используя команду ВХ или BLX.
При возникновении исключительной
ситуации процессор автоматически
переключается на 32-битный
набор команд ARM
Рис. 1.19. Переключение в режим ARM
В составе набора команд THUMB имеются более привычные команды работы
со стеком PUSH и POP (Рис. 1.20). С помощью этих команд реализуется нисходя-
щий стек, жестко привязанный к регистру R13.
Рис. 1.20. Команды PUSH и POP
31
Глава 1. Процессорное ядро ARM7
И, наконец, в наборе команд THUMB имеется команда SWI, работаю-
щая так же, как и аналогичная команда набора ARM, но содержащая только
8 неиспользуемых битов, что ограничивает максимальное число вызовов
SWI до 255.
Резюме
После прочтения этой главы вы должны иметь общее представление о про-
цессорном ядре ARM7. Книги, в которых ядро ARM7 рассматривается более под-
робно, приведены в списке литературы. Кроме того, на компакт-диске, прилага-
ющемся к книге, имеется копия полного руководства пользователя по ядру
ARM7 («ARM7 TDMI Technical Reference Manual»).
Глава 2
РАЗРАБОТКА ПРОГРАММНОГО
ОБЕСПЕЧЕНИЯ
Основные положения
В этой книге мы будем использовать интегрированную среду разработки
(ИСР) (Integrated Development Environment — IDE) компании Keil Elektronik, на-
зываемую ^VISION (произносится, как «мйкровижн»). В настоящее время су-
ществуют версии этой среды и для других популярных микроконтроллеров, в том
числе и для микроконтроллеров семейства 8051 (Intel) и семейства С16Х компа-
нии Infineon. В среде ^VISION интегрированы средства управления проектами,
редактор, компилятор и отладчик. Несмотря на то что в данной книге мы рас-
сматриваем только семейство LPC2000, программные средства для процессоров
ARM от компании Keil могут использоваться и для других микроконтроллеров,
построенных на базе ядра ARM7.
Какой из компиляторов?
Среда разработки pVISION может использоваться с различными компиля-
торами. Этими компиляторами являются ARM ADS, GNU, а также собствен-
ный компилятор Keil. Все примеры, приведенные в этой книге, написаны в
расчете на последний компилятор. Тем на менее, параллельно приводятся вер-
сии примеров для компилятора GNU, а в главе 6 подробно описываются раз-
личия между этими двумя компиляторами. Так какой же из компиляторов ис-
пользовать?! Прежде всего, необходимо отметить, что компилятор GNU явля-
ется бесплатным и его можно легко скачать из сети Интернет. Кроме того, он
имеется на компакт-диске, прилагающемся к книге. Так зачем же использо-
вать дорогостоящий коммерческий компилятор? Что ж, прежде чем присту-
пать к выполнению серьезного проекта, нелишне будет взглянуть на Табл. 2.1
и Табл. 2.2 с результатами тестов, сравнивающих наиболее популярные ком-
пиляторы языка Си для ЦПУ ARM.
Из таблиц видно, что коммерческие компиляторы на голову выше компиля-
тора GNU по плотности итогового кода и скорости выполнения программы. Ис-
ходя из результатов тестов, можно сделать следующие выводы: если вы хотите по-
лучить наиболее быстрый код и предпочитаете стандартные средства — исполь-
зуйте компилятор ARM, для достижения наибольшей плотности кода 33
Глава 2. Разработка программного обеспечения
Таблица 2.1. Dhrystone V2.1
Параметр Компилятор
KeilCA ВЕТА GNU V3.22 ARM ADS V1.2 IAR V4.11a
Время выполнения [мкс] 25.4 112.9 16.8 24.4
Быстродействие [циклов/с] 39370.1 8857.4 59382.4 40983.6
Размер кода [байт] 10330 36004 22266 19892
Размер стека [байт] 208 852 608 356
Размер данных [байт] 10256 11912 10256 10269
Примечание. Все тесты проводились в одинаковых условиях с использованием симулятора pVISION.
Симулировался микроконтроллер Philips LPC2294, работающий на частоте 60 МГц в
режиме THUMB.
Таблица 2.2. Whetstone
Параметр Компилятор
Keil СА ВЕТА GNU V3.22 ARM ADS V1.2 IAR V4.11a
Время выполнения [с] 0.195308 2.461430 0.268623 0.635633
Быстродействие [KWIPS] 5263 406 3846 1587
Размер кода [байт] 8492 44428 28516 16316
Размер стека [байт] 212 1552 710 488
Размер данных [байт] 72 1768 76 72
Примечание. Все тесты проводились в одинаковых условиях с использованием симулятора pVISION.
Симулировался микроконтроллер Philips LPC2294, работающий на частоте 60 МГц в
режиме THUMB.
используйте компилятор Keil, если же вы ограничены в средствах или у вас
простой проект — используйте компилятор GNU. Поскольку мы пишем про-
граммы для небольших однокристальных микроконтроллеров с ограниченными
аппаратными ресурсами, очевидно, что наилучшим выбором для нас будет ком-
пилятор Keil. При выборе пакета программ также важно проверить, насколько
полно в нем поддерживается конкретная реализация ядра ARM7. Несмотря на то
что пакет генерирует код для процессоров ARM7, он может не понимать, каким
образом это ядро используется в конкретной системе, например LPC2000. Ис-
пользование «чистого» ARM7 приведет к генерации кода, который будет выпол-
няться на LPC2000, однако при этом вам придется потратить время на написание
стартового кода и кода взаимодействия с отладчиком, который не имеет никакого
понятия о периферийных устройствах микроконтроллеров семейства LPC2000.
В результате процесс написания программы может превратиться в «борьбу» со
средствами разработки, не говоря уже о том, что эта борьба может оказаться со-
вершенно бесполезной.
Какой из компиляторов?
MCPpVISION
В составе среды pVISION имеется два средства отладки. Прежде всего, после
компиляции и компоновки программы ее код можно загрузить в симулятор
pVISION. Этот отладчик симулирует работу ядра ARM7 и периферийных уст-
ройств поддерживаемого микроконтроллера. Работа с симулятором — хороший
способ получить представление об устройствах семейства LPC2000. Поскольку
симулятор обеспечивает симуляцию работы ядра и периферии с точностью до
такта, он может оказаться очень полезным инструментом для проверки, коррект-
но ли был инициализирован микроконтроллер и правильно ли были вычислены
различные стартовые константы, например значения коэффициента деления
предделителей таймеров.
Однако рано или поздно вам потребуются реальные входные воздействия.
Иногда их можно сымитировать с помощью языка сценариев симулятора, но в
большинстве случаев придется запускать программу на реальном устройстве.
Клиентскую часть симулятора можно подключить к вашему устройству через
фирменный отладчик компании Keil — ULINK. К ПК кабель ULINK подключа-
ется через USB, а к устройству — через интерфейс JTAG микроконтроллера
LPC2000. Интерфейс JTAG является отдельным модулем ядра ARM7, который
поддерживает команды отладки, посылаемые хостом (ПК). Используя интерфейс
JTAG, можно из симулятора pVISION управлять работой микроконтроллера.
С его помощью можно загружать код в микроконтроллер, запускать программу в
пошаговом режиме или в режиме реального времени, устанавливать точки оста-
нова и просматривать содержимое памяти.
Учебное пособие
На компакт-диске, прилагающемся к книге, имеется демонстрационная
версия ИСР ^VISION компании Keil. В состав дистрибутива входят два ком-
пилятора — Keil ARM и GNU. В соответствующих главах рассматривается
множество учебных программ, которые демонстрируют основные возможнос-
ти микроконтроллеров семейства LPC2000. Эти программы можно запускать
в симуляторе, а если у вас имеется стартовый набор разработчика (Starter Kit),
то и на демонстрационной плате МСВ2100. На диске находятся две группы
примеров — для компиляторов Keil и GNU. Основная часть примеров в книге
рассчитана на компилятор Keil. Тем не менее, в главе 6 описывается работа с
компилятором GNU, а также подробно разбираются версии упражнений для
компилятора GNU (до 6-го упражнения включительно). При выполнении ос-
тальных упражнений можно использовать их описания в основном тексте
книги.
В конце каждого раздела книги приводятся упражнения, иллюстрирующие
рассматриваемые в данном разделе вопросы. Поэтому с книгой лучше всего рабо-
тать в следующей последовательности: сначала прочитать раздел, а затем перейти
к учебному пособию и выполнить упражнение. Если придерживаться этой схемы,
то к тому моменту, когда вы перевернете последнюю страницу книги, вы будете в
совершенстве знать ядро ARM7, средства разработки для него и микроконтролле-
ры семейства LPC2000.
35
Глава 2. Разработка программного обеспечения
Упражнение 1. Конфигурирование нового проекта
В нашем первом упражнении рассматривается процесс установки ПО ^Vision и на-
стройки нового проекта.
Стартовый код
В наш учебный проект будут входить несколько файлов с исходным текстом
программы. Фактически, весь исходный текст программы хранится в файлах с
расширением .с, а файл startup.s является ассемблерным модулем, содержащим
стартовый код, который предоставлен компанией Keil. Как следует из его на-
звания, стартовый код размещается в памяти микроконтроллера таким обра-
зом, чтобы запускаться при переходе по вектору сброса. В этом коде располага-
ется таблица векторов исключительных ситуаций, а также осуществляется ини-
циализация указателей стека различных режимов работы. Кроме того, прежде
чем передать управление написанной вами функции main(), в нем выполняется
инициализация некоторых периферийных модулей и встроенного ОЗУ. Старто-
вый код будет различным в зависимости от конкретного устройства и используемо-
го компилятора, поэтому при настройке проекта необходимо убедиться, что вы ис-
пользуете корректный файл. Модули со стартовым кодом для компилятора Keil
находятся в папке «C:\keil\ARM\startup», а для компилятора GNU — в папке
«С :\keil\GNU\startup».
Прежде всего, в стартовом коде размещается таблица векторов исключи-
тельных ситуаций, как показано ниже:
EXTERN CODE32 (Undef„Handler?А)
Объявление внешних extern CODE32 (SWl_Handler?A)
Си-подпрограмм обработки extern CODE32 (PAbt_Handler?A)
исключительных ситуаций. ___extern CODE32 (DAbt_Handler?A)
Суффикс ?А означает, что EXTERN CODE32 (!RQ_Handler?A)
в подпрограммах используется extern CODE32 (FlQ_Handler?A)
набор команд ARM
Неиспользуемый вектор, он потребуется нам позже/ Vectors: LDR LDR LDR LDR LDR ► NOP LDR LDR PC, Reset_Addr
PC, Undef_Addr
PC, SWI_Addr
PC, PAbt_Addr
PC, DAbt_Addr
/* Зарезервированный вектор */
PC, IRQ_Addr
PC, FIQ_Addr
Таблица конетбнт с адресами Reset_Addr: DD Reset_Handler
Undef_Addr: DD Unde f_Handler ?A
подпрограмм обработки ” SWI_Addr: DD SWI_Handler?A
прерываний PAbt_Addr: DD PAbt_Handler?A
DAbt_Addr: DD DD DAbt_Handler?A 0 /* Зарезервированный адрес */
IRQ_Addr: DD IRQ_Handler?A
FIQ_Addr: DD FIQ_Handler?A
36
Стартовый код
Таблица векторов располагается по адресу 0x00000000 и обеспечивает переход
к соответствующим подпрограммам обработки прерываний (ISR). Чтобы иметь
доступ ко всему адресному пространству процессора, используется команда LDR
(загрузка регистра). Эта команда загружает в счетчик команд константу из табли-
цы, расположенной сразу после таблицы векторов. Таким образом, таблица век-
торов и таблица констант занимают первые 64 байта памяти.
В микроконтроллерах семейства LPC2000 эти 64 байта могут быть отображены из
различных мест, в зависимости от режима работы LPC2000 (этот вопрос мы рас-
смотрим чуть позже). Вместо «отсутствующего» вектора по адресу 0x000000014
находится команда NOP Тем не менее, этот адрес используется загрузчиком
LPC2000 (тоже обсуждается позже). Управление содержимым таблицы векторов
ложится на ваши плечи, поскольку компилятор не может заполнить таблицу ав-
томатически.
Кроме того, в стартовом коде осуществляется инициализация указателей сте-
ка для каждого из режимов работы*
Шесть внутренних указателей стека (R13)
устанавливаются на верхнюю область памяти микроконтроллера.
Следует внимательно подойти к вопросу выделения
достаточного объема памяти для каждого стека
\>
// Конфигурируем стек для каждого режима
LDR RO, =Top_Stack
// Переключаемся в режим Undefined Instruction
//и инициализируем его стек
Меняем режим и запрещаем прерывания —• Загружаем адрес в указатель стека 1 Вычисляем стартовый адрес стека 1 следующего режима В конце переходим в режим USER 1 и разрешаем прерывания Проверяем, какой из наборов команд (ARM или THUMB) используется \ Загружаем адрес выхода в регистр связи 1 Переходим к Си-подпрограмме 1 инициализации ► MSR CPSR_c, #Mode_UND|I_Bit|F_Bit ► MOV SP, RO ► SUB RO, RO, #UND_Stack_Size // Переключаемся в режим Abort и инициализируем // его стек MSR CPSR_c, #Mode_ABTII_BitIF_Bit MOV SP, RO SUB RO, RO, #ABT_Stack_Size // Стеки режимов FIQ, IRQ и Supervisor // Переключаемся в режим USER и // инициализируем его указатель стека ► MSR CPSR_c, #Mode_USR MOV SP, RO // Переходим к Си-программе LDR R0,=?C?INIT TST R0,#l ; Бит 0 установлен: ; INIT - THUMB ► LDREQ LR,=exit?A ; Режим ARM LDRNE LR,=exit?T ; Режим Thumb ► BX RO
Глава 2. Разработка программного обеспечения
Поскольку в каждом режиме работы имеется уникальный регистр R13,
в процессоре ARM7 присутствует шесть стеков. Компилятор размещает пе-
ременные пользователя, начиная с первого адреса встроенного ОЗУ в на-
правлении старших адресов. Стеки же размещаются в старших адресах
ОЗУ и заполняются в направлении младших адресов. В стартовом коде
происходит последовательное переключение в различные режимы ARM7,
и в каждый из регистров R13 загружается начальный адрес соответствую-
щего стека (Рис. 2.1).
upcion
Б Stack Configuration (Stack Sizes in Bytes)
Undefined Mode
Supervisor Mode
Abort Mode
? Fast Interrupt Mode
Interrupt Mode
; User/System Mode
i- PLL Setup
03 MAM Setup
g External Memory Controller (EMC)
I vaiue
0x0000 0004
0x0000 0004
0x0000 0004
0x0000 0004
0x0000 0080
0x0000 0400
P
F
P
Рис. 2.1. Окно редактора
Как и в случае таблицы векторов прерываний, задание размера стеков ложит-
ся на ваши плечи. В принципе, это можно сделать, непосредственно изменяя код
стартового модуля, однако в составе ИСР предусмотрен специализированный ре-
дактор, позволяющий управлять параметрами стеков в графическом виде. Более
того, этот графический редактор позволяет конфигурировать ряд системных пе-
риферийных модулей LPC2000. Позже мы рассмотрим этот вопрос более подроб-
но, но не забывайте, что их можно конфигурировать путем непосредственного
изменения стартового кода.
Упражнение 2. Стартовый код
Во втором упражнении рассматривается процесс выделения памяти под каждый из
стеков процессора.
Взаимодействие кода ARM и THUMB
Один из наиболее важных вопросов, которые должны быть решены в нашей
программе, — взаимодействие между наборами команд ARM и THUMB. Для
обеспечения такого взаимодействия компанией ARM был разработан стандарт
«ARM THUMB Procedure Call Standard» (ATPCS). Помимо всего прочего, этот
стандарт определяет, каким образом производится вызов одних функций из
других, порядок передачи параметров и использование стеков (Рис. 2.2). При
использовании стандарта APCS к коду функций добавляется своеобразная
«обертка» на языке ассемблера, благодаря которой обеспечивается поддержка
38
Взаимодействие кода ARM и THUMB
различных возможностей компилятора. Чем больше этих возможностей вы ис-
пользуете, тем больше получается количество дополнительного кода. Теорети-
чески, стандарт APCS обеспечивает совместную работу кода, созданного раз-
личными пакетами программ. То есть вы можете взять библиотеку, скомпили-
рованную каким-либо компилятором, и использовать ее совместно с пакетом
компании Keil.
Передаваемые параметры
Локальные переменные
Рабочий регистр
Регистр стека
Регистр связи
Счетчик команд
Стандарт A PCS определяет порядок
использования компилятором
пользовательских регистров ЦПУ.
Соблюдение этого стандарта
обеспечивает взаимодействие между
инструментальными средствами
различных производителей
Рис. 2.2. Порядок использования
пользовательских регистров
Согласно стандарту APCS регистровый файл делится на несколько облас-
тей. Регистры R0...R3 используются для передачи параметров в подпрограм-
мы. Если необходимо передать больше 16 байт, то остальные параметры пере-
даются через стек. Локальные переменные размещаются в регистрах R4...R11,
а регистр R12 резервируется для хранения адреса промежуточного интерфейс-
ного кода. В компиляторе Keil весь код создается с учетом дальнейшего взаи-
модействия, а набором команд по умолчанию является набор команд
THUMB. Таким образом, вся программа будет скомпилирована с использова-
нием команд THUMB (за исключением обработчиков прерываний, для кото-
рых по умолчанию используется набор команд ARM). Такое поведение ком-
пилятора можно изменить. Вызовите через меню Options for Target диалог ус-
тановки параметров проекта (Рис. 2.3) и на вкладке С снимите флажок Use
THUMB code. В результате набором команд, используемым по умолчанию,
станет набор команд ARM.
Кроме того, программист может явно указать, с использованием какого набо-
ра команд должна быть скомпилирована та или иная функция. Для этого предна-
значены две директивы #pragma ARM и #pragma THUMB, использование которых
показано ниже. В этом примере основная функция компилируется с использова-
39
Глава 2. Разработка программного обеспечения
Options for Target 'МАМ* [Х]
Device) Target | Output) Listing C | Asm | LA Misc | LA Locate | Debug) Utilities |
Preprocessor Symbols
Define:
Undefine:
Code Optimization
Level: |6. Common tail merging
Emphasis:
(Favor code size|
P Use Thumb Mode
Warnings: | Warninglevel 2
p treat plain char as 'unsigned char'
P Alias checking on pointer accesses
Include
Paths
Misc
Controls
Compiler
control
string
THUMB OPTIMIZE (SIZE) BROWSE DEBUG TABS (4)
| OK| Отмена | Defaults |
Справка |
Рис. 2.3. Установка параметров проекта
нием набора команд ARM и вызывает функцию THUMB_function (как легко до-
гадаться, последняя скомпилирована с использованием 16-битного набора ко-
манд THUMB).
#pragma ARM // Переключаемся на набор команд ARM
int main(void)
{
while(1)
{
THUMB_function(); // Вызываем THUMB-функцию
}
}
#pragma THUMB // Переключаемся на набор команд THUMB
void THUMB_function(void)
{
unsigned long i,delay;
for (i = 0x00010000;i < 0x01000000 ;i = i«l) // Мигалка
{
for (delay = 0;delay<0x000100000;delay++) // Простой цикл задержки
{
}
IOSET1 = i;
}
// Указываем на следующий СИД
40 }
Библиотека STDIO
Помимо этого, любую функцию можно описать как ARM- или
THUMB-функцию, используя следующие объявления прототипа функ-
ции:
int ARM-FUNCTION ( int my_var) _ARM
{
}
int THUMB-FUNCTION ( int my_var) _THUMB
{
}
Упражнение 3. Обеспечение взаимодействия
В третьем упражнении рассматривается настройка проекта, в котором осуществ-
ляется взаимодействие между кодом ARM и THUMB.
Библиотека STDIO
Функции форматного ввода/вывода высокого уровня библиотеки STDIO,
такие как printf() и scanf(), используют модуль UART0 микроконтроллеров
LPC2000. Корректное задание скорости передачи модуля является задачей
программиста. После соответствующей инициализации модуля эти функции
высокого уровня можно использовать, к примеру, для передачи данных терми-
нальной программе на ПК. Для передачи и приема одиночных символов в/из
стандартного устройства (в данном случае UART) в библиотеке STDIO исполь-
зуются две низкоуровневые функции. Эти функции называются putchar() и
getchar(), а их исходный код находится в файле serial.c в директории lib. Если
присоединить этот файл к своему проекту, то библиотека, используемая ком-
пилятором по умолчанию, будет игнорироваться, а вместо нее будет использо-
ваться код из файла serial.c. Таким образом, модифицируя подпрограммы
putchar() и getchar(), можно перенаправить функции высокого уровня printf() и
scanf() на любое устройство ввода/вывода, которое вы собираетесь использо-
вать, такое как ЖК индикатор и клавиатура. Имейте в виду, что функции вы-
сокого уровня библиотеки STDIO довольно ресурсоемкие и их использование
оправдано только в том случае, если в приложении осуществляется интенсив-
ный ввод/вывод данных.
Упражнение 4. Библиотека STDIO
В этом упражнении рассматриваются подпрограммы низкого уровня, используемые
функциями printf() и scanf(), которые модифицируются для выполнения операций
чтения/записи с использованием встроенного модуля UART.
41
Глава 2. Разработка программного обеспечения
Организация доступа
к периферийным устройствам
После того как мы напишем и отладим некоторую часть программы, нам в ка-
кой-то момент времени потребуется обращаться к регистрам специальных функ-
ций (РСФ, или SFR) периферийных устройств. Поскольку все периферийные
устройства отображены на память данных, эти регистры можно рассматривать
как обычные ячейки памяти. Таким образом, к любому РСФ можно обращаться
посредством «фиксированного» volatile-указателя на занимаемую этим регистром
ячейку памяти:
#defineSFR (*((volatile unsigned long *) OxFFFFFOOO))
Вместе с компилятором Keil поставляется набор включаемых файлов, в кото-
рых определяются РСФ для различных моделей микроконтроллеров LPC2000.
Включив соответствующий файл в программу, вы сможете напрямую обращаться
из нее к РСФ периферийных устройств. Все включаемые файлы имеют имена
вида:
LPC21xx.h
LPC22xx.h
LPC210x.h
Подпрограммы
обработки прерываний
Помимо обращения к встроенным периферийным устройствам микроконт-
роллеров, в ваших программах будет осуществляться обслуживание запросов на
прерывание. Превратить обычную функцию в подпрограмму обработки прерыва-
ния можно следующим способом:
void fiqint(void) ____fig
{
IOSET1 = OxOOFFOOOO;
EXTINT = 0x00000002;
}
// Включить СИД
// Сбросить флаг прерывания
Ключевое слово__fiq указывает на то, что эта функция является подпрограм-
мой обработки быстрого прерывания (FIQ) и в ней будет использован соответ-
ствующий механизм возврата. Поддержка других прерываний осуществляется с
помощью ключевых слов___irq,_swi,__abort.
Помимо объявления Си-функции в качестве подпрограммы обработки пре-
рывания, вы должны связать ее с вектором прерывания.
Подпрограммы обработки прерываний
Vectors: LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
NOP /* Зарезервированный вектор */
LDR PC,IRQ_Addr
LDR PC,[PC, #-OxOFFO] /* Вектор из VicVectAddr */
LDR PC,FIQ_Addr
Reset.Addr: DD Reset_Handler
Undef_Addr : DD Undef_Handler?A
SWI_Addr: DD SWI_Handler?A
PAbt_Addr: DD PAbt_Handler?A
DAbt_Addr: DD DAbt_Handler?A
DD 0 k Зарезервированный адрес*/
IRQ_Addr: DD IRQ_Handler?A
FIQ Addr: DD FIQ Handler?A
Таблица векторов прерываний состоит из двух частей. Первая из них физи-
чески является таблицей векторов, в которой по каждому вектору находится ко-
манда загрузки регистра (LDR). Эта команда загружает содержимое 32-битной
ячейки памяти в счетчик команд, осуществляя тем самым переход в пределах все-
го адресного пространства процессора. Эти значения хранятся во второй части,
называемой также таблицей констант, которая располагается сразу же за табли-
цей векторов. Таким образом, вся таблица векторов прерываний занимает первые
64 байта памяти. В модуле стартового кода для компилятора Keil используются
предопределенные имена подпрограмм обработки прерываний. Поэтому, чтобы
связать свою подпрограмму обработки прерываний с каким-либо вектором,
достаточно объявить ее с предопределенным именем, сопоставленным данному
вектору. Ниже приведены идентификаторы, хранящиеся в таблице констант, и
соответствующие им прототипы функций на языке Си.
Источник исключения Таблица констант
Неопределенная Unde f_Handler?A
команда
Сбой выборки PAbt_Handler?A
Сбой данных DAbt_Handler?A
Быстрое прерывание FIQ_Handler?A
Прототип Си-функции
void Undef_Handler(void) ___abort
void Pabt_Handler(void) abort
void Dabt_Handler(void) abort
void FIQ_Handler(void) ___fiq
Как мы увидим позже, исключительные ситуации SWI и IRQ требуют особен-
ного отношения. Суффикс ?А указывает компоновщику, что данная функция
должна быть скомпилирована с использованием набора команд ARM. Для указа-
ния набора команд THUMB используется суффикс ?Т. Из всех источников пре-
рываний запретить можно только прерывания FIQ и IRQ. Исключительные ситу-
ации защищенного режима («Undefined Instruction», «Prefetch Abort» и «Data
43
Глава 2. Разработка программного обеспечения
Abort») всегда разрешены, поэтому их всегда необходимо обрабатывать. Если вы
не объявите обработчик для какого-либо из этих источников прерываний, то для
его перехвата компилятор автоматически создаст обработчик, содержащий бес-
конечный цикл.
Pabt_Handler:
В Pabt Handler
Обработчик исключительной ситуации, используемый
по умолчанию (если для нее не была объявлена Си-функция)
Упражнение 5. Обработка исключительной ситуации
В этом упражнении мы напишем простейшую подпрограмму обработки прерывания
и исследуем ее выполнение в отладчике. Позже мы рассмотрим, как следует конфи-
гурировать LPC2000 для обслуживания прерываний.
Программное прерывание
Исключительная ситуация «программное прерывание» представляет особый
случай. Как мы уже говорили, в неиспользуемых битах слова команды SWI можно
закодировать целое число.
#define SWIcall2 asm{ swi #2 }
Однако в компиляторе Keil поддержка программных прерываний реализова-
на более изящно. Подпрограмму обработки программного прерывания можно
объявить с использованием следующего ключевого слова (не соответствующего
стандарту ANSI):
int Syscall2(int pattern) _swi(2)
{
}
Кроме того, в проект должен быть включен ассемблерный файл SWIVEC.S.
Теперь при вызове функции командой SWI процессор будет переходить в при-
вилегированный режим Supervisor и выполнять код, содержащийся в файле
SWI VEC.S. Этот код определяет, какая из функций была вызвана и обеспечивает
передачу необходимых параметров. Такой механизм существенно облегчает ис-
пользование структуры исключительных ситуаций процессора ARM7 и разби-
ение кода на второстепенный, выполняющийся в режиме User, и критический,
такой как BIOS или функции операционной системы. В учебном пособии этот
вопрос рассматривается более подробно.
Упражнение 6. Программное прерывание
В этом упражнении демонстрируется поддержка компилятором Keil программных
прерываний. Вы можете легко разбить свою программу на секции, часть которых бу-
дет выполняться в режиме User, а часть — в режиме Supervisor.
44
Размещение кода в ОЗУ
Размещение кода
в ОЗУ
Как мы увидим позже, самым узким местом в ЦПУ ARM7, ограничиваю-
щим его производительность, является выборка исполняемых команд из
FLASH-памяти. В микроконтроллерах семейства LPC2000 имеется специаль-
ный модуль для решения этой проблемы при использовании встроенной
FLASH-памяти. Однако, если ваша программа хранится во внешней FLASH-
памяти, вы в буквальном смысле завязнете в ней из-за ее большого времени
доступа. Одним из способов решения этой проблемы является перегрузка ис-
полняемого кода в быстродействующее ОЗУ и последующее выполнение дан-
ного кода из ОЗУ. Для этого вам нужно будет скомпилировать либо перемести-
мый код, который можно скопировать в ОЗУ, либо код, который можно запус-
кать из ОЗУ и который загружается туда отдельной программой-загрузчиком.
Оба этих решения будут работать, однако для их реализации придется прило-
жить дополнительные усилия. К счастью, компилятор Keil позволяет явно оп-
ределять функцию как размещаемую в ОЗУ. При выполнении стартового кода
такая функция будет скопирована в ОЗУ, и все вызовы этой функции будут на-
правлены компоновщиком в определенную область ОЗУ. Такие функции объ-
являются следующим образом:
int RAM_FUNCTION (int my_var) _ram
{
}
Кроме того, необходимо указать, какая из секций памяти будет использо-
ваться для хранения таких функций. Для этого определенная секция ОЗУ объ-
является как исполняемое ОЗУ (ERAM). В этом объявлении используется ди-
ректива задания класса памяти, которая выделяет участок ОЗУ под подобные
функции.
Директива имеет следующий синтаксис:
ERAM (0x40000000-0x40000FFF)
Ее необходимо ввести в поле User classes на вкладке LA Locate диалога уста-
новки параметров проекта (Рис. 2.4).
Обратите внимание, что компилятор никак не контролирует ситуацию, при
которой ваша подпрограмма в ОЗУ вызывает другие, не находящиеся в ОЗУ По-
этому если ваша «быстрая» функция вызывает подпрограмму математической
библиотеки, находящуюся в FLASH-памяти, то вы можете не получить ожидае-
мого быстродействия. Указанный способ размещения подпрограмм в ОЗУ не
только прост и легок в использовании, он еще и облегчает работу компоновщику,
т.к. последний знает итоговое место размещения подпрограммы и может размес-
тить отладочную информацию по корректному адресу. В результате мы получим
автономно выполняемый образ, пригодный не только для записи в ПЗУ, но и для
отладки.
45
Глава 2. Разработка программного обеспечения
Рис. 2.4. Вкладка LA Locate
Встраиваемые функции
Увеличения производительности программы можно достичь также, используя
встраиваемые функции (inlining). Любую функцию можно сделать встраиваемой,
указав при ее объявлении ключевое слово_inline:
void NoSubroutine(void) _inline
{
}
Если функцию объявить подобным образом, то подпрограммы как таковой
создано не будет, вместо этого везде, где вызывается функция, будет вставлен ее
код. При этом не потребуется выполнять код входа в подпрограмму и выхода из
нее, что ускорит выполнение функции. Однако, поскольку код функции дублиру-
ется при каждом вызове, такое решение приводит к большим затратам FLASH-
памяти.
46
Поддержка операционных систем
Поддержка операционных систем
Если в микроконтроллере используется операционная система, она, как пра-
вило, сама заботится о системных стеках и переключении контекста. Чтобы избе-
жать дублирования этих операций компилятором, можно определить функцию
как задачу операционной системы. Это приведет к тому, что компилятор будет
просто транслировать код функции, не добавляя к нему обычный код входа в
подпрограмму и выхода из нее, обеспечивающий сохранение регистров в стеке и
их восстановление. Объявить функцию как задачу операционной системы можно
следующим образом:
void Analoguesample(void) _task
{
}
Размещение объектов
по фиксированным адресам
Компилятор позволяет также размещать любой из объектов Си-программы,
например переменную или функцию, по любому абсолютному адресу в памяти.
Для этого используется следующее расширение языка Си:
int checksum_at 0x40000000;
Переменные, объявленные таким образом, не могут быть инициализированы
в стартовом коде. Кроме того, необходимо следить за корректным выравнивани-
ем переменных, в противном случае возникнет ошибка обращения к памяти (на-
пример, если целое число будет размещено по четному адресу).
Встроенный ассемблер
Компилятор также позволяет вставлять ARM- и THUMB-команды ассембле-
ра непосредственно в программы на языке Си. Для этого используется следующее
выражение:
_asm {mov rl5,r2}
Это может пригодиться в том случае, если вам требуется выполнить какие-ли-
бо действия, не поддерживаемые языком Си, например команды MRS и MSR.
Аппаратные средства отладки
При разработке семейства LPC2000 компания Philips позаботилась о наличии
в микроконтроллерах семейства как можно более полной поддержки отладки.
Причем эта поддержка осуществляется на нескольких уровнях. Самый простой 47
Глава 2. Разработка программного обеспечения
уровень — порт отладки по интерфейсу JTAG. С его помощью можно подключить
микроконтроллер к ПК для проведения сеанса отладки (Рис. 2.5). Интерфейс
JTAG предоставляет базовые средства управления функционированием кристал-
ла. Так, вы можете пошагово выполнять программу, запускать и приостанавли-
вать ее выполнение в реальном времени, устанавливать точки останова, а также
просматривать при останове программы значения переменных и ячеек памяти.
Рис. 2.5. Подключение микроконтроллера к ПК для отладки
Кроме того, в составе микроконтроллеров семейства имеется модуль встроен-
ной трассировки (ЕТМ) от компании ARM (Рис. 2.6). Этот модуль предоставляет
гораздо более развитые средства отладки и трассировки в реальном времени, ис-
следования кода программы и анализа эффективности. Помимо использования
расширенных средств отладки, модуль ЕТМ позволяет выполнять подробную ве-
рификацию кода и углубленное тестирование программного обеспечения, что
невозможно сделать при использовании простого интерфейса JTAG. Это особен-
но важно в том случае, если вы разрабатываете приложения, для которых безо-
пасность является критическим фактором.
TDO —
TMS —
ТСК —
RTCK —
TDI —
RST —
Помимо порта JTAG, в микроконтроллерах фирмы Philips
имеется модуль ЕТМ, позволяющий использовать
развитые отладочные средства
— PIPESTATE О
— PIPESTATE 1
— PIPESTATE 2
— TRACESYNC
— TRACEPKT О
— TRACEPKT 1
— TRACEPKT 2
— TRACEPKT 3
— VcC2
— Vcci
— EXTTRIG
— DBGACK
— TRACECLK
48
Puc. 2.6. Модуль ЕТМ
Аппаратные средства отладки
Последним из встроенных отладочных средств является монитор реального
времени (Real Time Monitor). Он представляет собой код, постоянно находящийся
в зарезервированной области памяти. Во время сеанса отладки отладчик может за-
пустить этот монитор через интерфейс JTAG. Монитор реального времени можно
использовать для внесения изменений «на ходу», в процессе выполнения про-
граммы. На самом деле этот процесс не является процессом реального времени,
поскольку монитор прерывает выполнение прикладной программы. Кроме того,
ему требуется время для считывания и передачи отладочной информации на ПК.
Важное замечание!
Отладочные интерфейсы JTAG и ЕТМ представляют собой довольно «тупые»
средства отладки ядра ARM7 по последовательному каналу. Инструментальные
средства ARM общего назначения, использующие интерфейс JTAG, не имеют
никакого понятия обо всей архитектуре микроконтроллеров семейства LPC2000.
Это означает, что при их использовании после сброса микроконтроллера всегда
будет запускаться загрузчик, поскольку они не записывают в FLASH-память так
называемую «сигнатуру программы» (эта особенность микроконтроллеров се-
мейства будет обсуждаться позже). Соответственно, при их использовании ваша
программа никогда не запустится. Если вы только начинаете изучать микроконт-
роллеры семейства LPC2000, такое поведение программ элементарно может по-
ставить вас в тупик. Поскольку программные средства компании Keil разрабаты-
ваются специально для микроконтроллеров общего назначения с ядром ARM7, в
ИСР Micro Vision (pVISION) заложена информация об архитектуре памяти се-
мейства LPC2000, поэтому отладка будет осуществляться безо всяких проблем.
Еще более важное замечание!
Как уже было отмечено, порт JTAG является простым средством отладки ядра
ARM7 по последовательному каналу. Очень важно хорошо представлять себе его
поведение при сбросе. Когда ЦПУ ARM7 находится в состоянии сброса, все пе-
риферийные модули, включая модуль JTAG, тоже сброшены. При этом отладчик
ULINK теряет контроль над кристаллом и должен восстановить его после того,
как микроконтроллер выйдет из состояния сброса. Для этого потребуется опреде-
ленное количество тактов. Все это время программа, содержащаяся в устройстве,
будет выполняться в нормальном режиме. Как только отладчик перехватывает
управление кристаллом, он выполняет программный сброс (soft reset) путем об-
нуления счетчика команд. Однако встроенные периферийные устройства микро-
контроллера уже не находятся в состоянии сброса, т.е. периферия к этому момен-
ту будет уже проинициализирована, прерывания разрешены и т.д. Вы должны
учитывать это обстоятельство, если такое поведение микроконтроллера может
воспрепятствовать нормальному функционированию разрабатываемой вами
программы. Простейшим решением указанной проблемы будет вставка цикла за-
держки в стартовый код или в начало функции main(). После сброса ЦПУ будет
«висеть» в этом цикле до тех пор, пока ULINK не восстановит контроль над крис-
таллом. При этом собственно приложение выполняться не будет, т.е. микроконт-
роллер останется в инициализированном состоянии.
49
Глава 2. Разработка программного обеспечения
Резюме
Итак, после прочтения этой главы вы должны уметь выполнять настройку
проекта в ИСР pVision компании Keil, указывать используемый компилятор и ис-
пользуемую модель микроконтроллера, конфигурировать стартовый код, обеспе-
чивать взаимодействие между наборами команд ARM и THUMB, обращаться к
периферийным устройствам микроконтроллеров семейства и объявлять Си-
функции, являющиеся обработчиками исключительных ситуаций. Обладая эти-
ми знаниями, мы можем приступить к изучению системных периферийных уст-
ройств микроконтроллеров семейства LPC2000.
Глава 3
СИСТЕМНЫЕ
ПЕРИФЕРИЙНЫЕ УСТРОЙСТВА
Основные положения
Теперь, когда мы в какой-то степени познакомились с ядром ARM7 и необхо-
димыми средствами разработки для него, можно приступить к изучению соб-
ственно микроконтроллеров семейства LPC2000. Основное внимание в этой гла-
ве уделено системной периферии, т.е. модулям, определяющим быстродействие и
функциональные характеристики устройств. К системной периферии относятся
встроенные FLASH-память и ОЗУ, интерфейс внешней шины, имеющийся в мо-
делях LPC22xx, схема ФАПЧ, используемая для умножения частоты сигнала
внешнего генератора и обеспечивающая формирование тактового сигнала про-
цессора частотой до 60 МГц, а также средства управления электропитанием. А в
конце главы, прежде чем приступить к подробному изучению исключительных
ситуаций, мы познакомимся с простейшим источником пользовательских пре-
рываний — выводами внешнего прерывания.
Внутренние шины
С точки зрения программиста, память любого из устройств семейства
LPC2000 представляет собой непрерывное 32-битное адресное пространство. Од-
нако на самом деле внутри устройства имеется несколько шин (Рис. 3.1). Ядро
ARM7 подключено к усовершенствованной высокопроизводительной шине
(Advanced High performance Bus — АНВ), разработанной компанией ARM. Как
следует из названия шины, она обеспечивает наибольшую скорость обмена меж-
ду периферийными устройствами и ядром ARM7. К этой шине подключен век-
торный контроллер прерываний и специальный мост к второй шине, называемой
периферийной шиной СБИС (VLSI Peripheral Bus — VPB). Векторный контрол-
лер прерываний управляет всеми источниками прерываний устройства, именно
поэтому он подключается к ядру ARM7 через самую быструю шину.
Остальные периферийные модули подключены к шине VPB. В составе моста
VPB имеется делитель частоты тактового сигнала, поэтому шина VPB может ра-
ботать медленнее, чем ядро ARM7 и шина АНВ. Это полезно по двум причинам.
Во-первых, мы можем запускать пользовательскую периферию на частоте, кото- 51
Глава 3. Системные периферийные устройства
Рис. 3.1. Внутренние шины LPC2000
рая ниже частоты основного процессора, для уменьшения потребляемой мощ-
ности. Во-вторых, такое решение позволяет компании Philips внедрять в микро-
контроллеры семейства более медленную периферию, избегая при этом образо-
вания узкого места на шине АНВ. В настоящее время все встроенные
периферийные модули могут работать на частоте 60 МГц, так что частота шины
VPB может быть задана равной частоте шины АНВ. Необходимо отметить, что
после сброса делитель частоты шины VPB устанавливается в режим деления на
четыре, т.е. тактовая частота всех периферийных модулей будет равна 1/4 такто-
вой частоты ЦПУ.
И в завершение упомянем третью локальную шину, которая используется
для подключения встроенных FLASH-памяти и ОЗУ к ЦПУ. Разумеется, память
программ и данных можно было бы подключить к ЦПУ через шину АНВ, однако
в этом случае выполнение программы периодически приостанавливалось бы из-
за конфликтов на шине. Использование отдельных локальных шин исключает
возможность возникновения подобных задержек, обеспечивая более высокую
производительность процессора.
Организация памяти
Несмотря на наличие нескольких внутренних шин, в семействе LPC2000 ис-
пользуется линейное адресное пространство. В общем виде распределение памя-
ти показано на Рис. 3.2.
Встроенная FLASH-память располагается, начиная с адреса 0x00000000,
а пользовательское ОЗУ — с адреса 0x40000000. При изготовлении микро-
контроллеров семейства в них записывается программа загрузчика FLASH-
памяти, а также программа управления монитором реального времени. Эти
программы размещаются в диапазоне 0x7FFFFFFF...0x80000000. Область адресов
0x80000000...ОхЕООООООО зарезервирована для внешней памяти. В настоящее вре-
мя микроконтроллеры моделей LPC22xx могут адресовать до 64 Мбайт внешней
52 памяти (4 страницы по 16 Мбайт).
Организация памяти
4.0 GB
3.75 GB
3.5 GB
3.0 GB
2.0 GB
1.0 GB
0.0 GB
Периферия AHB
Периферия VPB
Зарезервировано
для внешней памяти
Загрузчик
Зарезервировано
для встроенной памяти
Встроенное
статическое ОЗУ
Зарезервировано
для регистров
специальных функций
Зарезервировано
для встроенной памяти
Встроенная
энергонезависимая
память
Периферия АНВ
Зарезервировано
Зарезервировано
Периферия VPB
OxFFFFFFFF
OxFOOO 0000
ОхЕООО 0000
0x0000 0000
0x8000 0000
0x4000 0000
Ox3FFF 8000
0x0000 0000
Адресное пространство LPC2000
разделено на несколько частей,
предназначенных для встроенной
FLASH-памяти, пользовательского
статического ОЗУ,
предустановленного загрузчика,
внешней шины и пользовательской
периферии
Рис. 3.2. Организация памяти LPC2000
Рис. 3.3. Регистры периферийных устройств
Все пользовательские
периферийные
устройства
подключаются
к шине VPB.
Для регистров
каждого устройства
выделяется диапазон
адресов размером 16К
53
Глава 3. Системные периферийные устройства
Все пользовательские периферийные устройства, подключенные к шине VPB,
отображены на область памяти с адресами 0хЕ0000000...0хЕ0200000, при этом
каждому устройству отводится страница размером 16 Кбайт (Рис. 3.3). Регистры
векторного контроллера прерываний размещаются в старших адресах, начиная с
адреса OxFFFFFOOO.
Если пользовательская программа пытается обратиться к памяти, находящей-
ся вне указанных диапазонов адресов, или же к отсутствующей памяти в пределах
этих адресов, то ЦПУ сгенерирует исключительную ситуацию Abort. Этот меха-
низм жестко заложен в конструкцию процессора, и его нельзя ни изменить, ни
отключить.
Программирование регистров
Прежде чем приступить к изучению блока управления системой, необходимо
понять, каким образом в кристаллах на базе ARM7 осуществляется изменение ре-
гистров специальных функций, или РСФ (Special Function Registers — SFR).
Как правило, управление всеми регистрами
специальных функций, унаследованных
от компании ARM, осуществляется
с помощью трех регистров: регистра
установки (Set), регистра сброса (Clear)
и регистра статуса (Status)
Примечание. Чтобы сбросить бит, следует
записать лог. 1 в соответствующий бит
регистра сброса
110 0 РСФ
Рис. 3.4. Управление регистрами
специальных функций
Каждый базовый РСФ управляется тремя пользовательскими регистрами
(Рис. 3.4). Регистр установки используется для установки битов РСФ, регистр
сброса — для сброса битов путем записи лог. 1 в сбрасываемые биты РСФ, а ре-
гистр статуса — для считывания текущего содержимого регистра. Наиболее рас-
пространенной ошибкой, которую допускают программисты, впервые столкнув-
шиеся с микроконтроллерами LPC2100, является запись лог. 0 в регистр сброса
(эта операция совершенно бесполезна).
54
Модуль ускорения работы памяти
Модуль ускорения работы памяти
Модуль ускорения работы памяти (Memory Accelerator Module — МАМ) явля-
ется ключевым фактором, обеспечивающим высокую скорость выполнения ко-
манд в микроконтроллерах семейства LPC2000. Модуль МАМ подключается к
локальной шине ЦПУ ARM7 и размещается между ним и FLASH-памятью
(Рис. 3.5).
Рис. 3.5. Подключение модуля ускорения работы памяти
Одним из основных ограничивающих факторов, препятствующих созданию
высокопроизводительных однокристальных микроконтроллеров на базе ядра
ARM7, является довольно большое время доступа к встроенной FLASH-памяти.
Процессор ARM способен работать на частотах до 80 МГц, однако время доступа
к встроенной FLASH-памяти составляет целых 50 нс. Соответственно уже одно
только использование FLASH-памяти ограничивает частоту тактового сигнала на
уровне 20 МГц (что в четыре раза меньше максимальной тактовой частоты про-
цессора). Существует несколько путей решения этой проблемы. Самый простой
заключается в загрузке критических секций программы в ОЗУ и запуск их уже от-
туда. Поскольку ОЗУ имеет гораздо меньшее время доступа, общая производи-
тельность намного увеличится. Недостаток такого решения заключается в том,
что встроенное ОЗУ является ограниченным и ценным ресурсом. Использование
ОЗУ для хранения команд существенно ограничивает размер создаваемых про-
грамм. Другой способ заключается в использовании встроенного кэша. Кэшем
называется область памяти небольшого размера, расположенная между процес-
сором и основной памятью, где хранится содержимое участков основной памяти,
к которым обращались в последний раз. В случае правильно спроектированного
кэша процессор будет использовать его, где только возможно, уменьшая, таким
образом, влияние медленной памяти. Однако полнофункциональный кэш явля-
ется сложным периферийным устройством, для реализации которого требуется
огромное количество логических элементов и соответственно значительная часть
площади кристалла микроконтроллера. Это противоречит основной идее ядра
ARM7 — простоте. Другим недостатком использования полнофункционального
кэша является непредсказуемость времени выполнения кода, использующего 55
Глава 3. Системные периферийные устройства
данный кэш. Соответственно этот способ нельзя использовать в приложениях,
которые должны быть предсказуемыми и повторяемыми.
Модуль МАМ (Рис. 3.6) является компромиссом между сложностью полно-
функционального кэша и простотой прямого доступа к FLASH-памяти.
Вся FLASH-память организована
в виде двух перемежающихся
128-битных банков памяти.
При одном обращении
к FLASH-памяти модуль МАМ
загружает четыре команды ARM
или восемь команд THUMB,
которые затем выполняются
процессором
Рис, 3.6, Работа модуля МАМ
Подобно кэшу, модуль МАМ пытается своевременно обеспечить в своей ло-
кальной памяти наличие следующей команды ARM, которую должен будет вы-
полнить ЦПУ. Для этого вся FLASH-память разбивается на два банка, доступ к
которым может осуществляться независимо. Это означает, что при одном обра-
щении к FLASH-памяти загружается четыре команды ARM или восемь команд
THUMB. Код программы распределяется между двумя банками таким образом,
чтобы при выполнении линейного кода одновременно осуществлялось выполне-
ние команд, считанных модулем МАМ из одного банка, и предварительная вы-
борка следующего 128-битного блока команд из другого. За счет этого гарантиру-
ется, что к моменту завершения предыдущих 128 бит кода указанные команды бу-
дут готовы к выполнению. Данная методика достаточно действенна в случае
команд ARM, которые для «сглаживания» коротких переходов могут использо-
вать условное выполнение, чтобы получить максимально возможную линейность
кода. Для поддержки коротких циклов и переходов в модуле МАМ предусмотре-
ны специальные буферы, где хранятся последние загруженные команды, которые
при необходимости можно выполнить повторно.
Вся эта сложная структура модуля МАМ совершенно прозрачна для пользова-
теля, а его конфигурация определяется двумя регистрами — регистром тайминга
MAMTIM и регистром управления MAMCR. Кроме того, имеется несколько до-
полнительных регистров, содержащих информацию о текущей эффективности
работы модуля. Регистр тайминга используется для задания соответствия между
тактовой частотой ЦПУ и временем доступа к FLASH-памяти. Значение, запи-
санное в трех младших битах регистра тайминга, соответствует количеству тактов
тактового сигнала ЦПУ, которое требуется модулю МАМ для обращения к
FLASH-памяти. Поскольку максимальная тактовая частота FLASH-памяти со-
ставляет 20 МГц, а ЦПУ может работать на частотах до 60 МГц, количество так-
тов, необходимое для обращения к FLASH-памяти, равно трем. Таким образом,
каждые три такта мы можем загружать четыре команды, сохраняющиеся в модуле
МАМ для дальнейшего использования. Регистр управления МАМ используется
для задания режима работы модуля (Рис. 3.7).
56
Модуль ускорения работы памяти
МАМ МАМ
отключен задействован частично
МАМ
задействован полностью
Разрешена
предварительная
выборка команд
Рис. 3.7. Режимы работы модуля МАМ
После сброса модуль МАМ выключен, и все команды и значения конс-
тант считываются непосредственно из FLASH-памяти. Модуль МАМ можно
включить частично, так чтобы линейный код считывался бы из модуля, а ад-
реса переходов и значения констант — непосредственно из FLASH-памяти.
И, наконец, модуль МАМ можно задействовать полностью. В этом случае все
обращения к FLASH-памяти будут производиться через него. Смысл нали-
чия этих режимов заключается в том, что, как и при кэшировании, время вы-
полнения кода из модуля МАМ — величина неопределенная. Поэтому, если
нам необходимо обеспечить конкретное время выполнения кода, мы можем
отключить модуль или уменьшить его влияние. Тем не менее, даже если мо-
дуль МАМ задействован полностью, его влияние заметно гораздо меньше,
чем кэша. В частности, используя инструментарий анализа производитель-
ности («performance analysis») средств разработки, можно предсказать произ-
водительность кода.
Чтобы облегчить этот анализ, а также для того, чтобы оценить эффективность
работы модуля МАМ, предусмотрено несколько регистров для сбора статистичес-
кой информации (Рис. 3.8), которые можно использовать для измерения произ-
водительности модуля.
Основными среди этих регистров являются два счетчика, отслеживающие об-
ращения к FLASH-памяти и к буферам модуля МАМ. Регистр управления позво-
ляет задать условие, при котором будет происходить инкрементирование счетчи-
ков. Изменяя содержимое регистра управления, мы можем различать выборку
констант и выборку команд, что позволяет нам определять частоту выборок ко-
манд, частоту выборок данных или общую частоту выборок. Основываясь на этих
измерениях, можно в какой-то степени определить эффективность использова-
ния модуля МАМ в вашем приложении. На компакт-диске имеется простой при-
мер, демонстрирующий использование модуля МАМ и регистров статистической
информации. Кроме того, в данном примере показано, насколько важен этот мо-
дуль для повышения производительности микроконтроллеров семейства
LPC2000. 57
Глава 3. Системные периферийные устройства
ARM 7
Регистр состояния
статистической
информации
Все команды
и данные находятся
в защелках
Счетчик обращений
к буферу
МАМ
Счетчик обращений
к FLASH-памяти
FLASH
Регистр управления
статистической
информацией
В модуле МАМ имеется несколько
регистров для сбора
статистической информации,
в одном из которых хранится
число обращений к FLASH-памяти,
а в другом — число обращений
к модулю МАМ.
На основании этих значений
можно численно оценить
эффективность МАМ
Рис, 3.8. Регистры для оценки эффективности работы МАМ
Пример конфигурирования модуля МАМ
Приведенный ниже пример начинает выполняться при выходной частоте
ФАПЧ, равной 60 МГц, и выключенном модуле МАМ. Программа последова-
тельно, с некоторой задержкой, кратковременно включает светодиоды. В это же
время выполняется аналого-цифровое преобразование и, если результат преобра-
зования превышает 0x00000080, включается модуль МАМ для достижения макси-
мальной скорости выполнения программы. Работу модуля МАМ можно заметить
визуально по увеличению частоты вспышек светодиодов. В следующем разделе
мы посмотрим, как можно загрузить программу в FLASH-память, чтобы понаб-
людать за ее работой в реальном устройстве.
int main(void)
{
unsigned int delay;
unsigned int FLASHer = 0x00010000; // Объявляем локальные переменные
IODIR1 = OxOOFFOOOO; // Все порты - выходы
VPBDIV = 0x02;
ADCR = 0x00270601; // Инициализируем АЦП: 10 бит, AINO, 3 МГц
ADCR |= 0x01000000; // Запускаем преобразование
while(1)
{
do
{
val = ADDR; // Считываем регистр данных АЦП
}
while ((val & 0x80000000) == 0);
val = ((val >> 6) & 0x03FF);
if(val < 0x80)
MAMCR = 0;
MAMTIM = 0x03;
58
Программирование FLASH-памяти
MAMCR = 0x02;
}
else
{
MAMCR = 0x0;
}
for(delay=0;delay<0xl00000;delay++) // Простой цикл задержки
{
ChangeGPIOPinState(FLASHer);
FLASHer = FLASHer « 1;
if(FLASHer & 0x01000000)
{
FLASHer = 0x00010000;
}
// Выводим значение в порт
// Двигаем маску текущего СИД
// Проверяем маску на переполнение
void ChangeGPIOPinState(unsigned int
{
IOCLR1 = -state;
IOSET1 = state;
state)
// Сбрасываем соответствующие выводы
// Устанавливаем соответствующие выводы
Программирование FLASH-памяти
Думаю, вам будет приятно узнать, что несмотря на физическую реализацию
встроенной FLASH-памяти в виде двух перемежающихся банков, с ней можно
работать как с непрерывным блоком памяти. Причем перед записью программ в
микроконтроллер не требуется выполнять никаких специальных преобразова-
ний полученного кода. С точки зрения пользователя, встроенная FLASH-па-
мять представляет собой набор 8-килобайтных секторов, которые можно запи-
сывать и стирать независимо друг от друга. Программирование встроенной
FLASH-памяти можно осуществить несколькими способами. Самым простым
является использование встроенного загрузчика (bootloader), который позволя-
ет загрузить код программы в ОЗУ по интерфейсу UART0, а затем переписать
его в FLASH-память. Также для программирования микроконтроллера можно
воспользоваться средствами разработки, поддерживающими интерфейс JTAG.
Этот способ особенно удобен во время разработки программы, поскольку в дан-
ном случае программирование можно выполнять непосредственно из среды от-
ладчика и нет необходимости постоянно переключаться между отладчиком и
загрузчиком. Кроме того, скорость загрузки по интерфейсу JTAG может дости-
гать 400 Кбайт/с, поэтому данный способ лучше всего подходит для больших
программ, в частности тех, которые используют внешнюю FLASH-память. И,
наконец, перепрограммирование секторов FLASH-памяти можно осуществлять
из уже находящейся в микроконтроллере программы (т.н. внутрипрограммное
59
Глава 3. Системные периферийные устройства
программирование). В этом случае новый код можно загружать в микроконт-
роллер по любому доступному интерфейсу (SPI, I2C, CAN), а затем записывать
его в требуемый сектор FLASH-памяти. Очевидно, что этот способ удобно ис-
пользовать для обновления программы в уже готовом устройстве.
Управление картой распределения памяти
Прежде чем приступить к рассмотрению работы загрузчика, мы должны разо-
браться в различных моделях памяти, использующихся в микроконтроллерах се-
мейства LPC2000. Как вы уже знаете, таблица векторов прерываний ядра ARM7 и
таблица адресов обработчиков этих прерываний занимают младшие 64 байта па-
мяти программ. На самом деле, на эти адреса можно отобразить различные участ-
ки памяти, в зависимости от режима работы, заданного в регистре МЕММАР. Не
перепутайте, эти режимы не имеют ничего общего с режимами работы ядра
ARM7! С помощью регистра МЕММАР можно выбрать один из следующих ре-
жимов: BOOT, FLASH, RAM и EXTERNAL MEMORY. В каждом режиме на
первые 64 байта памяти отображается своя таблица векторов (Рис. 3.9). Так,
в режиме RAM на начало памяти отображается содержимое адресов
0x40000000...0х4000003Е Это позволяет загрузить программу в ОЗУ, начиная с ад-
реса 0x40000000, а затем переадресовать таблицу векторов. В результате и про-
грамма, и обработчики прерываний будут выполняться из ОЗУ. Как правило, этот
режим используется только для отладки небольших программ. В режиме FLASH
содержимое первых 64-х байт FLASH-памяти остается неизменным. Этот режим
является стандартным для пользовательских приложений. В режиме BOOT пер-
вые 64 байта FLASH-памяти замещаются таблицей векторов загрузчика, а по ад-
ресу вектора сброса размещается команда перехода на встроенный загрузчик
микроконтроллера.
00x00000040
1
0x40
0x00000040
0x00000000
2
0x40000040
0x40000000
3
0x80000040
0x80000000
0
Режим BOOT
Встроенная Режим FLASH
FLASH-память
Режим RAM
Режим
EXTERNAL
MEMORY
Рис. 3.9. Распределение памяти в различных режимах
Загрузчик
При каждом сбросе LPC2000 конфигурация памяти соответствует режиму
BOOT, т.е. выполнение команды по адресу вектора сброса приведет к переходу на
точку входа загрузчика (0x7FFFFFFF). Такое поведение микроконтроллера мо-
жет сильно испортить жизнь неопытным пользователям, т.к. после загрузки про-
60
Программирование FLASH-памяти
граммы в FLASH-память через JTAG, сброса и выполнения одной единственной
команды они обнаруживают, что счетчик команд указывает на какой-то стран-
ный адрес в старших областях памяти. В этом случае в регистр МЕММАР следует
записать число 0x00000002, чтобы перевести микроконтроллер в режим FLASH и
вернуть пользовательскую таблицу векторов прерываний.
После запуска загрузчик производит ряд проверок, чтобы определить, нужно
ли программировать FLASH-память. Сначала проверяется состояние сторожево-
го таймера, чтобы определить тип сброса — аппаратный (hard) или программный
(soft). Если произошел аппаратный сброс, проверяется напряжение на выводе
РО. 14. Если оно имеет НИЗКИЙ уровень, выполняется переход к обработчику
команд загрузчика. Если же произошел программный сброс (например, по тайм-
ауту сторожевого таймера) или на выводе Р0.14 присутствует напряжение ВЫСО-
КОГО уровня, то считается, что внешний запрос на перепрограммирование
FLASH-памяти отсутствует. Однако, прежде чем передать управление пользова-
тельской программе, загрузчик проверяет корректность содержимого FLASH-па-
мяти. Чтобы можно было выполнить такую проверку, все пользовательские про-
граммы должны содержать сигнатуру. Сигнатура представляет собой 32-битное
число, хранящееся в неиспользуемом месте таблицы векторов процессора ARM7
по адресу 0x00000014. Сигнатура вычисляется как дополнительный код суммы со-
держимого таблицы векторов ARM7 (Рис. ЗЛО).
Рис. 3.10. Вычисление сигнатуры
Для корректной программы результат сложения этого значения с сигнатурой
должен быть равен нулю. Если обнаружена корректная программа, память пере-
ключается в режим FLASH, в котором восстанавливается пользовательская таб-
лица векторов, счетчик команд сбрасывается в ноль и начинается выполнение
программы пользователя. Если же корректной программы не обнаружено, за-
грузчик переходит к собственному обработчику команд. Таким образом, при от-
сутствии сигнатуры ваша программа никогда не запустится! Сигнатуру програм-
мы можно добавить в код стартового модуля следующим образом:
Глава 3. Системные периферийные устройства
LDR PC, Reset_Addr
LDR PC, Undefined_Addr
LDR PC, SWI_Addr
LDR PC, Prefetch_Addr
LDR PC, Abort_Addr
.long 0xB8A06F58
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
/* Сигнатура программы */
Внутрисхемное программирование (ISP)
При отсутствии корректной сигнатуры программы или наличии во время
сброса на выводе Р0.14 напряжения НИЗКОГО уровня начинает выполняться за-
грузчик. Прежде чем передать управление обработчику команд, загрузчик запус-
кает процедуру автоматического определения скорости передачи. Эта процедура
ожидает прихода в порт UART0 символа синхронизации. При посылке хостом
этого символа микроконтроллер измеряет длительность передачи одного бита и
настраивает скорость обмена модуля UART0 так, чтобы она соответствовала ско-
рости хоста. Затем производится подтверждение установления связи, после чего
управление передается обработчику команд.
Обработчик команд загрузчика принимает команды в формате ASCII по ин-
терфейсу UART0. Используемые команды, которые перечислены в Табл. 3.1, пре-
доставляют вам полный контроль над процессом программирования FLASH-па-
мяти. Помимо команд программирования, предусмотрена и простейшая отладоч-
ная команда («Запуск»), которую можно использовать для запуска кода,
загруженного в ОЗУ. Полное описание протокола обмена с загрузчиком можно
найти в документации на микроконтроллеры семейства LPC2000.
Таблица 3.1. Форматы команд
62 Команда Формат Загрузчик принимает команды в формате ASCII через последовательный порт 0
Разблокировать U <код разблокировки>
Установить скорость обмена В <скорость><стоп-биты>
Эхо А < установки >
Записать в ОЗУ W <стартовый адрес Хколичество байтов>
Прочитать память R <стартовый адресХколичество байтов>
Подготовить сектор(а) к записи Р <№ первого секторах № последнего сектора>
Копировать ОЗУ в FLASH-память С <адрес FLASHXaapec ОЗУХколичество байтов>
Запуск G <адрес><режим>
Стереть сектор(а) Е <№ первого секторах № последнего сектора>
Проверить сектор(а) на чистоту I <№ первого секторах № последнего сектора>
Считать ID устройства J
Считать версию загрузчика К
Сравнить М <1-й адрес><2-й адресХколичество байтов>
Программирование FLASH-памяти
Компания Philips разработала утилиту внутрисхемного программирования
FLASH-памяти, которую можно использовать для программирования микро-
контроллера на макетной плате. Эта утилита автоматически вычисляет сигнатуру
программы и записывает ее по требуемому адресу. Чтобы утилита работала кор-
ректно, по адресу неиспользуемого вектора прерывания должна находиться ко-
манда NOP.
Упражнение 7. Модуль МАМ и утилита программирования FLASH-памяти
В этом упражнении описывается порядок работы с утилитой программирования
FLASH-памяти на примере загрузки простой программы. Эта программа начинает
выполняться при выключенном модуле МАМ. В зависимости от результата аналого-
цифрового преобразования модуль МАМ включается, и мы можем визуально заме-
тить увеличение скорости выполнения программы, которое происходит благодаря
использованию модуля.
Внутрипрограммное программирование (IAP)
Содержимое FLASH-памяти можно изменять и непосредственно из вашей
программы. Для этого из программы вызываются команды загрузчика. Для обра-
щения к функциям загрузчика необходимо создать в ОЗУ таблицу, содержащую
код команды, которую вы хотите выполнить, и ее параметры. Стартовый адрес
этой таблицы запоминается в регистре R0. Стартовый адрес второй таблицы, в
которой будут сохранены код статуса и результаты выполнения команды, загру-
жается в регистр R1 (Рис. 3.11).
Таблица
параметров
команды
Таблица
результата
выполнения
команды
Рис. 3.11, Таблицы ОЗУ
Для внутрипрограммного
программирования используются
функции загрузчика.
Передача команд
осуществляется с помощью
двух таблиц. Стартовые адреса
этих таблиц загружаются
в регистры R0 и R1
Точка входа в обработчик IAP располагается по адресу 0x7FFFFFF0, если вы
обращаетесь к нему из THUMB-функций, и по адресу 0x7FFFFFFl, если из
ARM-функций. При этом предполагается, что адрес возврата находится в регист- 63
Глава 3. Системные периферийные устройства
ре связи. Это условие введено для того, чтобы соответствовать стандартному со-
глашению ARM о вызове подпрограмм. Вызов подпрограмм IAP через указатели
на функции подробно описан в справочной документации. Ниже показан альтер-
нативный метод вызова этих функций, а в упражнении используются оба этих
метода. Если вам не хватает памяти программ, можете поэкспериментировать с
обоими способами, чтобы определить, какой из них наиболее эффективен с ва-
шим компилятором.
Определим функцию THUMB следующим образом:
void iap (unsigned *cmd, unsigned *rslt, unsigned entry)
{
asm("mov rl5,r2");
}
Мы можем передать стартовый адрес таблицы команды и таблицы резуль-
тата; в соответствии с соглашениями APCS эти значения будут загружены в
регистры R0 и R1. В следующий регистр передачи параметров (R2) мы можем
загрузить адрес точки входа в подпрограмму IAP. В режиме THUMB мы не
можем непосредственно обращаться к старшим регистрам, однако можем ко-
пировать содержимое младших регистров в старшие. Соответственно мы мо-
жем скопировать содержимое регистра R2 непосредственно в счетчик команд
и тем самым инициировать вызов функции IAP. После ее завершения про-
изойдет возврат в нашу прикладную программу по значению, сохраненному в
регистре связи. Это значение является адресом команды, следующей за ко-
мандой вызова нашей функции iap(...). Обратите внимание, что после возвра-
та из функций IAP микроконтроллер находится в режиме ARM, а не THUMB.
Для работы функций IAP требуется 32 старших байта встроенного ОЗУ, поэ-
тому вы можете либо расположить стек ниже этой области (в этом случае она
не будет использоваться), либо, если вам требуется весь имеющийся объем
ОЗУ, расположите стек режима IRQ в старших адресах памяти и запрещайте
прерывания перед вызовом подпрограмм IAP. Используя указатель, вы може-
те скопировать старшие 32 байта встроенного ОЗУ во временный буфер, а
после возврата из функции IAP восстановить их содержимое. При этом ис-
ключается повреждение данных, находящихся в стеке.
Интерфейс внешней шины
В моделях LPC22xx имеется контроллер внешней памяти (External
Memory Controller — ЕМС). Во включенном состоянии этот контроллер
формирует четыре сигнала выбора кристалла при обращении к адресам, на-
чиная со значения 0x80000000. Каждый сигнал соответствует фиксирован-
ному диапазону адресов объемом 16 Мбайт. Для каждого такого банка памя-
ти можно индивидуально задать количество тактов задержки и ширину, или
разрядность, шины (8, 16 и 32 бита). Помимо подключения дополнитель-
ной памяти и периферийных устройств, микроконтроллеры моделей
LPC22xx могут загружать программу из внешней FLASH-памяти, подклю-
64 ченной к нулевому банку.
Интерфейс внешней шины
Интерфейс внешней памяти
Интерфейс внешней памяти моделей LPC22xx показан на Рис. 3.12.
Рис. 3.12. Интерфейс внешней памяти
В качестве шины данных используются выводы 2-го порта Р2.0...Р2.31, а в ка-
честве шины адреса — выводы 3-го порта Р3.0...Р3.23. Остальные выводы 3-го
порта используются для сигналов выбора кристалла CS1...CS3, сигналов выбора
байтового тракта BLS0...BLS3 и сигнала разрешения записи WE. Для сигнала вы-
бора кристалла CSO и сигнала разрешения выхода ОЕ используются выводы 1-го
порта. Два вывода управления загрузкой мультиплексированы с выводами шины
данных D26 и D27. В зависимости от состояния этих выводов во время сброса,
микроконтроллер загрузится либо из внутренней FLASH-памяти, либо из внеш-
ней памяти (любой разрядности), подключенной к О-му банку. В Табл. 3.2 показа-
но, в каком состоянии должны находиться выводы при сбросе, чтобы осущест-
вить загрузку из конкретного устройства. Оба вывода подтянуты к линии питания
внутренними подтягивающими резисторами с небольшим сопротивлением, что-
бы по умолчанию обеспечить загрузку из внутренней FLASH-памяти.
Таблица 3.2. Состояние выводов управления загрузкой
Boot 1:0 Разрядность шины блока CSO Boot 1:0 Разрядность шины блока CSO
00 8-битная 10 32-битная
01 16-битная 11 Внутренняя FLASH-память
В документации на LPC22xx можно найти базовые схемы для подключения
наиболее распространенных устройств. Тем не менее, мы рассмотрим пример
подключения внешней FLASH-памяти и статического ОЗУ к 32-битной шине.
В качестве микросхемы FLASH-памяти мы будем использовать микросхему
AM29LV320DT компании AMD. Это микросхема FLASH-памяти объемом
32 Мбит, которая может быть организована как 4М х 8 бит или 2М х 16 бит. В ка-
честве микросхемы ОЗУ мы возьмем микросхему статического ОЗУ K6F1616U6A
с организацией 1М х 16 бит. Обе эти микросхемы имеют низкое потребление и 65
Глава 3. Системные периферийные устройства
поддерживаются JTAG-интерфейсом ULINK. FLASH-память мы подключим к
линии CS0, а ОЗУ — к линии CS1. Схемы подключения для этих типов памяти
приведены соответственно на Рис. 3.13 (FLASH-память) и Рис. 3.15 (ОЗУ).
I ID31...D01 >
( [А23...А0]
[ Control
U300
25
79"
73
U301
\A2
\AT
\A4
\A3
\A6 7
\A7’ 70
\A8~..ТГ
\A9 "2
\ AID".TT
\A11 5
\AT2 ТГ
\Al3 73
\A14 12
\A15 6
\AT6~ 78"
\A17 '24
\A18 30
\Al9 8
\A20 15
\A2T~..72"
\A2'2 7Г
\ /ОЕ 37
\.../WE ~4
X /CSFO 31
10
7F
R303
Юк
AO
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
A15
A16
A17
A18
A19
A20
Of
WE
RESET
BYTE
DO
D1
D2
D3
D4
D5
D6
D7
D8
D9
D10
D11
D12
D13
D14
D15/A-1
WP/ACC
NO
ry/by”
VCC
GND
GND
29LV320DT-90WM1
26
44
77
45
"46
78
47
79
72
38
33 P10/I
39 5l1/
34" 5l2/
41 Р13/
35~~5'14/
72 ~ D15X
9
40
7Г
3
R301
Юк
J301 Й2
ЛХ2 —_
43
47
GND
VDD
3.3 в
\A2 25
<A3" ~T9
\A4 13
\A5" ~"1
\A6 7
\A7..~70
KA8 14
<A9~' ~~2
\A1O ' 11
\Ai1 "5
\A12 17
\AT3 ~73
\A17 ~72'
\A15 ..6
\A16 18
\AT7 ”74
\AI8~ ’”r
\AT9~
\A23
\A2T~
73
T
73
77
Угёг ~7T
\ /ОЕ 37
\ /WE •” 4
X /C$FO~31
10
77
AO
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
A15
A16
A17
A18
A19
A20
ОЁ
RESET
BYTE
DO
D1
D2
D3
D4
D5
D6
D7
D8
D9
D10
D11
D12
D13
D14
D15/A-1
WP/ACC
NC
26 Р16/
44 Р17/
27 Р18/
'45~"blS/
46 Р20/
78~Т2Т/
47' Ь27/
29 Ь23/
32' ЙЯ/
38" D25>
33 Ь26/
39 527/
34 Р28/
4Г..523/
35 Р30/
42~"D31V
9
~~re~
RY/BY
VCC
40 0Vdd
3.3 В
43
GND
GND
29LV320DT-90WM1
GND
3
/RESET
Р017
J300 2
J1X2
Puc. 3.13. Схема подключения микросхем FLASH-памяти
Две микросхемы 29LV320DT используются в конфигурации 2М х 16 бит, об-
разуя 32-битную страницу FLASH-памяти объемом 2М. Чтобы разрешить 16-бит-
ный режим работы, выводы #byte обеих микросхем подтянуты к линии питания.
Микросхемы FLASH-памяти разрабатывались как устройства с загрузочным сек-
тором, поэтому в них предусмотрена защита от записи первого и последнего сек-
торов для предотвращения повреждения записанных в них данных. Защита от за-
писи включается подачей напряжения НИЗКОГО уровня на вывод WP/АС. Пос-
кольку такая защита нам не требуется, соответствующие выводы подтянуты к
линии питания, что обеспечивает возможность перепрограммирования любого
сектора FLASH-памяти. Выходы RY/BY также не используются, поэтому их тоже
подтягиваем к линии питания. Остальные управляющие сигналы — сброс, разре-
шение выхода (ОЕ), разрешение записи (WE) и разрешение кристалла (СЕ) —
подключены непосредственно к процессору. Поскольку память организована
66
Интерфейс внешней шины
пословно (32 бита), нам нужно адресовать только каждый 4-й байт, поэтому ли-
нии шины адреса АО и А1 не используются. Если необходим блок памяти больше-
го объема, то вместо микросхемы 29LV320 можно поставить 29LV640, в результате
чего получим 32-битную страницу памяти объемом 4М. Для использования всего
адресного пространства размером 16М можно добавить еще пару микросхем и
стробировать сигнал CS0 сигналом линии А23 шины адреса, обеспечивая тем са-
мым выборку обеих половин страницы памяти (Рис. 3.14).
0x81000000
0x80800000
0x80000000
CS0. А23
CS0.АЗЗ
Из 4-х микросхем с организацией 2Мх 16
можно сформировать блок памяти
с линейным адресным пространством 4М х 32.
Для выбора конкретного банка используется
линия адреса А23 и сигнал CS0
Рис. 3.14. Формирование блока памяти
[ [D31...D0]
( [А23...А0]
U400
U401
3
3
/BLSO /
J400
Л Д2 /BLS1 /
— »4 /LUBR /
J2X2
/BLS2 /
/HLBR /
\A2 3
\A3 4
\A4 ' 5
\A5 9
\A6 10
\A7 15
\A8 16
\A9 22
\A1O 44
\A11 45
\A12 46
\A13 47
\A14 39
\A15 40
\A16 33
\Al7 ~34~
\A18 "28
\A19 21
\A20 43
\A21 38
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
A15
A16
A17
A18
A19
DO
D1
D2
D3
D4
D5
D6
D7
D8
D9
D10
D11
D12
D13
D14
D15
12 DO /
17 D1 /
18 D2 /
23 D3 /
23~ 5'4/
3'5 " D5 /
35~~ D6" /
42~ 57/
7 •• D8 /
13~ 55 /
14 D1O/
20~ 5i~1/
26 Di 2/
32~ 513/
31 Р14/
37 D15Z
Vdd
3.3 В Vbat
\A2 3
\A3 4
\A4 5
\A5 9
\A6 10
\A7 '15
\A8 16
\A9 22
\A10 44
\A11 45
\A12 46
\A13 47
\A14 39
\A15 40
\A16 33
\ A 7 34
\A18..~28~
\Al9 ~21
\A20
J401
/LLBR 1
/ШбЙ" S'
/0Е 2
/WE 41
LB
UB
NC
48 1
_____43
\A21 38
A0
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
A15
A16
A17
A18
A19
DO
D1
D2
D3
D4
D5
D6
D7
D8
D9
D10
D11
D12
D13
D14
D15
12 Р16/
17 Р17/
18 Р18/
23~ "СИЗ/
29 D20 /
35 ' 021 /
36 Р22/
42 Р23/
7 524/
13 Р25/
14 Р26/
20 527/
26 D28 /
32 " 523/
31 530/
37 5зi/
J2X2
/CSRO 11
~3
WE
Vcc
Vcc
2 VcCRAM
CS1
CS2
GND
GND
GND
25
34
1Q По умолчанию:
io 1-2
27—
1 -2
/HLBR 1
/HUBR 8
/0Г 2
/WE 41
/CSRO 11
6
LB
UB
WE
CS1
CS2
NC
48
K6F1616U6A-EF70 GND
Vcc
Vcc
GND
GND
GND
25 VcCRAM
24 "T ю
19
30
37
K6F1616U6A-EF70
GND
3
/RESET
Рис. 3.15. Схема подключения микросхем ОЗУ
67
Глава 3. Системные периферийные устройства
Микросхемы ОЗУ подключаются к шине адреса аналогичным образом, толь-
ко в данном случае используется линия CS1 (Рис. 3.15). Поскольку микросхемы
имеют объем 1 Мбайт, мы будем использовать линии А2...А21 шины адреса. До-
полнительные микросхемы можно подключить, используя стробирование сигна-
ла выбора кристалла сигналами линий адреса А22 и А23. Поскольку при работе с
ОЗУ нам может потребоваться доступ как к словам, так и к полусловам или бай-
там, то для обращения к старшим или младшим байтам обеих микросхем мы мо-
жем использовать выводы выбора байтового тракта.
И, наконец, если мы хотим загружать программу из внешней памяти, выводы
выбора режима загрузки D26 и D27 должны быть подтянуты к общему проводу.
Использование интерфейса внешней шины
Каждому сигналу выбора кристалла соответствует фиксированный диапазон
адресов и отдельный регистр конфигурации шины BCFG0...BCFG3. Диапазон
адресов для каждой страницы приведен в Табл. 3.3.
Таблица 3.3. Диапазоны адресов
Линия Адрес Область
CS0 8000 0000 80FF FFFF
CS1 8100 0000 81FF FFFF
CS2 8200 0000 82FF FFFF
CS3 8300 0000 83FF FFFF
В предыдущем примере мы подключили внешнюю FLASH-память к линии
CS0 по адресу 0x80000000, а ОЗУ — к линии CS1 по адресу 0x81000000. Прежде
чем использовать внешнюю память, необходимо соответствующим образом ини-
циализировать регистры конфигурации (Рис. 3.16).
AT MW ВМ WP WP ERR BUSS ERR WST2 RBLE WST1 IDCY
1
IDCY — Минимальное число «холостых» тактов между операциями чтения и записи
WST1 — Длительность операций чтения
RBLE — 0 для 8-битных устройств (на выводе BLS устанавливается напряжение ВЫСОКОГО уровня),
1 для 16/32-битных устройств (на выводе BLS устанавливается напряжение НИЗКОГО уровня)
WST2 — Длительность операций записи
WPERR — Устанавливается, если программа пытается записать в банк, защищенный от записи
WP — Защита от записи, при установке запрещает запись в соответствующий банк памяти
ВМ — Определяет банк памяти как Burst ROM
MW — Ширина шины данных
AT, BUSS ERR, ERR — не используются
Рис. 3.16. Регистр конфигурации
Каждый из используемых банков памяти должен быть сконфигурирован в соот-
ветствии с параметрами задействованных устройств. Возьмем, к примеру, FLASH-na-
68 мять. Длительность цикла чтения FLASH-памяти равна 90 нс, поэтому при частоте
Интерфейс внешней шины
процессора 60 МГц (период 16 нс) нам потребуется 6 тактов для выполнения операции
чтения и один такт ожидания. Доступ к FLASH-памяти осуществляется пословно, по-
этому бит RBLE должен быть сброшен для запрещения выбора байтового тракта.
Таблица 3.4. Разрядность шины данных
MW Разрядность шины
00 8 битов
01 16 битов
10 32 бита
11 Зарезервировано
Каждый блок памяти может
использовать шину данных
шириной 8, 16 или 32 бита
Во время обычной работы программы запись в FLASH-память не произво-
дится, поэтому бит WST2 должен быть сброшен. Кроме того, для обнаружения
случайных попыток записи в банк FLASH-памяти можно установить защиту от
записи. Однако если эта защита конфликтует с алгоритмом программирования
FLASH-памяти, осуществляемого устройством ULINK, то на время разработки
программы эту защиту лучше отключить, сбросив соответствующий бит. И, нако-
нец, зададим ширину шины равной 32 битам (Табл. 3.4). Таким образом, значение
регистра конфигурации будет равно 0x20000060.
Что касается ОЗУ, то время записи и чтения использованных нами микросхем
составляет 70 нс. Соответственно при тактовой частоте 60 МГц число тактов ожи-
дания как при записи, так и при чтении (WST1 и WST2) равно 5, а значение поля
IDCY должно быть равно 1. Поскольку ОЗУ является устройством с байтовой ор-
ганизацией, необходимо разрешить управление байтовым трактом, установив бит
RBLE. Шина должна быть 32-битной. Таким образом, значение регистра конфи-
гурации получается равным 0x20001440.
Эти числа можно заносить непосредственно в код стартового модуля Keil, ис-
пользуя специализированный графический редактор (Рис. 3.17).
S Stack Configuration (Stack Sizes in Bytes)
E -VPSDIV Setup г
® PLL Setup p
0 MAM Setup p
в External Memory Controller (EMC) p
IB Bank Configuration 0 (BCFGO) p
IDCY: Idle Cycles 1
' WST1: Wait States 1 6
; WST2: Wait States 2 0
I RBLE: Read Byte Lane Enable Г~
; WP: Write Protect Г
; BM: Burst ROM Г
: MW: Memory Width 32-bit
PI Bank Configuration 1 (BCFG1) p
; IDCY: Idle Cycles 1
• WST1: Wait States 1 5
i WST2: Wait States 2 5
i RBLE: Read Byte Lane Enable p
WP: Write Protect Г"
i BM: Burst ROM F
MW: Memory Width 32-bit
H с C —,r ( h ‘ > Г
+ ‘ > г
Рис. 3.17. Окно графического редактора
69
Глава 3. Системные периферийные устройства
Загрузка из ПЗУ
По умолчанию загрузка микроконтроллеров LPC22xx производится из внут-
ренней FLASH-памяти, а обращение к внешней памяти может осуществляться
только после конфигурирования соответствующих регистров. Однако если любой
из выводов выбора режима загрузки подключен к общему проводу, то программа
будет загружена из внешней памяти. В этом случае разрешается обращение к нуле-
вому банку памяти с шириной шины данных, определяемой состоянием выводов
выбора режима загрузки. При этом значения WST1 и WST2 будут соответствовать
34 тактам, a IDCY — 16 тактам. Таким образом, гарантируется, что обращение к ну-
левому банку внешней памяти будет выполняться достаточно медленно для того,
чтобы работать с любым внешним устройством. При загрузке из внешней памяти в
регистре МЕММАР будет число 0x03 (загрузка из внешней FLASH-памяти), а при
чтении младших 64 байт внешней памяти, подключенной к нулевому банку, будут
возвращаться нули. Это означает, что вы должны так скомпоновать свою програм-
му, чтобы таблица векторов прерываний и таблица адресов их обработчиков раз-
мещались, начиная с адреса 0x80000000. На практике это означает изменение стар-
тового адреса с 0x00000000 на 0x80000000. В коде стартового модуля Keil это
изменение производится с помощью соответствующей директивы ассемблера, пе-
ремещающей сегмент CODE_BASE, который содержит таблицу векторов.
$IF (EXTERNAL-MODE)
CODE_BASE EQU 0x80000000
$ELSE
CODE_BASE EQU 0x00000000
$ENDIF
AREA STARTUPCODE, CODE, AT CODE_BASE // Только для чтения, выравнивание = 4
PUBLIC _startup
Макрос EXTERNAL-MODE объявляется на вкладке локальных опций ассем-
блера, как показано на Рис. 3.18:
70
Рис. 3.18. Вкладка локальных опций ассемблера
Схема ФАПЧ
После того как мы сделали нашу программу пригодной для запуска из внеш-
ней FLASH-памяти, возникает ситуация, известная как «задача курицы и яйца».
Чтобы запрограммировать внешнюю FLASH-память, необходимо сконфигури-
ровать 0-й банк памяти, но сделать это можно только из программы. Одним из
способов решения этой проблемы является размещение во встроенной FLASH-
памяти программы конфигурации, которая будет загружаться первой и конфигу-
рировать контроллер внешней памяти. Однако некоторые модели микроконтрол-
леров поставляются без встроенной FLASH-памяти. К счастью, с помощью от-
ладчика ULINK можно выполнить файл сценария, в котором сначала конфигу-
рируется контроллер внешней памяти, а затем в эту память заносится программа.
Упражнение 9. Интерфейс внешней шины
В этом упражнении мы изменим проект, созданный нами при выполнении 1-го уп-
ражнения, чтобы конечная программа могла загружаться и выполняться из внешней
памяти.
Схема ФАПЧ
На вход схемы фазовой автоподстройки частоты (Phase Locked Loop — PLL),
или сокращенно ФАПЧ, подается сигнал частотой 10...25 МГц, полученный с по-
мощью кварцевого резонатора, а на выходе формируется сигнал частотой до
60 МГц, обеспечивающий синхронизацию (тактирование) ЦПУ ARM7 и перифе-
рии (Рис. 3.19). Благодаря этому микроконтроллеры семейства могут работать на
максимально допустимой частоте, используя внешние генераторы с относитель-
но низкой частотой. Таким образом, снижается до минимума электромагнитное
излучение микросхем. Кроме того, выходная частота схемы ФАПЧ может дина-
мически изменяться, что позволяет замедлять работу устройства для экономии
энергии в ждущем режиме.
Схема ФАПЧ предназначена для повышения
частоты сигнала, получаемого от внешнего
резонатора, вплоть до 60 МГц.
Коэффициент умножения определяется
константами Ми Р
Рис. 3.19. Схема ФАПЧ
Работа схемы ФАПЧ определяется двумя константами, значениями которых
необходимо задаться для определения частоты тактового сигнала ЦПУ и шины
АН В. Этот сигнал называется CCLK. Первая константа является коэффициентом
умножения. После этой операции выходная частота сигнала ФАПЧ определяется
выражением
Cclk ~ М х Fosc .
71
Глава 3. Системные периферийные устройства
В цепи обратной связи схемы ФАПЧ включен генератор, управляемый током
(ССО), который должен работать в диапазоне 156...320 МГц. Вторая константа
определяет коэффициент деления программируемого делителя, который обеспе-
чивает нахождение частоты ССО в заданных пределах. Рабочая частота ССО оп-
ределяется выражением:
Fcco = CClk х 2 х Р.
На нашей отладочной плате расположен генератор частоты 12 МГц, поэтому,
чтобы достичь максимальной частоты ЦПУ (60 МГц), коэффициент умножения
должен составлять:
М = Cclk/Fosc = 60/12 = 5.
А значение Р выбирается из уравнения:
156 < Fcco < 320 = 60x2 хР.
Примем Р = 2.
Интерфейс блока ФАПЧ показан на Рис. 3.20.
Внутренние регистры
блока ФАПЧ
Содержимое регистров управления
блока ФАПЧможно изменить
в любой момент времени,
однако новые установки вступят
в силу только после записи
в регистр PLLFEED определенной
последовательности чисел
Рис, 3,20, Интерфейс блока ФАПЧ
Значения, записанные в пользовательские РСФ, не будут переписаны во
внутренние регистры блока ФАПЧ до тех пор, пока в регистр запуска не будет за-
писана определенная последовательность чисел. После изменения содержимого
регистров PLLCON и PLLCFG вы должны записать в регистр PLLFEED сначала
ОхООООООАА, а затем 0x00000055. Эти значения должны быть записаны в двух пос-
ледовательных тактах. Если вы будете конфигурировать схему ФАПЧ при разре-
шенных прерываниях, вполне вероятно, что прерывание произойдет между опе-
рациями записи этих двух значений, в результате чего конфигурация данной схе-
мы не изменится. Для инициализации схемы ФАПЧ вы должны записать
соответствующие значения констант Р и М в регистр PLLCFG, после чего разре-
шить работу схемы, используя регистр PLLCON (Рис. 3.21). В результате этих
действий схема ФАПЧ запустится, однако для установления стабильного сигнала,
пригодного для использования в качестве тактового сигнала CCLK, потребуется
72 некоторое время. Процесс запуска схемы ФАПЧ можно контролировать, отеле-
Делитель шины VPB
живая состояние бита LOCK регистра PLLSTATUS. Установка этого бита означа-
ет, что выходной сигнал схемы ФАПЧ можно использовать в качестве основного
источника тактовых импульсов. При захвате частоты может также генерироваться
прерывание, позволяя вам во время запуска схемы ФАПЧ выполнять другие зада-
чи. Как только выходной сигнал стабилизируется, его можно будет использовать
в качестве источника CCLK вместо внешнего генератора. Это переключение осу-
ществляется с помощью бита PLCC регистра PLLCON.
Все действия, необходимые
для инициализации схемы ФАПЧ,
выполняются стартовым модулем
компилятора Keil,
поэтому от вас требуется
только задать значения
констант Ми Р.
При захвате частоты
схемой ФАПЧможет также
генерироваться прерывание.
Для обеспечения наибольшей
эффективности процесса
инициализации
можно использовать
это прерывание вместо того,
чтобы следить за состоянием
бита LOCK
Рис. 3.21. Инициализация схемы ФАПЧ
Необходимо аккуратно подходить к выбору значений, сохраняемых в регист-
ре PLLCFG. Числа, записываемые в регистр, соответствуют значениям Р — 1 и
М — 1, благодаря чему гарантируется, что константы Р и М никогда не будут рав-
ны нулю. Кроме того, значение М является 5-битным, так что младший бит зна-
чения Р располагается не на границе полубайтов. Если вы ошибетесь при конфи-
гурировании схемы ФАПЧ, рабочие параметры всего микроконтроллера могут
выйти за предельно допустимые значения. При переходе микроконтроллера в ре-
жим «Power Down» схема ФАПЧ выключается и отключается от линии тактового
сигнала. При выходе из спящего режима работа схемы ФАПЧ не возобновляется,
так что при каждом выходе из спящего режима необходимо выполнять ту же пос-
ледовательность операций, что и при инициализации.
Делитель шины VPB
В качестве сигнала CCLK, являющегося тактовым сигналом ЦПУ ARM7 и ши-
ны АНВ, используется сигнал от внешнего генератора или выходной сигнал
ФАПЧ. Между тем периферийные устройства подключаются к отдельной шине
VPB (Рис. 3.22): 73
Глава 3. Системные периферийные устройства
Рис. 3.22. Формирование тактовых сигналов
Тактовый сигнал шины VPB обозначается как Pclk- Этот сигнал формируется
после прохождения сигнала CCLK через мост VPB. В составе моста имеется дели-
тель, который может понижать частоту CCLK в 1, 2 или 4 раза. Содержимое ре-
гистра управления делителем VPB можно изменить из программы в любой мо-
мент времени. При сбросе устанавливается максимальный коэффициент, поэто-
му в момент инициализации программы частота Рськ составляет 1/4 от частоты
CCLK. В настоящее время все периферийные устройства, реализованные в микро-
контроллерах семейства LPC2000 могут работать на частоте 60 МГц, поэтому де-
литель VPB используется, главным образом, для уменьшения потребления мик-
роконтроллера за счет установки минимально возможной для данного приложе-
ния тактовой частоты шины VPB.
Пример. Конфигурирование ФАПЧ и VPB
Приведенный ниже фрагмент программы демонстрирует процесс конфигури-
рования схемы ФАПЧ для получения сигналов CCLK = 60 МГц и PCLK = 30 МГц
при использовании резонатора с частотой 12 МГц.
void init_PLL(void)
{
PLLCFG = 0x00000024; // Устанавливаем коэффициенты умножения и
// деления ФАПЧ для получения частоты 60.00 МГц
PLLCON = 0x00000001; // Включаем ФАПЧ
PLLFEED = ОхООООООАА; // Обновляем регистры ФАПЧ
PLLFEED = 0x00000055;
while(!(PLLSTAT & 0x00000400)); // Проверяем флаг LOCK
PLLCON = 0x00000003; // Подключаем ФАПЧ
PLLFEED = ОхООООООАА; // Обновляем регистры ФАПЧ
PLLFEED = 0x00000055;
VPBDIV = 0x00000002; // Устанавливаем частоту шины VPB = 30.00 МГц
}
Упражнение 10. Схема ФАПЧ
В этом упражнении мы будем конфигурировать схему ФАПЧ для формирования
74 cCLK = 60 МГц и PCLK = 30 МГц.
Управление электропитанием
Управление электропитанием
Во всех (хорошо спроектированных) микроконтроллерах ток потребления
прямо пропорционален количеству логических элементов и частоте их переклю-
чения. Микроконтроллеры семейства LPC2000 не являются исключением. Прос-
тота данных микроконтроллеров и относительно небольшое количество логичес-
ких элементов, составляющих ядро ARM7, способствуют низкому энергопотреб-
лению. Разумное использование ФАПЧ и делителя VPB позволяет уменьшить
скорость переключения элементов при выполнении программы. Кроме того, у
микроконтроллеров семейства LPC2000 есть дополнительные возможности по
управлению энергопотреблением. Процессор ARM7 имеет 2 режима пониженно-
го энергопотребления, которые управляются двумя младшими битами регистра
PCON. ЦПУ можно перевести в режим Idle, при котором ЦПУ останавливается, а
остальные периферийные устройства продолжают работать (Рис. 3.23). Любое из
прерываний от периферийных устройств приведет к выходу процессора из спя-
щего режима и возобновлению выполнения программы.
12 О
PCON I I I I I I I I PI
Рис. 3.23. Режим Idle
Кроме того, процессор ARM7 можно перевести в режим Power Down, в кото-
ром останавливается и ЦПУ, и периферия (Рис. 3.24). В этом случае выход мик-
роконтроллера из спящего режима может произойти только в результате сброса
либо в результате генерации внешнего прерывания. Генератор в этом режиме вы-
ключается. Содержимое регистров процессора и встроенного ОЗУ, а также логи-
ческие уровни на контактах ввода/вывода сохраняются. При выходе из спящего
режима в качестве источника тактового сигнала используется внешний генератор
и необходимо повторно выполнять процедуру конфигурирования ФАПЧ. 75
Глава 3. Системные периферийные устройства
Внешнее прерывание
Таймер О
Таймер 1
GPI0
PWMO
RTC
Блок управления выводами
PCON I ТГГПГ1Т1
Рис. 3.24. Режим Power Down
В микроконтроллерах LPC2000 имеется встроенный таймер, благодаря кото-
рому обеспечивается стабильность сигнала внешнего генератора и инициализа-
ция встроенной памяти и периферийных устройств до начала выполнения про-
цессором каких-либо команд. При «пробуждении» генератор начнет генериро-
вать колебания. После того как его сигнал станет достаточно стабильным для
управления кристаллом, таймер начнет отсчет 4096 тактов, после чего будет вы-
полнена инициализация FLASH-памяти и возобновится выполнение програм-
мы. Такое решение обеспечивает минимальную задержку включения после спя-
щего режима или сброса микроконтроллера. Помимо этого, в режим Power Down
можно перевести отдельные периферийные модули (если они не требуются в
программе) с помощью соответствующих управляющих битов регистра PCONP.
Ряд периферийных устройств отключать ни в коем случае нельзя: сторожевой
таймер, порты ввода/вывода, блок управления выводами и блок управления сис-
темой. В каждой программе можно оптимизировать конфигурацию LPC2000 та-
ким образом, чтобы обеспечить минимальное потребление для конкретного при-
ложения. Несколько неофициальных значений тока потребления приведены в
Табл. 3.5.
Таблица 3.5. Ток потребления для различных конфигураций LPC2000
Микроконтроллер Условие Ток потребления
LPC2106 При 60 МГц 30 мА
Power Down 10...15 мкА
LPC2129 При 60 МГц 55 мА
При 60 МГц VPBDIV=4 40 мА
Система прерываний LPC2000
Во время разработки программы вы скорее всего будете использовать отла-
дочные средства, подключаемые к выделенным выводам ARM7 по интерфейсу
JTAG. После перевода ЦПУ в любой из спящих режимов (Idle или Power Down)
дальнейшая отладка будет возможна только после «пробуждения» ЦПУ.
Система прерываний LPC2000
В разделе, посвященном языку Си, мы с вами узнали, как следует обрабаты-
вать такие исключительные ситуации ARM7, как неопределенная команда,
ошибка памяти и команда SWI. В этом разделе мы познакомимся с двумя остав-
шимися источниками исключительных ситуаций: прерывание общего назначе-
ния (IRQ) и быстрое прерывание (FIQ). Эти исключения используются для под-
держки различных источников прерываний, внешних по отношению к ЦПУ
ARM7. В нашем случае такими источниками являются пользовательские перифе-
рийные устройства. Для изучения структуры прерываний семейства LPC2000 нам
потребуется простой источник прерываний. В качестве такого источника можно
воспользоваться выводами внешних прерываний. Этот периферийный модуль
проще всего конфигурировать. Кроме того, к входу EINT1 на отладочной плате
подключена кнопка, с помощью которой мы сможем инициировать прерывание
и наблюдать реакцию в отладчике.
Блок управления выводами
Все контакты ввода/вывода в микроконтроллерах семейства LPC2000 имеют
дополнительные функции и подключены к встроенным периферийным модулям
через мультиплексоры, называемые блоками выбора функции выводов (pin select
block). С помощью этого блока (Рис.3.25) можно задействовать вывод в качестве
линии порта ввода/вывода общего назначения (GPIO) или же «повесить» на него
одну из трех функций.
Pinsel О
1 О
GP10 ----
TXD -----
PWM1 ------
Зарезервировано ---
РО-О
Благодаря блоку выбора функции выводов
каждый контакт ввода/вывода
может использоваться четырьмя
периферийными устройствами
Рис, 3,25, Блок выбора функций выводов
При сбросе все контакты ввода/вывода задействованы в качестве линий пор-
тов ввода/вывода общего назначения. Дополнительные функции выбираются с
помощью регистров PINSEL. К примеру, линия внешнего прерывания EINT1 яв-
ляется одновременно контактом порта ввода/вывода общего назначения Р0.14 и
линией управления модуля UART1. Поэтому для использования линии EINT1
мы должны записать в регистр выбора функции вывода соответствующее значе-
ние, подключающее вывод к схеме прерываний. 77
Глава 3. Системные периферийные устройства
Выводы внешних прерываний
Управление внешними прерываниями осуществляется с помощью четырех
регистров. Регистром EXMODE задается тип прерывания — по фронту или по
уровню. Если используется прерывание по фронту, то в регистре EXPOL задается
активный фронт (нарастающий или спадающий), при обнаружении которого бу-
дет генерироваться прерывание. Если используется прерывание по уровню, то
оно может возникнуть только при НИЗКОМ уровне на входе прерывания. С по-
мощью регистра EXWAKE можно разрешить выход процессора из режима Power
Down по внешнему прерыванию. Итак, для инициализации учебной программы
задайте для прерывания EINT1 чувствительность по уровню и подключите этот
вывод к процессору с помощью регистра PINSEL0 (Рис.3.26).
Для начального изучения
структуры прерываний
LPC2000 проще всего
в качестве источника
прерываний
воспользоваться
линиями внешних
прерываний
Рис. 3.26. Подключение линии внешнего прерывания
Структура прерываний
ЦПУ ARM7 имеет две линии внешних прерываний — одну для режима обра-
ботки запроса на быстрое прерывание (FIQ), а другую для режима обработки за-
проса на обычное прерывание (IRQ). Вообще говоря, в системах на базе ARM7
должен быть только один источник прерывания, генерирующий прерывание
FIQ, чтобы процессор мог как можно быстрее перейти в этот режим и приступить
к обработке прерывания. Из этого следует, что остальные источники прерываний
должны быть подключены к линии прерывания IRQ. В простых системах эти ис-
точники можно объединить с помощью многовходового элемента «ИЛИ». В этом
случае при возникновении прерывания процессор должен будет проверить каж-
дое периферийное устройство для определения источника прерывания, что мо-
жет занять довольно много времени. Очевидно, что нам требуется гораздо более
сложное решение. Для более эффективной обработки внешних прерываний в
микроконтроллеры был добавлен специальный модуль (Рис.3.27), называемый
векторным контроллером прерываний (Vectored Interrupt Controller — VIC).
Модуль VIC является компонентом из семейства модулей PrimeCell™, разра-
ботанных компанией ARM, и представляет собой высокооптимизированный
контроллер прерываний. Модуль VIC используется для обработки всех источни-
ков прерывания от встроенных периферийных устройств. Каждый из внутренних
78 источников прерываний подключен к определенному каналу модуля VIC; в про-
Система прерываний LPC2000
Рис. 3.27. Дополнительная аппаратная поддержка прерываний
с помощью модуля VIС
грамме каждый из этих каналов можно подключить к линиям прерываний ЦПУ
(FIQ и IRQ) одним из трех способов. Каждое прерывание может обрабатываться
как быстрое прерывание FIQ, векторное прерывание IRQ или же невекторное
прерывание IRQ (Рис.3.28). Все три типа прерываний имеют различное время от-
клика. Самым быстрым является прерывание FIQ, вслед за ним идет векторное
прерывание IRQ, ну а медленнее всего процессор реагирует на невекторные пре-
рывания IRQ. Постепенно мы рассмотрим все три метода обработки прерываний.
f Модуль VIC предоставляет три уровня"' обслуживания прерываний. Все внутренние источники прерываний могут быть размещены в любой из этих групп
ARM7TDMI nFIQ VIC « FIQ
nIRQ
< Векторное IRQ * Невекторное IRQ
Рис. 3.28. Типы прерываний
Прерывание FIQ
Любой источник прерывания может использоваться в качестве прерывания
FIQ. В регистре выбора типа прерывания модуля VIС каждому источнику преры-
вания соответствует свой бит. При установке этого бита выбранный канал конт-
роллера подключается к линии прерывания FIQ. В идеальном случае у нас долж-
но быть только одно прерывание FIQ. Тем не менее при одновременной установ-
ке нескольких битов этого регистра будет разрешено несколько источников 79
Глава 3. Системные периферийные устройства
прерываний FIQ. В этом случае с помощью регистра состояния FIQ модуля VIC
можно будет при входе в обработчик определить конкретный источник прерыва-
ния и перейти к требуемой секции обработчика. Очевидно, что наличие несколь-
ких источников прерываний FIQ замедляет переход к подпрограмме обработки
прерывания. После назначения источника прерывания FIQ, прерывание можно
разрешить, используя регистр разрешения прерываний модуля VIC. Кроме того,
необходимо сконфигурировать все периферийные устройства, генерирующие
прерывания, а также разрешить им генерацию этих прерываний. При генерации
прерывания FIQ процессор переходит в режим FIQ, а программа переходит по
адресу 0x0000001 С вектора прерывания FIQ. Для обслуживания прерывания вы
должны разместить в этом месте команду перехода к вашей подпрограмме обра-
ботки прерывания.
Выход из прерывания FIQ
Как мы с вами уже видели, объявление Си-функции в качестве обработчика
прерывания FIQ указывает компилятору использовать корректную команду воз-
врата для возобновления выполнения фонового кода с того места, где его выпол-
нение было прервано. Однако, прежде чем выйти из подпрограммы обработки
прерывания, вы должны убедиться, что флаги прерываний всех периферийных
устройств сброшены (Рис.3.29). В противном случае прерывание будет генериро-
ваться постоянно, пока соответствующий флаг не будет сброшен. И не забывай-
те, что для сброса флага вы должны записать в соответствующий ему бит регистра
не 0, а 1.
Регистр прерывания
периферийного устройства
В конце обработки прерывания флаг прерывания должен"
быть сброшен. Невыполнение этого условия приведет
к постоянной генерации одного и того же прерывания
Рис. 3.29. Сброс флага прерывания
Пример. Прерывание FIQ
Эта функция устанавливает внешнее прерывание в качестве прерывания FIQ,
а затем входит в бесконечный цикл.
void main (void)
{
IODIR1 = OxOOFFOOOO;
PINSEL0 = 0x20000000;
VICIntSelect = 0x00008000;
VICIntEnable = 0x00008000;
IOCLR1 = OxOOFFOOOO;
while(1);
80 }
// Сконфигурировать выводы СИД как выходы
// Выбрать функцию EINT1 в блоке управления
// выводами
// Подключить канал VIC к линии FIQ
// Разрешить в VIC прерывание EINT1
// Выключить светодиоды
// Бесконечный цикл
Система прерываний LPC2000
В коде стартового модуля необходимо добавить в таблицу векторов вызов под-
программы обработки прерывания FIQ. Адрес подпрограммы обработки преры-
вания FIQ начинается с суффикса ?А, означающего, что в данной подпрограмме
используется 32-битный набор команд ARM.
EXTERN CODE32 (fiqint?A)
startup PROC CODE32
Vectors: LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
NOP / * Зарезервированный вектор */
LDR PC,[PC, #-0x0FF0]
LDR PC,FIQ Addr и Загружаем адрес подпрограммы FIQ
// в PC из таблицы адресов
Reset_Addr: DD Reset_Handler
Undef_Addr: DD Undef„Handler
SWI_Addr: DD SWI_Handler
PAbt_Addr: DD PAbt_Handler
DAbt_Addr: DD DAbt_Handler
DD 0 /* Зарезервированный адрес */
IRQ.Addr: DD IRQ_Handler
FIQ_Addr: DD fiqint?A // Адрес подпрограммы FIQ хранится здесь
При нажатии кнопки INTI на плате МСВ2100 генерируется прерывание FIQ
и процессор переходит к выполнению подпрограммы fiqint(). Подпрограмма объ-
явлена как подпрограмма обработки прерываний с помощью расширения языка
_fiq. Перед возвратом из подпрограммы флаг прерывания сбрасывается.
void fiqint (void) ___fiq
{
IOSET1 = OxOOFFOOOO;
EXTINT = 0x00000002;
}
// Устанавливаем выводы СИД
// Сбрасываем флаг прерывания
Упражнение 11. Быстрое прерывание
В этом упражнении мы сконфигурируем модуль VIC таким образом, чтобы он реаги-
ровал на внешнее прерывание как на исключительную ситуацию FIQ.
Векторные прерывания IRQ
Если один из источников прерывания определен как прерывание FIQ, то ос-
тальные источники должны быть подключены к линии IRQ. Для быстрой и эф-
фективной обработки этих прерываний в модуле VIC имеется аппаратно реализо-
ванная программируемая таблица, в которой хранятся адреса Си-функций, соот-
ветствующих каждому источнику прерывания. В модуле VIC имеется 16 слотов
81
Глава 3. Системные периферийные устройства
для векторной адресации. Для каждого слота предусмотрено два регистра — ре-
гистр адреса вектора и регистр управления вектором (Рис. 3.30).
Адрес вектора
Адрес вектора по умолчанию
Адрес вектора 0
Для поддержки векторных прерываний IRQ
в модуле VIC аппаратно реализована таблица,
в которой хранятся адреса всех подпрограмм
обработки прерываний. Кроме того,
можно назначать приоритеты прерываний
всех периферийных устройств
Адрес вектора 15
Управление вектором 0
Управление вектором 15
Рис. 3.30. Слоты векторной адресации
В регистре управления вектором (VlCVectCntbcx) имеется два поля: номер ка-
нала и флаг разрешения прерывания (Рис. 3.31). Изменяя содержимое поля но-
мера канала, можно назначить соответствующему слоту любой из каналов преры-
ваний, а затем активировать его с помощью флага разрешения. Приоритет век-
торного прерывания определяется номером слота — чем меньше номер слота, тем
больший приоритет имеет прерывание.
Рис. 3.31. Регистр управления вектором
Вторым регистром для управления слотом в модуле VIC является регистр
адреса вектора (VICVectAddrxx). Как следует из его названия, в этом регистре
должен храниться адрес соответствующей Си-функции, которая будет запус-
82 каться при возникновении прерывания, связанного с данным слотом. На са-
Система прерываний LPC2000
мом деле, при генерации векторного прерывания канал прерывания подклю-
чается к заданному слоту, а адрес подпрограммы обработки прерывания, нахо-
дящийся в регистре адреса вектора данного слота, загружается в отдельный
регистр адреса вектора (Рис. 3.32). Таким образом, при генерации прерыва-
ния, сконфигурированного как векторное, адрес его обработчика будет загру-
жен в фиксированную ячейку памяти, которая называется регистром адреса
вектора (VICVectAddr).
Исключительная
ситуация
О
15
Регистры
адресов векторов
Регистр
адреса вектора
При возникновении
прерывания
содержимое регистра
адреса вектора слота,
связанного с этим
каналом прерывания,
пересылается
в выделенный регистр
адреса вектора
VICVectAddr
Рис. 3.32. Регистры адресов векторов
Пока модуль VIC выполняет все эти действия, процессор ARM7 выполняет
стандартную операцию перехода в режим IRQ и переходит по адресу вектора пре-
рывания IRQ (0x00000018). Чтобы выполнить соответствующую подпрограмму
обработки прерывания, необходимо загрузить в PC адрес из регистра адреса век-
тора модуля VIC. Следующая команда ассемблера выполняет эту операцию за
один такт:
LDA PC,[PC,#-0xFF0]
Поскольку мы уже находимся в режиме IRQ, то нам известно, что текущий
адрес равен 0x00000018 + 8 (с учетом конвейера). При вычитании из этого значе-
ния числа OxFFO произойдет переход через верхнюю границу 32-битного адрес-
ного пространства, в результате чего указанная команда загрузит в счетчик ко-
манд содержимое ячейки памяти с адресом 0xFFFFF020 (содержимое регистра
адреса вектора), Рис. 3.33.
83
Глава 3. Системные периферийные устройства
Загружаем содержимое ячейки
с адресом 0x18 - OxFFO - PC
в счетчик команд
0х00 Вектор прерывания IRQ
0x0000 0018
0xFFFF020
Регистр адреса вектора
OxFFFF FFF
При возникновении
исключительной ситуации
IRQ ЦПУ выполняет команду
LDA РС,[РС, #-0xFF0],
которая загружает
содержимое регистра
адреса вектора в РС,
вызывая переход
к подпрограмме обработки
прерывания
Рис. 3.33. Обработка векторного прерывания IRQ
Выход из прерывания IRQ
Как и в случае прерывания FIQ, вы должны убедиться в том, что флаги пре-
рываний всех периферийных устройств, генерирующих запросы на прерывание,
сброшены. Кроме того, в конце обработчика прерывания вы должны выполнить
фиктивную операцию записи в регистр адреса вектора VICVectAddr (Рис. 3.34).
Эта операция указывает модулю VIC на окончание обработки прерывания и раз-
решает обработку отложенных прерываний IRQ.
конце обработки векторного
прерывания IRQ вы, помимо сброса
флага прерывания
периферийного устройства,
должны выполнить фиктивную запись
^врегистр адреса вектора
Запись —►
Регистр адреса вектора
Сброс
Регистр прерывания периферийного устройства
Рис. 3.34. Завершение обработки векторного прерывания IRQ
Пример. Прерывание IRQ
Этот пример аналогичен примеру прерывания FIQ, но, в отличие от него, по-
казывает, как осуществляется конфигурирование модуля VIC для поддержки век-
торного прерывания IRQ.
84
Система прерываний LPC2000
В таблице векторов должна присутствовать команда, выполняющая чтение
вектора адреса VIC:
Vectors: LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI.Addr
LDR PC,PAbt_Addr
LDR NOP PC,DAbt_Addr
LDR PC,[PC, #-0x0FF0] /* Вектор из VicVectAddr */
LDR PC,FIQ_Addr
Функции на языке Си, одна из которых инициализирует модуль VIC, а другая
обслуживает прерывание, приведены ниже.
void main (void)
{
IODIR1 = OxOOOFFOOO; // Сконфигурировать выводы СИД как выходы
PINSELO = 0x20000000; // Разрешить прерывание EXTINT1
VICVectCntIO = 0x0000002F; // Выбрать слот для этого прерывания
VICVectAddrO = (unsigned)EXTINTVectoredlRQ; // Загрузить адрес обработчика
// IRQ в слот модуля VIC
VICIntEnable = 0x00008000; // Разрешить прерывание
while(1);
}
void EXTINTVectoredlRQ(void) __irq
{
IOSET1 = OxOOOFFOOO; // Установить выводы СИД
EXTINT = 0x00000002; // Сбросить флаг прерывания
VICVectAddr = 0x00000000; // Фиктивная запись для обозначения конца
// обработки прерывания
}
Упражнение 12. Векторное прерывание
В этом упражнении используется тот же источник прерываний, что и в предыду-
щем, однако модуль VIC конфигурируется таким образом, чтобы реагировать на не-
го как на исключительную ситуацию векторного прерывания IRQ.
Невекторные прерывания
Модуль VIC может обслуживать до 16 векторных прерываний IRQ и по край-
ней мере одно быстрое прерывание FIQ. Если в микроконтроллере имеется боль-
ше 17 источников прерываний, остальные могут обслуживаться как невекторные
прерывания. Все источники невекторных прерываний обслуживаются одной 85
Глава 3. Системные периферийные устройства
единственной подпрограммой обработки прерывания. Адрес этой подпрограммы
хранится в дополнительном регистре адреса вектора, называемом регистром ад-
реса вектора по умолчанию (VICDefVectAddr). Если в модуле VIC прерывание
разрешено и при этом не сконфигурировано как прерывание FIQ или же ему не
назначен слот векторного прерывания, то оно будет восприниматься как невек-
торное прерывание. При генерации такого прерывания адрес из регистра
VICDefVectAddr перегружается в регистр адреса вектора VICVectAddr, что вызыва-
ет переход процессора к этой подпрограмме (Рис. 3.35). При входе в эту подпро-
грамму ЦПУ должен прочитать регистр статуса IRQ, чтобы определить, какой из
источников невекторных прерываний сгенерировал исключительную ситуацию.
Невекторному прерыванию
соответствует
всего один слот, так что
все источники невекторных
прерываний обрабатываются
одной и той же подпрограммой
обработки прерывания
Исключительная
ситуация
Регистр
адреса вектора
по умолчанию
Регистр
адреса вектора
Рис, 3,35, Обработка невекторного прерывания
Выход из невекторного прерывания IRQ
Как и в случае векторного прерывания IRQ, вы должны сбросить флаги пре-
рываний периферийных устройств и выполнить запись в регистр адреса вектора
VICVectAddr.
Пример. Невекторное прерывание
void main (void)
{
IODIR1 = OxOOOFFOOO; // Сконфигурировать выводы СИД как выходы
PINSELO = 0x20000000; // Разрешить прерывание EXTINT1
VICDefVectAddr = (unsigned)NonVectoredlRQ; // Загрузить адрес обработчика
//в слот VIC
VIClntEnable - 0x8000; // Разрешить прерывание
while (1);
}
86
Система прерываний LPC2000
Vectors: LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
NOP
LDR PC,[PC, #-0x0FF0]
LDR PC,FIQ_Addr
/* Вектор из VicVectAddr */
void NonVectoredlRQ(void) __irq
if(VICIRQStatus & 0x00008000)// r Проверить источник прерывания
t IOSET1 = OxOOFFOOOO; EXTINT = 0x00000002; // Установить выводы СИД // Сбросить флаг прерывания
update++; ) VICVectAddr = 0x00000000; // Фиктивная запись для обозначения конца // обработки прерывания
Упражнение 13. Невекторное прерывание
В этом последнем упражнении, посвященном модулю VIC, продемонстрировано, ка-
ким образом осуществляется обработка невекторного прерывания. Это упражнение
приведено исключительно для полноты картины, поскольку данный режим практи-
чески никогда не используется.
Модуль VIC предоставляет возможность прикладному ПО генерировать пре-
рывание по любому из каналов, используя регистры программного прерывания
модуля (Рис. 3.36). Эти регистры не имеют никакого отношения к команде про-
граммного прерывания (SWI), однако позволяют протестировать источники пре-
рываний (при включении питания или же при отладке во время разработки про-
граммы).
С помощью регистров установки и сброса
программных прерываний модуля VIC
можно симулировать срабатывание любого
из источников прерываний \
Регистр программного прерывания
Источник прерывания
Рис. 3.36. Регистр программного прерывания
87
Глава 3. Системные периферийные устройства
Помимо всего прочего, в модуле VIC предусмотрен специальный защищен-
ный режим, предотвращающий доступ к любым регистрам модуля в режиме User.
Если прикладной программе требуется доступ к модулю VIC, она должна пере-
ключиться в привилегированный режим. Для этого можно использовать преры-
вание FIQ или IRQ, а также команду SWI.
Типичные значения задержек для различных прерываний приведены ниже.
В случае невекторных прерываний задержка складывается из времени реакции на
векторное прерывание и времени, необходимого для считывания регистра состо-
яния IRQ и определения источника.
• FIQ
Синхронизация прерывания
+ А л
Максимально возможное время выполнения команды
+ Переход к 1-й команде
Задержка FIQ = 12 тактов = 200 нс при тактовой частоте 60 МГц
• IRQ
Синхронизация прерывания
+ Максимально возможное время выполнения команды
+ Переход к 1-й команде
+ Обработка вложенности
Задержка IRQ = 25 тактов = 416 нс при тактовой частоте 60 МГц
Вложенные прерывания
На аппаратном уровне ЦПУ ARM7 и модуль VIC не поддерживают вложен-
ные прерывания. Если в вашей программе требуется возможность прерывать вы-
полнение подпрограмм обработки прерываний, такое поведение необходимо ре-
ализовывать программно. К счастью, это легко сделать с помощью пары макро-
сов (Рис. 3.37). Прежде чем перейти к обсуждению вложенных прерываний, я
хотел бы напомнить вам, что при обработке процессором ARM7 внешнего пре-
рывания, прерывания IRQ запрещаются. Кроме того, при входе в Си-функцию,
объявленную как обработчик прерывания IRQ, регистр LR isr сохраняется
в стеке.
После того как процессор вошел в подпрограмму обработки прерывания
IRQ, нам нужно выполнить ряд команд для включения поддержки вложенных
прерываний. Прежде всего, необходимо сохранить регистр SPSR irq, помещая
его в стек. Это позволит нам корректно восстановить состояние регистра CPSR
при возврате в режим User. Затем мы должны разрешить прерывания IRQ и пе-
рейти в режим System (напоминаю, что этот режим аналогичен режиму User, од-
нако в нем можно использовать команды MSR и MRS). В режиме System необхо-
димо сохранить новый регистр связи, т.к. в нем может храниться значение, ис-
пользуемое в фоне (в режиме User), поэтому данный регистр заносится в стек
режима System. После выполнения этих операций мы можем приступить к вы-
полнению подпрограммы обработки прерывания. После завершения обработки
запускается макрос, выполняющий обратные операции. Этот макрос восстанав-
ливает состояние регистра связи, запрещает прерывание IRQ, переключает
88
Система прерываний LPC2000
Для обработки вложенных прерываний
можно воспользоваться двумя макросами
Режим IRQ
Режим System
Рис. 3.37. Обработка вложенных прерываний
процессор в режим IRQ, окончательно восстанавливает регистр SPSRirq, после
чего обработка прерывания считается завершенной. Код описанных макросов
приведен ниже.
Me fine TENABLE /* Вход во вложенное прерывание */
asm { MRS LR, ; SPSR} /* Копируем SPSR_irq в LR */
asm { STMFD SP! , {LR}} /* Сохраняем SPSR_irq */
asm { MSR CPSR. _c, #0xlF} /* Разрешаем IRQ (режим System) */
asm { STMFD SP! , {LR}} /* Сохраняем LR */
Mefine IDISABLE / * Выход из вложенного прерывания */
asm { LDMFD SP! , {LR}} /* Восстанавливаем LR */
asm { MSR CPSR. __c, #0x92} /* Запрещаем IRQ (режим IRQ) */
asm { LDMFD SP! , {LR}} /* Восстанавливаем SPSR_irq в LR */
asm { MSR SPSR. _cxsf, LR} /* Копируем LR в SPSR_irq */
В общей сложности, этот код состоит из восьми команд (32 байта кода ARM),
а общее время выполнения обоих макросов составляет 230 нс. Описанная мето-
дика позволяет реализовать прерывание обработки какого угодно прерывания
любым другим прерыванием. Если вам необходимо установить приоритеты вло-
женных прерываний, то в макросе следует предусмотреть блокировку прерыва-
ний с низким приоритетом путем запрещения в модуле VIС источников прерыва-
ний с более низким приоритетом.
89
Глава 3. Системные периферийные устройства
Упражнение 14, Вложенные прерывания
Вот и последнее упражнение, посвященное прерываниям. В этом упражнении демон-
стрируется конфигурирование таймера для периодической генерации прерывания.
Кроме того, конфигурируется прерывание от источника EINT1. В обработчике
внешнего прерывания используется описанная выше методика, благодаря которой
даже во время выполнения подпрограммы обработки внешнего прерывания обеспечи-
вается обработка прерывания от таймера.
Резюме
Это была наиболее важная глава книги, поскольку в ней описывалась систем-
ная архитектура микроконтроллеров семейства LPC2000. Хорошее знание всех
вопросов, рассмотренных в этой главе, позволит вам наиболее оптимально кон-
фигурировать микроконтроллеры семейства для обеспечения их наибольшей
производительности в конкретных приложениях, а также предотвратит соверше-
ние большинства ошибок, допускаемых новичками.
ПЕРИФЕРИЙНЫЕ УСТРОЙСТВА
ОБЩЕГО НАЗНАЧЕНИЯ
Основные положения
Эта глава посвящена периферийным устройствам микроконтроллеров се-
мейства. Процесс конфигурирования каждого устройства и его использование де-
монстрируется на примерах. После того как вы разберетесь с работой периферий-
ных устройств, текст примеров можно будет использовать в качестве основы для
написания собственных драйверов низкого уровня.
Порты ввода/вывода общего назначения
При сбросе блок управления выводами конфигурирует все выводы перифе-
рийных устройств как входы портов ввода/вывода общего назначения (GPIO).
Управление выводами GPIO осуществляется четырьмя регистрами, как показано
на Рис. 4.1.
Вывод GPIO
РСФ
Каждый вывод GPIO управляется
соответствующим битом
в каждом из четырех регистров
модуля GPIO. Эти биты определяют
направление передачи данных,
используются для установки
или сброса бита, а также
отражают состояние вывода
Рис. 4.1. Управление выводами GPIO
91
Глава 4. Периферийные устройства общего назначения
Биты регистра IODIR позволяют индивидуально конфигурировать каждый
вывод в качестве входа (0) или выхода (1). Если вывод является выходом, его со-
стоянием можно управлять с помощью регистров IOSET и IOCLR. Запись 1 в би-
ты этих регистров приводит к установке или сбросу соответствующего вывода.
Обратите внимание, что для сброса вывода необходимо в бит регистра IOCLR за-
писать не 0, а 1! Состояние вывода GPIO можно определить в любой момент, счи-
тав содержимое регистра IOPIN. Ниже приведена программа, вызывающая мига-
ние светодиодов на демонстрационной плате.
int main(void)
{
unsigned int delay;
unsigned int flasher = 0x00010000; // Объявляем локальные переменные
IODIR1 = OxOOFFOOOO; // Все порты - выходы
while(1)
{
for(delay - 0;delay<0xl0000;delay++) // Простой цикл задержки
{
}
IOCLR1 = -flasher; // Сбрасываем соответствующие выводы // Устанавливаем соответствующие выводы
IOSET1 = flasher;
flasher = flasher << 1; if(flasher&OxOl000000) // Двигаем маску текущего СИД
flasher = 0x00010000; // Проверяем маску на переполнение
Упражнение 15. Порты ввода/вывода общего назначения
В этом упражнении демонстрируется использование GPIO для управления свето-
диодами.
Таймеры общего назначения
В составе микроконтроллеров семейства LPC2000 имеется несколько тайме-
ров общего назначения. Конкретное число таймеров зависит от модели. Тем не
менее, в любом микроконтроллере семейства имеется по крайней мере два тайме-
ра. Все таймеры общего назначения имеют одинаковую структуру и отличаются
только количеством поддерживаемых функций. Таймеры построены на базе
32-битного счетчика, объединенного с 32-битным предделителем (Рис. 4.2).
В качестве тактового сигнала во всех таймерах используется тактовый сигнал
шины VPB (Pclk)-
Скорость счета таймера зависит от значения, находящегося в регистре пред-
92 делителя. Счетный регистр предделителя будет инкрементироваться по каждому
Таймеры общего назначения
Регистр предделителя
Оба таймера и модуль ШИМ имеют идентичную
базовую структуру — 32-битный счетчик
с 32-битным предделителем
Pclk ---------► Предделитель
Счетный регистр
таймера
Сброс Разрешение
Регистр управления
таймером
Рис. 4.2. Структура таймера
импульсу сигнала Pclk Д° тех пор, пока не достигнет значения, находящегося в
регистре предделителя. В этот момент содержимое счетного регистра таймера
увеличивается на 1, счетный регистр предделителя сбрасывается в нуль и снова
начинает счет. Регистр управления таймером содержит всего два бита, использу-
ющиеся для включения/выключения таймера и для его сброса.
Наряду с основным счетчиком каждый таймер имеет до четырех каналов за-
хвата (capture). Они позволяют запоминать значение счетного регистра таймера
по изменению внешнего сигнала.
Счетный регистр
таймера
Регистр захвата
Регистр управления
каналом захвата
Рис. 4.3. Канал захвата
Каждому каналу захвата соответствует один из выводов микроконтроллера
(Рис. 4.3), использование которого может быть разрешено блоком управления
выводов. Содержимое регистра управления каналом захвата определяет, появле-
ние какого из фронтов сигнала (нарастающего, спадающего или обоих) иниции-
рует захват. При наступлении этого события текущее значение счетного регистра
таймера переписывается в соответствующий регистр захвата и, если это необхо-
димо, генерируется прерывание. В приведенном ниже фрагменте программы де-
монстрируется конфигурирование канала захвата. При такой конфигурации за-
хват будет осуществляться по нарастающему фронту сигнала на выводе Р0.2
(Capture 0.0), при этом будет генерироваться прерывание. 93
Глава 4. Периферийные устройства общего назначения
int main(void)
{
VPBDIV = 0x00000002; //
PINSELO = 0x00000020; //
T0PR = OxOOOOOOlE; //
T0TCR = 0x00000002; //
T0CCR = 0x00000005; //
T0TCR = 0x00000001; //
VICVectAddr4 = (unsigned)TOisr;
VICVectCntl4 = 0x00000024; //
VICIntEnable = 0x00000010; //
while(1);
}
void TOisr(void) ___irq
{
static int value;
Задаем Pclk = 30 МГц
Подключаем P0.2 к 0-му каналу захвата
Конфигурируем предделитель для импульсов 1 мс
Сбрасываем счетчик и предделитель
Захват по нарастающему фронту
Разрешаем таймер
// Задаем адрес обработчика прерывания
// от таймера
Задаем канал
Разрешаем прерывание
value = T0CR0; // Считываем захватываемое значение
T0IR 1= 0x00000001; // Сбрасываем флаг прерывания «совпадение по 0-му
// каналу»
VICVectAddr = 0x00000000; // Фиктивная запись для индикации завершения
// прерывания
}
Упражнение 16. Функция захвата (capture)
В этом упражнении таймер общего назначения конфигурируется таким образом,
чтобы измерять длительность импульсов, поступающих на вывод канала захвата.
Кроме того, каждый таймер имеет до четырех каналов совпадения (match).
С каждым из этих каналов связан регистр совпадения, содержащий 32-битное
число. Счетный регистр таймера непрерывно сравнивается с содержимым этого
регистра (Рис. 4.4). При совпадении их значений возникает событие «совпаде-
ние», которое может воздействовать на таймер (сбросить, остановить или генери-
ровать прерывание), а также на состояние определенного вывода микроконтрол-
лера (установка, сброс, переключение).
Чтобы использовать эту возможность таймера, загрузите в регистр совпадения
требуемое значение. Дальнейшее конфигурирование блока совпадения осуществ-
ляется посредством регистра управления блоком совпадения (Match Control
Register). В этом регистре каждому каналу сопоставлен набор битов, использую-
щихся для разрешения выполнения следующих действий по событию совпадения:
генерация прерывания от таймера, сброс таймера, останов таймера. Причем допус-
кается любая комбинация указанных действий. Кроме того, каждому каналу совпа-
дения соответствует определенный вывод микроконтроллера, состояние которого
может изменяться при совпадении. Как и в случае каналов захвата, для использо-
вания этой возможности сначала нужно с помощью блока управления выводами
подключить вывод к каналу совпадения. Состояние этих выводов соответствует со-
стоянию 4-х младших битов внешнего регистра совпадения EMR (Рис. 4.5).
Таймеры общего назначения
Рис, 4,4, Канал совпадения
Регистр EMR определяет поведение вывода канала
совпадения при возникновении события «совпадение»
в этом канале. Кроме того, ЦПУ может напрямую
управлять состоянием этих выводов, изменяя
содержимое четырех младших битов регистра
Управление выводом канала 3
i 1 Управление выводом канала 2
4 Управление выводом канала 1
Управление выводом канала О
31
Биты EMR
00
01
10
11
Нет действий
Сброс вывода
Установка вывода
Переключение вывода
Рис, 4,5, Внешний регистр совпадения
Регистр EMR содержит 4 поля, по одному на канал. Состояние битов этого
поля определяет поведение вывода совпадения при возникновении события. По-
мимо этого, в регистре имеются биты, изменяя которые можно напрямую изме-
нять состояние этого вывода.
В приведенном ниже примере показано, как с помощью двух каналов совпа-
дения можно реализовать простой широтно-импульсный модулятор. Нулевой ка-
нал используется для формирования периода ШИМ-сигнала. При возникнове-
нии события «совпадение» сбрасывается таймер и генерируется прерывание, ко-
торое используется для выдачи на выход 1-го канала напряжения ВЫСОКОГО
уровня. Первый канал используется для управления скважностью сигнала. При
95
Глава 4. Периферийные устройства общего назначения
возникновении события «совпадение» в 1-м канале выход 1-го канала сбрасыва-
ется в 0. Таким образом, изменяя содержимое регистра совпадения 1-го канала,
можно осуществлять модуляцию ШИМ-сигнала.
int main(void)
{
VPBDIV = 0x00000002; // Конфигурируем делитель VPB // Matchl - выход
PINSEL0 1= 0x00000800;
ТО PR = OxOOOOOOlE; и Загружаем предделитель
TOTCR = 0x00000002; И Сбрасываем счетчик и предделитель
T0MCR = 0x00000003; И При совпадении сбрасываем таймер и генерируем
И прерывание
T0MR0 = 0x00000010; II Устанавливаем значение периода
T0MR1 = 0x00000008; И Устанавливаем коэффициент заполнения 50%
T0EMR = 0x00000042; и При совпадении сбрасываем Matchl
TOTCR = 0x00000001;
// Разрешаем таймер
VICVectAddr4 = (unsigned)TOisr; // Задаем адрес обработчика прерывания
// от таймера
VICVectCntl4 = 0x00000024; // Задаем канал
VICIntEnable 1= 0x00000010; // Разрешаем прерывание
while(1);
}
void TOisr (void) __irq
{
T0EMR |= 0x00000002; // Устанавливаем Matchl в начале периода
T0IR 1= 0x00000001; // Сбрасываем флаг прерывания «совпадение по 0-му
// каналу»
VICVectAddr = 0x00000000; // Фиктивная запись для индикации завершения
// прерывания
}
Упражнение 17. Функция совпадения (match)
Во втором упражнении, посвященном таймерам, используются два канала совпаде-
ния для генерации ШИМ-сигнала. При этом часть ресурсов ЦПУ используется в под-
программе обработки прерывания от таймера.
Модуль ШИМ
На первый взгляд, модуль ШИМ кажется гораздо сложнее, чем таймеры об-
щего назначения. На самом же деле он представляет собой все тот же таймер,
снабженный дополнительными блоками. Модуль ШИМ (Рис. 4.6) обеспечивает
формирование до шести ШИМ-сигналов с управлением по одному фронту или
до трех — с управлением по обоим фронтам.
В таймерах общего назначения при записи нового числа в регистр совпадения
это число начинает действовать сразу же. Если не предусмотреть специальных
мер в программе, это может вызвать искажение ШИМ-сигнала. При одновремен-
ном обновлении нескольких каналов новые значения будут вступать в действие в
96
Модуль ШИМ
Совпадение 0...6
Захват 0...3
Прерывание
Рис. 4.6. Модуль ШИМ
разные моменты времени формирования импульса, что может привести к не-
предсказуемым результатам. Чтобы избежать этого, в модуле ШИМ предусмотрен
специальный механизм защелок (Рис. 4.7), позволяющий изменять значения
ШИМ «на лету», при этом новые значения будут вступать в силу одновременно и
только в начале нового периода.
Содержимое любого из регистров совпадения может быть изменено в любой
момент времени, однако оно не будет использоваться до тех пор, пока не будет ус-
тановлен соответствующий этому каналу бит в регистре управления защелкой
(Latch Enable Register — LER). После установки этого бита содержимое регистра
совпадения будет скопировано в теневой регистр в начале следующего периода.
Таким образом, гарантируется, что все изменения регистров будут осуществляться
одновременно в начале периода. Не считая этих теневых регистров-защелок, ка-
налы совпадения модуля ШИМ функционируют точно так же, как и в таймерах.
Вторым отличием модуля ШИМ от обычных таймеров является схема управ-
ления выводами микроконтроллера. Каналы совпадения управляют выводами не
напрямую, а через RS-триггеры (Рис. 4.8).
Такая схема, состоящая из RS-триггеров и мультиплексоров, позволяет фор-
мировать сигналы, управляемые по одному или по обоим фронтам. Состояние
мультиплексоров (MUX) определяется битами PWMSELx регистра управления
PWMPCR. С помощью этих мультиплексоров можно задавать одну из двух кон- 97
Глава 4. Периферийные устройства общего назначения
Рис, 4.7. Регистр-защелка
PWM1
PWM ENA1
PWM SEL2
PWM2
PWM ENA2
PWM SEL3
PWM3
PWM ENA3
Дополнительные элементы,
подключенные к выходам
каналов совпадения,
позволяют формировать
либо шесть ШИМ-сигналов,
управляемых по одному фронту,
либо три сигнала,
управляемых по обоим фронтам
Рис. 4.8. Схема управления выводами
фигураций выходных каскадов модуля. Первая конфигурация соответствует мо-
дуляции с управлением по одному фронту (Рис. 4.9).
В этой конфигурации выход 0-го канала совпадения подключается к входу S
всех триггеров, а выходы остальных каналов подключаются к входам R соответ-
98 ствующих триггеров. Таким образом, 0-й канал определяет длительность периода
Модуль ШИМ
Рис. 4.9. Модуляция по одному фронту
ШИМ-сигналов, общую для всех каналов. В конце периода 0-й канал сбрасывает
счетный регистр модуля и устанавливает свой выход в 1. В результате все триггеры
устанавливаются в начале периода ШИМ-сигнала. При этом на их выходах Q по-
является напряжение ВЫСОКОГО уровня, а на выводах микроконтроллера фор-
мируется нарастающий фронт. Модуляция ШИМ-сигнала осуществляется ос-
тальными каналами совпадения, при этом каждый канал совпадения соответ-
ствует одному каналу ШИМ. При совпадении по какому-либо каналу
соответствующий триггер сбрасывается и на выходе канала ШИМ формируется
спадающий фронт. Таким образом, модуляция осуществляется изменением со-
держимого регистра требуемого канала совпадения.
Совпадение 0
Сброс счетного регистра
Совпадение 1
Совпадение 2
ШИМ 2
ШИМ по обоим фронтам
Нулевой канал определяет период ШИМ-сигнала.
Для управления моментами формирования нарастающего
и спадающего фронтов по каждому каналу ШИМ
используются два канала совпадения
Рис. 4.10. Модуляция по обоим фронтам
Вторая конфигурация мультиплексоров соответствует модуляции ШИМ-сиг-
налов с управлением по обоим фронтам (Рис. 4.10). В этой конфигурации 0-й ка-
нал совпадения используется исключительно для сброса счетного регистра 99
Глава 4. Периферийные устройства общего назначения
модуля в конце каждого периода ШИМ-сигнала, а входы R и S триггеров под-
ключены к выходам соответствующих каналов совпадения. В начале периода на
выходе канала ШИМ присутствует напряжение НИЗКОГО уровня. Нарастаю-
щий фронт импульса формируется каналом совпадения, подключенным к входу S
триггера, а спадающий фронт — каналом, подключенным к входу R. В следую-
щем примере показано, как следует конфигурировать модуль ШИМ для форми-
рования ШИМ-сигналов с управлением по обоим фронтам.
int main(void)
PINSEL0 1= 0x00028000; PWMPR = 0x00000001; // Вывод Р0.7 - выход 2-го канала ШИМ // Загружаем предделитель
PWMPCR = 0x0000404; // 2-й канал ШИМ: управление по двум фронтам,
// выход разрешен
PWMMCR = 0x00000003; // При совпадении по 0-му каналу сбрасывать счетчик
PWMMR0 = 0x00000010; // Задаем период, равный 16 тактам
PWMMR1 = 0x00000002; // Задаем нарастающий фронт по 2-му такту
PWMMR2 = 0x00000008; // Задаем спадающий фронт по 8-му такту
PWMLER = 0x00000007; // Разрешаем теневые регистры-защелки каналов 0...2
PWMEMR = 0x00000280; // При совпадении по 1-му и 2-му каналу выход = 1
PWMTCR = 0x00000002; // Сбрасываем счетчик и предделитель
PWMTCR = 0x00000009; // Разрешаем счетчик и ШИМ
while(1) // Основной цикл
{
и } // Модулируем регистры PWMMR1 и PWMMR2
Обратите внимание: регистр PWMEMR используется для того, чтобы гаран-
тировать установку выходов каналов совпадения при наступлении соответству-
ющих событий. Если в этом регистре будет записано некорректное значение, мо-
дуль ШИМ работать не будет. Кроме того, в отличие от базового таймера, для ра-
боты модуля ШИМ не требуется, никаких прерываний.
Упражнение 18. Центрированный ШИМ
В этом упражнении модуль ШИМ используется для формирования центрированного
ШИМ-сигнала без привлечения остальных ресурсов процессора.
Часы реального времени
Модуль часов реального времени (Real Time Clock — RTC) в моделях LPC2xxx
представляет собой часы с календарем, рассчитанные до 2099 года (корректно
вычисляются високосные годы). Как и остальные периферийные устройства,
RTC работает от тактового сигнала PCLK, т.е. не требует дополнительного генера-
тора. Этот модуль имеет чрезвычайно малое потребление и способен работать от
батарей при нахождении микроконтроллера в режиме пониженного энергопот-
ребления. Наряду с поддержкой функций часов и календаря, модуль RTC имеет
100
Часы реального времени
набор сигнальных (alarm) регистров, которые можно использовать для извеще-
ния о наступлении конкретной даты и времени или же о наличии в счетном ре-
гистре конкретного значения (Рис. 4.11).
Возможно
прерывание
по инкременту
содержимого
регистра
Рис. 4.11. Модуль RTC
Модуль RTC рассчитан на стандартную частоту «часового» резонатора
32.7 кГц. Чтобы обеспечить формирование сигнала такой частоты, сигнал PCLk
проходит через делитель опорной частоты, который представляет собой програм-
мируемый делитель, позволяющий точно делить сигнал РСьк любой частоты для
формирования сигнала с частотой 32 кГц (Рис. 4.12).
Рис. 4.12. Формирование тактового сигнала RTC
Чтобы обеспечить возможность формирования тактового сигнала RTC требу-
емой частоты из любого сигнала Рськ, предделитель модуля имеет более сложную
схему, нежели предцелители таймеров общего назначения. Работа предцелителя
Глава 4. Периферийные устройства общего назначения
программируется двумя регистрами, называемыми PREINT и PREFRAC. как
можно догадаться из их названий, в них хранятся целая и дробная части коэффи-
циента деления. Значения, записываемые в регистры, вычисляются по формулам:
PREINT = (int)(PCLK/32 768) - 1,
PREFRAC = PCLK - ((PREINT + 1) x 32 768).
Таким образом, для сигнала Pclk частотой 30 МГц:
PREINT = (int)(30 ООО 000/32 768) - 1 = 914.
Тогда
PREFRAC = 30 000 000 - ((914 + 1) х 32 768) = 17 280.
После загрузки этих значений в регистры предделителя RTC модуль будет го-
тов к работе. Для запуска счетчиков модуля потребуется только разрешить фор-
мирование тактового сигнала в регистре управления CCR.
PREINT = 0x00000392; // Сконфигурируем предделитель RTC для Pclk = 30 МГц
PREFRAC = 0x00004380;
CCR = 0x00000001; // Запустим RTC
В модуле имеется 8 счетных регистров (по одному на каждый временной па-
раметр), значения которых можно прочитать в любой момент времени. Кроме то-
го, предусмотрено три групповых регистра (Рис. 4.13), отражающих те же самые
значения, что позволяет получить всю информацию о текущем моменте времени
всего за три операции чтения.
Наряду с отсчетом времени модуль RTC может формировать извещения в ви-
де прерываний. Причем имеется два механизма прерываний. Вы можете запрог-
раммировать модуль RTC таким образом, чтобы прерывание генерировалось при
инкрементировании любого счетного регистра. То есть вы можете генерировать
прерывание раз в секунду, при обновлении счетчика секунд, или раз в год, при
инкрементировании счетчика лет. Регистр управления прерыванием по инкре-
ментированию (CIIR) позволяет разрешать прерывания этого типа для каждого
из восьми счетных регистров.
Вторым источником прерываний являются сигнальные регистры. Каждый
102 счетный регистр имеет соответствующий сигнальный регистр. Если какой-либо
Часы реального времени
сигнальный регистр разрешен, то он сравнивается со счетным регистром. Когда
значения всех разрешенных сигнальных регистров совпадут с содержимым счет-
ных регистров, будет сгенерировано прерывание. То есть можно установить бу-
дильник на любое время до 2099 года с точностью до одной секунды. Какие из
сигнальных регистров будут использоваться для сравнения, определяет регистр
маски (AMR). Поскольку прерывание от модуля RTC может генерироваться и по
инкременту, и по совпадению, в обработчике прерывания необходимо различать
эти события. Для этого предусмотрен регистр типа прерывания (ILR), содержа-
щий два флага, каждый из которых устанавливается при наступлении соответ-
ствующего события. Не забывайте, что эти флаги необходимо очищать для сброса
прерывания. В следующем примере показано, как следует инициализировать ре-
гистры модуля RTC и использовать оба типа прерывания.
int main (void)
{
VPBDIV = 0x00000002;
IODIR1 = OxOOFFOOOO;
IOSET1 = 0x00020000;
PREINT = 0x00000392;
PREFRAC = 0x00004380;
CIIR = 0x00000001;
ALSEC = 0x00000003;
AMR = OxOOOOOOFE;
CCR = 0x00000001;
// Выводы СИД - выходы
// Сконфигурируем предделитель RTC для Polk =30 МГц
// Разрешаем прерывание от счетчика секунд
// Устанавливаем сигнал на 3 с
// Разрешаем сигнал секунд
// Запускаем RTC
VICVectAddrl3 = (unsigned)RTC_isr;
VICVectCntll3 = 0x0000002D; //
VICIntEnable = 0x00002000; //
while(1);
)
void RTC_isr(void)
{
unsigned led;
if(ILR&OxOOOOOOOl) //
{
led = IOPIN1; //
IOCLR1 = led&0x00030000; //
IOSET1 = ~led&0x00030000; //
ILR = 0x00000001; //
}
if(ILR & 0x00000002)
{
IOSET1 = 0x00100000; //
ILR = 0x00000002; //
}
VICVectAddr = 0x00000000; //
//
}
// Задаем адрес обработчика прерывания
// от таймера
Задаем канал
Разрешаем прерывание
Проверяем на прерывание от счетного регистра
Считываем текущее состояние выводов
Выключаем светящийся СИД
Включаем СИД «idle»
Сбрасываем флаг прерывания
Включаем СИД на Р0.7
Сбрасываем флаг прерывания
Фиктивная запись для индикации завершения
прерывания
103
Глава 4. Периферийные устройства общего назначения
Упражнение 19, Часы реального времени
В этом упражнении конфигурируется модуль RTC и демонстрируется обработка
обоих типов прерывания (по сигналу и по инкременту).
Сторожевой таймер
Как и большинство других микроконтроллеров, микроконтроллеры семей-
ства LPC2000 имеют в своем составе сторожевой таймер, используемый для вос-
становления контроля над программой в случае ее фатального сбоя.
Регистры сторожевого таймера
Встроенный сторожевой таймер может вызвать
сброс процессора или сгенерировать прерывание.
При сбросе по сторожевому таймеру
устанавливается специальный флаг, так что
ваша программа может блокировать выполнение
«мягкого» сброса
Счетчик
сторожевого
таймера
Сброс
Прерывание
Рис. 4.14. Сторожевой таймер
Как показано на Рис. 4.14, сторожевой таймер имеет четыре регистра. Период
тайм-аута сторожевого таймера определяется содержимым регистра постоянной
таймера WDTC. Значение периода тайм-аута определяется по формуле:
Wdperiod = PCLK х WDTC х 4.
Минимальное значение регистра WDTC равно 256, а максимальное — 232. Та-
ким образом, при тактовой частоте процессора 60 МГц минимальный период сто-
рожевого таймера равен 17.066 мкс, а максимальный — чуть менее 5 мин.
После записи значения постоянной сторожевого таймера можно приступать к
конфигурированию его режима работы. Регистр режима сторожевого таймера
WDMOD (Рис. 4.15) содержит три управляющих бита, два из которых определя-
ют, будет ли сторожевой таймер генерировать прерывание и сигнал сброса про-
цессора, а третий используется для разрешения работы сторожевого таймера.
Кроме того, в регистре управления имеется два флага. Один из них, WDTOF,
устанавливается при тайм-ауте сторожевого таймера и сбрасывается только после
внешнего аппаратного сброса. Это позволяет в стартовом коде вашей программы
определить, что явилось причиной сброса — включение питания или ошибка в
программе. Второй флаг является флагом прерывания сторожевого таймера. Этот
>104 флаг доступен только для чтения, а для сброса его необходимо прочитать. Если
Универсальный асинхронный приемопередатчик
Рис. 4.15. Регистр режима сторожевого таймера
вы собираетесь отлаживать программу при включенном сторожевом таймере, не
разрешайте сброс от него, поскольку это приведет к отключению JTAG-отладчи-
ка при тайм-ауте сторожевого таймера.
После задания периода тайм-аута и режима работы сторожевого таймера его
можно включить, записав в регистр запуска WDFEED определенную последова-
тельность чисел, аналогичную последовательности, требуемой для включения
схемы ФАПЧ. Для запуска сторожевого таймера вы должны записать сначала
число ОхАА, а затем число 0x55. Если эта последовательность будет нарушена,
произойдет ошибка запуска сторожевого таймера, которая вызовет тайм-аут сто-
рожевого таймера, сопровождающийся соответствующей генерацией прерыва-
ния/сброса. Также необходимо отметить, что хотя сторожевой таймер может быть
разрешен в регистре режима, он не начнет работать до первой записи требуемой
последовательности в регистр запуска. Чтобы избежать срабатывания сторожево-
го таймера после того, как он будет запущен, его необходимо периодически пере-
устанавливать, записывая ту же последовательность чисел.
Последним регистром сторожевого таймера является регистр значения
WDTV, который позволяет узнать текущее значение сторожевого таймера.
Универсальный асинхронный
приемопередатчик
В настоящее время во всех микроконтроллерах семейства LPC2000 имеется по
два модуля универсального асинхронного приемопередатчика (UART). Оба моду-
ля используются одинаковым образом, если не считать того, что в модуле UART1
реализован полный модемный интерфейс. Оба модуля соответствуют специфи-
кации «Промышленного стандарта 550». Оба модуля имеют встроенный контрол-
лер скорости передачи и 16-байтные буфера (FIFO) приема и передачи
(Рис. 4.16). 105
Глава 4. Периферийные устройства общего назначения
Разрешение прерывания
ID прерывания
9 VCC
3.3 В
Управление FIFO
Управление линией
Состояние линии
I— ТХ
RX
J.C23
Т 0.1
Сверхоперативная память
Экран
Делитель (мл. байт)
Делитель (ст. байт)
dsr^cdO
RTS°R5
CTSCfe
1
6
у
7
У
У
4
9
5
8
UART0
7 PIN2 13
С21 1
=!= 0.1
2
С1 +
С1
T2OUT С2+
МАХ3232 С2
R2IN
16
Vcc V+
R1IN
14
T1OUT
GND
T1IN
T2IN
R2OUT
R1OUT
V-
15 I б|
ф 0.1
С26
0.1
—-------- PIN 13
10
9
12
- PIN14
7
2
±
5
Puc. 4J6. Модуль UART
Инициализация модуля UART0 производится следующим образом:
void init_serial (void)
{
PINSEL0 = 0x00050000;
U1LCR = 0x00000083;
U1DLL = 0x000000C2;
U1LCR = 0x00000003;
}
/* Инициализация последовательного интерфейса */
/* Разрешаем RxDl и TxDl */
/* 8 бит, без контроля четности, 1 стоп-бит */
/* Скорость обмена 9600 бод при частоте VPB 30 МГц */
/* DLAB =0 */
Сначала программируется блок управления функцией выводов для отключе-
ния выводов микроконтроллера от портов ввода/вывода и подключения их к мо-
дулю UART Затем в регистре управления линии UART (LCR) задается формат
передачи данных (Рис. 4.17),
В нашем примере устанавливается следующий формат передаваемых данных:
8-битное слово, один стоп-бит, контроль четности выключен. В регистре LCR
имеется дополнительный бит (DLAB), управляющий доступом к регистру-защел-
ке делителя контроллера скорости передачи. Для программирования контроллера
этот бит должен быть установлен в 1.
Контроллер скорости передачи представляет собой 16-битный предделитель,
формирующий из сигнала PCLk тактовый сигнал модуля UART, частота которого
должна быть в 16 раз больше требуемой скорости передачи. Таким образом, фор-
мула для вычисления коэффициента деления имеет вид:
Divisor = Pclk/16 х BAUD.
106
Универсальный асинхронный приемопередатчик
12 О
Регистр LCR задает формат
передаваемых данных.
Установка бита DLAB позволяет
программировать контроллер
скорости передачи
Размер слова
Количество стоп-битов
Разрешение контроля четности
Тип контроля четности
Управление разрывом связи
Управление защелкой делителя
Рис. 4.17. Регистр управления линии UART
В нашем случае (Pclk = 30 МГц):
Divisor = 30 000 000/16 х 9600 - 194, или 0хС2.
Действительная скорость передачи при таком значении делителя равна
9665 бод. Часто нет возможности установить точное значение требуемой скорости
передачи, однако модуль UART будет работать даже при 5-процентном отклоне-
нии длительности битового интервала от номинальной. Благодаря этому у вас
есть определенная свобода при конфигурировании UART, если частоту PCLK не-
обходимо подбирать для получения точных временных характеристик других пе-
риферийных устройств, например для тактовой синхронизации модуля CAN. Ко-
эффициент деления делителя хранится в двух регистрах-защелках, DLM и DLL.
Первые восемь битов обоих регистров используются для хранения соответствен-
но младшего и старшего байта коэффициента деления, как показано на Рис. 4.18.
Рис. 4.18. Скорость передачи данных UART
После инициализации модуля UART данные можно передавать, записывая их
в регистр хранения передатчика (THR). Аналогично, данные можно принимать,
считывая их из регистра буфера приемника (RBR). На самом деле оба регистра за-
нимают один и тот же адрес в памяти. Запись по этому адресу помещает символ в Л 07
Глава 4. Периферийные устройства общего назначения
FIFO-буфер передачи, а чтение по этому адресу загружает символ из FIFO-буфе-
ра приема. Ниже приведены примеры подпрограмм, осуществляющих прием и
передачу символов по UART
int putchar(int ch) /* Записывает символ в последовательный порт */
{
if (ch == '\n’)
{
while (!(U1LSR & 0x20));
U1THR - CR; /* Выводим CR */
}
while (!(U1LSR & 0x20));
return (U1THR = ch) ;
}
int getchar(void) /* Читает символ из последовательного порта */
{
while (!(U1LSR & 0x01));
return (U1RBR);
}
Функции putcharQ и getcharQ предназначены для чтения/записи одного сим-
вола из/в UART. Эти низкоуровневые функции используются функциями библи-
отеки STDIO компилятора Keil, такими как printf() и scanf(). Так что, если вы хо-
тите перенаправить стандартный ввод/вывод с UART, скажем, на Ж К дисплей и
клавиатуру, перепишите эти функции для поддержки приема и передачи одиноч-
ных символов из/в требуемого устройства ввода/вывода. Обе функции putcharQ и
getcharQ считывают регистр состояния линии (LSR) для обнаружения ошибок
обмена по UART, а также для контроля состояния FIFO-буферов приема и пере-
дачи (Рис. 4.19).
31
Регистр LSR содержит набор флагов,
отображающих состояние UART.
Их состояния можно отслеживать
в цикле или же считывать
в подпрограмме обработки
прерывания от UART
п I ш
Есть принятые данные
Ошибка переполнения
Ошибка четности
Ошибка кадрирования
Разрыв связи
Регистр хранения передатчика пуст
Буфер передатчика пуст
Ошибка в FIFO приемника
Рис. 4.19. Регистр состояния линии UART
В контроллере прерываний модулю UART выделен один канал, при этом пре-
рывание может генерироваться тремя источниками. Во-первых, прерывания
108 UART могут генерироваться при изменении состояния канала приема. То есть
Универсальный асинхронный приемопередатчик
прерывание будет сгенерировано при возникновении какой-либо ошибки, для
определения которой можно прочитать регистр LSR. Остальные два источника
прерываний — это прерывания приемника и передатчика. Прерывание по при-
ему инициируется символами, помещаемыми в FIFO-буфер приема (Рис. 4.20).
Глубина буфера, при которой будет генерироваться прерывание, задается в регист-
ре управления FIFO.
16 байт
RBR
Каждый модуль UARTимеет 16-байтный
FIFO-буфер приема, который может
генерировать прерывание при заполнении
до заданного уровня. Если количество
принятых символов меньше заданного уровня,
то для их считывания можно использовать
прерывание «тайм-аут приема символов»
Порог,
определяемый
пользователем
Рис. 4.20. FIFO-буфер приема
Прерывание по приему может генерироваться после приема 1, 4, 8 или 14
символов. Пусть задана генерация прерывания при появлении в буфере восьми
символов. Тогда при приеме 34-байтного пакета будет сгенерировано четыре пре-
рывания, и два символа останутся в FIFO-буфере. Эти символы вызовут прерыва-
ние «тайм-аут приема символов» (CTI). Прерывание CTI возникает, если в FIFO-
буфере имеется один или более символов и состояние буфера не изменяется в те-
чение интервала, равного времени передачи 3.5...4.5 символов.
FIFO-буфер передачи (Рис. 4.21) генерирует прерывания при опустошении
регистра хранения передатчика (THR), а также при опустошении сдвигового ре-
гистра передатчика (TSR).
THR
Как и FIFO-буфер приема,
FIFO-буфер передачи
имеет глубину 16 байтов.
FIFO-буфер передачи
может генерировать прерывание
при опустошении и при завершении
передачи
16 байт
TSR
THR пуст
THR пуст
и TSR пуст
Рис. 4.21. FIFO-буфер передачи
109
Глава 4. Периферийные устройства общего назначения
В модуле UART1 реализована поддержка модемов. Сигналами DTR
и RTSможно управлять напрямую. При изменении состояния
модема может генерироваться прерывание UART
DCD
RI
Экран
RTS®™^
гтс© 222
CTS DTR®-
ri©-^
___GND®
3
У
7
_______У
3 КГ
8 11
4----12
5-------
5
К
2
13
14
15
6
Vcc
3.3 В
U1
Vcc
3.3 В
DSR
С4
0.1
26
T1OUT
T2OUT
R2IN
T3OUT
R1IN
T4OUT
R3IN
T5OUT
FORCEON
FORCEOFF
INVALID
СЗ 1
=г= 0.1
27
С1 +
С1
С2+
С2
T1IN
T2IN
T3IN
T4IN
T5IN
R1OUT
R2OUT
R3OUT
R1OUT8
С26
25
3
24 PIN44
23 PIN37
22 PIN29
19 PIN36
17 PIN45
21 PIN35
20 PIN30
18 PIN41
С27
0.1
GND
V-
16
CTS
Изменение DCD
Регистр
состояния
модема
Спадающий фронт RI
Изменение DSR
Изменение CTS
0
управления
модемом
RTS
Кольцевая проверка
2
Рис, 4.22. Регистры модема модуля UART1
Модуль UART1 имеет такую же базовую структуру, что и UART0, однако вдо-
бавок он позволяет управлять модемом. Для поддержки полного модемного ин-
терфейса (CTS, DCD, DSR, DTR, RI, RTS) используются дополнительные выво-
ды микроконтроллера, а в модуле имеется два дополнительных регистра (регистр
управления модемом и регистр состояния модема) и дополнительный источник
прерывания, генерирующий прерывание при изменении состояния модема
(Рис. 4.22).
Эти дополнительные возможности обеспечивают оптимальное подключение
к модему с генерацией прерывания при каждом изменении регистра состояния
модема.
Упражнение 20. UART
В 4-м упражнении мы разобрались, как использовать функции библиотеки STDIO с
модулями UART. А в этом упражнении мы посмотрим, как следует инициализиро-
вать UART для передачи данных с требуемой скоростью.
110
Интерфейс I2C
Интерфейс I2C
Поскольку компания Philips является разработчиком стандарта шины I2C,
неудивительно, что в микроконтроллерах семейства LPC2000 реализован полно-
функциональный интерфейс I2C. Модуль I2C может работать в режиме ведущего
(Master) или ведомого (Slave) со скоростью передачи до 400 Кбит/с; в режиме ве-
дущего он автоматически будет выполнять арбитраж при наличии в системе не-
скольких ведущих устройств (т.н. режим Multi-Master).
Rp= “ [кОм]
D — количество устройств
Рис. 4.23. Типовая конфигурация шины I2C
На Рис. 4.23 изображена типовая система на базе шины I2C, в которой микро-
контроллер соединен с двумя микросхемами расширителей портов. Как и в слу-
чае других периферийных устройств, в блоке управления выводами линии такто-
вого сигнала (SCL) и данных (SDA) необходимо подключить к выводам модуля
I2C.
Периферийный интерфейс I2C имеет семь регистров (Рис. 4.24). Регистру уп-
равления соответствуют два отдельных регистра, предназначенных для установки
и сброса его битов (I2CONSET и I2CONCLR). Скорость передачи данных также
определяется содержимым двух регистров (I2SCLH и I2SCLL). Регистр состоя-
ния I2STAT возвращает управляющие коды, соответствующие различным собы-
тиям на шине. Регистр данных I2DAT используется для записи каждого передава-
емого байта или для считывания каждого принимаемого байта. А когда микро-
контроллер работает в режиме ведомого, его сетевой адрес определяется
содержимым регистра адреса I2ADR.
111
Глава 4. Периферийные устройства общего назначения
В модуле I2C имеется два регистра,
задающих временные
характеристики интерфейса,
регистры установки и сброса
внутреннего регистра управления,
регистр адреса, хранящий адрес
устройства в режиме ведомого,
а также регистр данных
для посылаемых и принимаемых
байтов данных
Рис. 4.24. Периферийные регистры модуля I2C
Для инициализации интерфейса I2C в программе должны присутствовать
следующие строки:
VICVectCntll = 0x00000029;
// Выбираем слот для данного прерывания
VICVectAddrl = (unsigned)I2CISR; // Передаем адрес обработчика в модуль VIC
VICIntEnable = 0x00000200; // Разрешаем прерывание
PINSEL0 = 0x50; // Подключаем выводы микроконтроллера
// к модулю I2C
I2SCLH = 0x08; // Устанавливаем частоту тактового
// сигнала 230.4 кГц
I2SCLL = 0x08;
Чтобы модуль I2C реагировал на все события, возникающие на шине, он дол-
жен быть соответствующим образом сконфигурирован. При этом мы получаем
периферийное устройство, управляемое, в основном, по прерыванию. Итак, пер-
вое, что мы должны сделать, — это сконфигурировать векторный контроллер
прерываний для работы с прерыванием от модуля I2C. Затем необходимо скон-
фигурировать блок управления выводами, чтобы подключить линии данных и
тактового сигнала модуля I2C к выводам микроконтроллера. В завершение мы
должны задать скорость передачи, программируя регистры I2SCLH и I2SCLL.
В обоих регистрах для хранения используются только младшие 16 битов. Частота
передачи битов определяется по формуле:
Bit Freq = PCLk/(I2SCLH + I2SCLL).
В приведенном выше примере схема ФАПЧ отключена, а частота резонатора
равна 14.7456 МГц. Поэтому частота передачи будет равна:
Bit Freq = (14 745 600/4)/(8 + 8) - 230 400 Гц.
После конфигурирования микроконтроллер может осуществлять обмен дан-
ными с другими устройствами, считывая и выдавая на шину данные в качестве
ведущего либо принимая данные и отвечая на запросы другого ведущего устройс-
тва. Содержимое регистра управления модуля I2C показано на Рис. 4.25. Не забы-
112 вайте, этот регистр управляется регистрами I2CONSET и I2CONCLR.
Интерфейс I2C
31 о
Регистры управления используются
для разрешения работы модуля I2C
и прерывания,
а также для формирования на шине
состояний СТАРТ, СТОП
^и подтверждения
I2CONSET
Разрешение I2C Старт Стоп Прерывание Подтверждение
I2CONCLR
Рис. 4.25. Регистры управления модуля I2C
Рассмотрим сначала работу модуля в режиме ведущего. Для перехода в этот
режим должна быть разрешена работа модуля I2C и сброшен флаг подтвержде-
ния. Последнее действие предотвращает формирование модулем подтверждения
приема пакета от любого потенциального ведущего и соответственно переход его
в режим ведомого. В режиме ведущего микроконтроллер является инициатором
обмена данными по шине. Во время передачи данных на шине могут возникать
различные события (Рис. 4.26).
Основными этапами транзакции на шине I2C являются: формирование состояния СТАРТ,
передача адреса ведомого и обмен данными с квитированием, формирование состояния СТОП
S Адрес ведомого R/W А Данные А Данные А/А Р
О — Запись
1 — Чтение
Передаваемые данные ----
(побайтно + подтверждение)
От ведущего к ведомому
| 1 От ведомого к ведущему
А — Подтверждение (SDA — НИЗКИЙ уровень)
А — Нет подтверждения (SDA — ВЫСОКИЙ уровень)
S — Состояние СТАРТ
Р — Состояние СТОП
Рис. 4.26. Типичная транзакция на шине I2C
Ведущее устройство на шине сначала должно сформировать состояние
СТАРТ. Для этого линия SCL переводится в состояние ВЫСОКОГО уровня, пос-
ле чего линия SDA переводится в состояние НИЗКОГО уровня. Затем на шину
выдается адрес ведомого устройства, с которым хочет связаться ведущий. Адрес
сопровождается битом, указывающим тип запроса (чтение/запись). Если ведомое
устройство распознало свой адрес, оно формирует подтверждение. После этого И ИЗ
Глава 4. Периферийные устройства общего назначения
можно передавать данные в виде последовательности байтов и сигналов
подтверждения до тех пор, пока ведущее устройство не завершит транзакцию
формированием на шине состояния СТОП. Вообще говоря, модуль I2C микро-
контроллеров семейства LPC2000 можно назвать «исполнительным устройством»
шины I2C. Он контролирует все события, происходящие на шине, однако не вы-
полняет никакой интеллектуальной обработки. Это означает, что ЦПУ должен
принимать определенное участие в управлении шиной I2C во время каждой тран-
закции. К счастью, это легко осуществить, используя прерывание I2C. После пе-
ревода модуля I2C в режим ведущего, мы можем начать передачу записываемых
данных следующим образом:
void !2CTransferByte(unsigned Addr,
unsigned Data)
{
I2ADR = Addr;
I2DAT = Data;
I2CONCLR = OxOOOOOOFF;
I2CONSET = 0x00000040;
I2CONSET = 0x00000020;
11 Адрес и данные должны храниться в глобальных
// переменных, чтобы их можно было использовать
// в прерывании
// Сбрасываем все установки шины I2C
// Разрешаем интерфейс I2C
// Формируем состояние СТАРТ
}
Адрес ведомого устройства и посылаемые данные хранятся в глобальных пе-
ременных, чтобы их можно было использовать в подпрограмме обработки преры-
вания. В старших битах байта адреса находится собственно 7-битный адрес ведо-
мого устройства, а младший бит указывает тип транзакции (1 — запись, 0 — чте-
ние). После того как на шине будет сформировано состояние СТАРТ,
генерируется прерывание и из регистра состояния модуля I2C можно считать код
результата операции (Рис. 4.27).
Для каждого события на шине генерируется прерывание
и в регистре состояния возвращается код события.
Это значение используется для определения
дальнейших действий, выполняемых модулем I2C
l2Stat 0x08
0x18 0x28 0x28/0x20
S Адрес ведомого R/W А Данные А » Данные А/А Р
Рис. 4.27. Регистр состояния модуля I2C
При успешном формировании состояния СТАРТ этот код будет равен 0x08.
Считав такой код, прикладная программа должна загрузить в регистр I2DAT ад-
рес ведомого устройства с управляющим битом R/W. Эти данные будут выданы
на шину и подтверждены ведомым. При получении подтверждения генерирует-
ся новое прерывание, а в регистре состояния будет находиться (при успешной
114
Интерфейс I2C
передаче) число 0x18. Это означает, что ведомое устройство адресовано и готово
к приему данных. Теперь мы можем записывать в регистр I2DAT данные. После
записи очередного байта в регистр он передается по шине I2C и от ведомого уст-
ройства принимается подтверждение. После приема сигнала от ведомого гене-
рируется прерывание и в регистре состояния формируется число 0x28 (при ус-
пешной передаче) или 0x20 (при неуспешной). В последнем случае байт данных
необходимо передать повторно. Таким образом, после передачи каждого байта и
генерации прерывания можно проверять код состояния и передавать следую-
щий байт. После передачи всех данных можно сформировать на шине состояние
СТОП, записав соответствующее значение в регистр управления модуля I2C, и
транзакция будет завершена. Нетрудно увидеть, что подпрограмма обработки
прерывания модуля I2C представляет собой конечный автомат, который при
каждом прерывании проверяет содержимое регистра состояния и выполняет
требуемые действия. Такой автомат легко реализуется с помощью оператора
switch().
void I2CISR (void) // Подпрограмма обработки прерывания I2C
t switch (I2STAT) // Считываем код состояния и выполняем
r // следующее действие
t case (0x08): // START
I2CONCLR = 0x20; И Сбрасываем флаг состояния СТАРТ
I2DAT = l2CAddress; break; и Посылаем адрес и бит записи
case (0x18): // SLA+W, АСК
I2DAT = l2Cdata; break; и Пишем данные в регистр передачи
case (0x20): // SLA+W, NACK
I2DAT = l2CAddress; break; // Повторно посылаем адрес и бит записи
case (0x28): // Данные, АСК
I2CONSET = 0x10; break; default: break; } // Формируем СТОП
I2CONCLR = 0x08; // Сбрасываем флаг прерывания I2C
VICVectAddr = 0x00000000; // Сбрасываем прерывание в VIC
В этом примере передается только один байт, однако приведенный пример
легко доработать для передачи нескольких байтов. Также можно добавить до-
полнительные операторы выбора для поддержки запросов данных от других
ведущих.
115
Глава 4. Периферийные устройства общего назначения
Когда ведущее устройство запрашивает данные от ведомого (Рис. 4.28), со-
стояние СТАРТ будет таким же, а управляющий бит R/W в байте адреса, выда-
ваемом на шину, будет сброшен. Если после посылки адреса ведомого устройс-
тва получено подтверждение, то после него сразу же приходит первый байт дан-
ных от ведомого, т.е. ведущему устройству ничего не надо делать. Тем не менее в
обработчике прерывания мы можем установить бит подтверждения, чтобы сра-
зу же после приема байта генерировалось подтверждение ведомому. После пере-
дачи каждого байта данных их можно считывать из регистра I2DAT. После при-
ема требуемого количества байтов можно сформировать состояние СТОП и за-
вершить транзакцию.
На рисунке изображена транзакция чтения данных
ведущим устройством из ведомого
l2Stat 0x08
0x40 0x50
0x50/58
Рис. 4.28. Ведущий-приемник
Для запуска транзакции чтения можно использовать ту же функцию
I2CTransferByte(), а в обработчике прерывания необходимо добавить новые вари-
анты оператора switch():
case (0x40) : Il SLA+R, ACK // Разрешаем подтверждение для байтов данных
12CONSЕТ break; - 0x04;
case (0x48) // SLA+R, NACK
I2CONSET = 0x20; II Снова формируем состояние СТАРТ
break;
case (0x50) // Данные приняты, АСК
message = I2DAT;
I2CONSET = 0x10; /7 Формируем состояние СТОП
lock = 0; // Индицируем окончание активности на шине
break;
case (0x58): // Данные приняты, NACK
I2CONSET = 0x20; // Снова формируем состояние СТАРТ
break;
Упражнение 21. Интерфейс I2C
В этом упражнении показано, как использовать интерфейс I2C для связи с последо-
вательными микросхемами EEPROM.
116
Интерфейс SPI
Интерфейс SPI
Как и модуль I2C, модуль интерфейса SPI (Рис. 4.29) является простым пери-
ферийным «исполнительным устройством», которое может выдавать и считывать
данные на/с шины SPI, однако недостаточно интеллектуально, чтобы управлять
шиной. После инициализации интерфейса ваша программа должна будет сама
управлять процессом передачи по шине.
Шина
VPB
Регистры модуля SPI
Прерывание SPI
Рис. 4.29. Модуль интерфейса SPI
Сбой режима
Передача завершена
Модуль SPI использует четыре внешних вывода: вывод синхронизации
(SCK), вывод выбора ведомого и два вывода для передачи данных: от ведомого к
ведущему (Master In/Slave Out—MISO) и от ведущего к ведомому (Master
Out/Slave In — MOSI). В режиме ведущего на выводе синхронизации формирует-
ся тактовый сигнал, обеспечивающий передачу данных со скоростью до
400 Кбит/с, а в режиме ведомого на этот вывод поступает внешний тактовый сиг-
нал от ведущего устройства. Шина SPI разрабатывалась исключительно для высо-
коскоростной последовательной передачи данных и, в отличие от шины I2C, в
ней не реализовано никакой схемы адресации. Внешнее периферийное устройс-
тво выбирается с помощью отдельного вывода выбора ведомого. Когда микро-
контроллер функционирует в режиме ведущего, он может использовать один из
выводов порта общего назначения для управления требуемым SPI-устройством.
Ав режиме ведомого у модуля SPI есть выделенный вывод выбора ведомого и,
чтобы ведущее устройство могло обмениваться данными с микроконтроллером,
на этот вывод следует подать напряжение НИЗКОГО уровня. Два вывода переда-
чи данных подключаются к соответствующим выводам удаленного SPI-устройс-
тва; направление потока данных по этим линиям зависит от режима работы уст-
ройства (ведущий или ведомый). Типовая схема подключения к микросхеме
EEPROM показана на Рис. 4.30.
Управление модулем SPI осуществляется с помощью пяти регистров. Регистр
счета тактов определяет скорость передачи данных по шине. Тактовый сигнал
шины SPI получается простым делением сигнала Pclk на число, находящееся в
117
Глава 4. Периферийные устройства общего назначения
Рис. 4.30. Микросхема EEPROM с SPI-интерфейсом
регистре счета тактов. Минимальное значение, которое может храниться в этом
регистре, равно 8. Регистр управления предназначен для конфигурирования ши-
ны SPI. Из-за примитивного характера процесса передачи по шине SPI и широ-
кого диапазона имеющихся периферийных устройств в спецификации интерфей-
са предусмотрена возможность функционирования линий синхронизации и дан-
ных в нескольких различных режимах. Прежде всего задается полярность и фаза
тактового сигнала. Полярность может быть положительной (активный уровень —
ВЫСОКИЙ) или отрицательной (активный уровень — НИЗКИЙ), а сам такто-
вый сигнал может быть привязан к началу или середине битового интервала
(Рис. 4.31).
СРО1_ = 0
CPOL=1
Рис. 4.31. Полярность и фаза тактового сигнала
118
Г
Аналого-цифровой преобразователь
Кроме того, можно задать порядок передачи байтов, поскольку первым может
передаваться как старший (MSB), так и младший (LSB) бит байта (Рис. 4.32).
Регистр
управления
Регистр
управления
Рис. 4.32. Прямой и обратный порядок передачи байтов
Обмен по шине SPI
можно сконфигурировать
таким образом,
чтобы он соответствовал
характеристикам любого
SPI-ycmpoucmea
Каждой из указанных опций конфигурации соответствует отдельный бит ре-
гистра управления, и вы должны запрограммировать эти биты так, чтобы соот-
ветствовать характеристикам SPI-устройства, с которым собираетесь обмени-
ваться данными.
После задания скорости передачи и конфигурирования регистра управления
можно приступить к собственно обмену. В частности, для взаимодействия с мик-
росхемой EEPROM, использованной в предыдущем примере, вы должны сначала
разрешить ее работу, выставив соответствующий уровень на определенном выво-
де микроконтроллера. Последующая запись в регистр данных SPI приведет к пе-
редаче этого байта, а при чтении из регистра данных будут считываться данные,
посланные внешним устройством. Фактический формат данных, используемый в
транзакциях, будет зависеть от конкретного устройства, с которым производится
обмен.
Упражнение 22. Интерфейс SPI
В этом упражнении мы посмотрим, как следует конфигурировать модуль SPI для
работы с внешней микросхемой EEPROM, подключенной к шине SPL
Аналого-цифровой преобразователь
Модуль аналого-цифрового преобразователя (АЦП), имеющийся в ряде мо-
делей микроконтроллеров семейства LPC2000, представляет собой 10-битный
АЦП последовательного приближения с временем преобразования порядка
2.44 мкс (частота выборок чуть меньше 410 тыс. выборок/с). В зависимости от
модели микроконтроллера модуль АЦП имеет 4 или 8 мультиплексированных
входов. Программный интерфейс АЦП показан на Рис. 4.33. >|9
Глава 4. Периферийные устройства общего назначения
Am О
Ain 7
V ЗА
VSSA
Преобразователь имеет
10-битное разрешение
и 4 или 8 каналов
преобразования
Рис. 4.33. Аналого-цифровой преобразователь
Регистр управления АЦП ADCR (Рис. 4.34) определяет конфигурацию моду-
ля и управляет запуском процесса преобразования. Первым делом при конфигу-
рировании преобразователя определяется тактовая частота модуля. Как и в ос-
тальных периферийных устройствах, тактовый сигнал модуля АЦП получается из
сигнала PCLK. В данном случае сигнал PCLK следует поделить таким образом, что-
бы получить сигнал с частотой 4.5 МГц. Это максимальная частота работы модуля
АЦП, поэтому если точное значение получить нельзя, то необходимо выбрать
значение, наиболее близкое к 4.5 МГц, но не превышающее его.
31 Edge Start Test PDN CLKS Burst CLKDIV
SEL 0
Рис. 4.34. Регистр управления АЦП
В регистре
управления
задается
режим
преобразования,
рабочий канал
и разрешение
Сигнал Pclk делится на величину, равную значению, записанному в поле
CLKDIV плюс один. Таким образом, частота модуля АЦП определяется из выра-
жения:
CLKDIV=(PCLK/AdCLK)-l.
Помимо возможности отключения тактового сигнала модуля АЦП в регистре
отключения периферийных устройств (PCONP), мы можем полностью выклю-
чить данный модуль. При этом снизится потребление микроконтроллера и уро-
вень помех, создаваемых модулем. После сброса микроконтроллера модуль АЦП
выключен, поэтому, помимо задания частоты тактового сигнала, его необходимо
включить. Для этого следует записать 1 в бит PDN регистра управления. В отли-
чие от других периферийных устройств, АЦП может преобразовывать сигнал,
поступающий с выводов микроконтроллера, даже тогда, когда выводы сконфигу-
рированы как линии портов ввода/вывода. Однако, подключив эти выводы не-
посредственно к АЦП, можно значительно повысить точность преобразования.
Перед запуском преобразования необходимо задать разрядность (разреше-
ние) результата, записав соответствующее значение в поле CLKS. Хотя АЦП яв-
ляется 10-битным, разрешение результата можно задать любым, вплоть до 3-х би-
тов. Вообще, разрешение равно числу тактов тактового сигнала, приходящихся
на одно преобразование, плюс один. То есть для получения 10-битного результата
необходимо 11 тактов, а для получения 3-битного — 4 такта. После задания разре-
120 шения результата можно начинать преобразование. Модуль АЦП может работать
Аналого-цифровой преобразователь
в двух режимах: аппаратном и программном. В первом вы можете выбрать требу-
емые каналы, после чего запустить преобразование. Преобразование будет по
очереди выполняться во всех выбранных каналах до тех пор, пока не будет оста-
новлено. После завершения каждого преобразования результат можно считывать
из регистра данных АЦП (Рис. 4.35).
В регистре данных хранится результат преобразования,
а также находятся флаги ошибки переполнения данных
и завершения преобразования
31 DONE OVERUN CHN V/Vdda
О
Рис. 4.35. Регистр данных АЦП
При завершении преобразования устанавливается флаг DONE регистра дан-
ных и может генерироваться прерывание. Результат преобразования сохраняется
в поле V/Vdda в виде отношения напряжения на входе аналогового канала к на-
пряжению на выводе питания аналоговой части микроконтроллера. Вместе с ре-
зультатом в поле CHN сохраняется номер канала, в котором было выполнено
преобразование. Если же к моменту завершения преобразования результат пре-
дыдущего преобразования не был считан, он будет перезаписан и установится
флаг OVERUN. Следующий фрагмент демонстрирует использование модуля
АЦП в аппаратном режиме.
int main(void)
{
VPBDIV = 0x00000002;
IODIR1 - OxOOFFOOOO;
ADCR = 0x00270607;
VICVectCntIO = 0x00000032;
VICVectAddrO = (unsigned)AD_ISR;
VICIntEnable = 0x00040000;
while(1)
}
void AD_ISR(void)
{
unsigned val,chan;
static unsigned result[4];
val = ADDR;
val = ((val >> 6) & 0x03FF)<<16;
chan = ((ADCR >> 0x18) & 0x07);
result[chan] = val;
// Pclk =30 МГц
// Pl.16...Pl.23 - выходы
// Инициализируем АЦП: 10 бит, AINO, 3 МГц
// Выбираем слот для данного прерывания
// Передаем адрес обработчика в модуль VIC
// Разрешаем прерывание
// Читаем регистр данных
// Выделяем результат
121
Глава 4. Периферийные устройства общего назначения
Вторым режимом работы модуля АЦП является программный режим.
В данном режиме номер требуемого канала заносится в поле SEL, а преобразо-
вание по этому каналу запускается программно, путем записи в поле START
значения 0x01 (Табл. 4.1). Затем будет выполнено одно преобразование, ре-
зультат которого сохраняется в регистре данных ADDR. Окончание преобразо-
вания можно определить по прерыванию или по установке флага DONE ре-
гистра ADDR. Кроме того, преобразование в программном режиме может
быть запущено при возникновении события «совпадение» таймера 0 или тай-
мера 1, а также при обнаружении заданного фронта сигнала на выводах Р0.16
или Р0.22 микроконтроллера. Активный фронт определяется состоянием бита
EDGE регистра ADCR.
Таблица 4.1. Запуск преобразования
Поле START Запуск преобразования Преобразование может быть запущено из программы или при возникновении определенных событий
000 Остановлено
001 Запустить
010 Р0.16
он Р0.22
100 МАТ0.1
101 МАТ0.3
по МАТ 1.0
111 МАТ1.1
Простейший вариант использования модуля АЦП показан ниже.
VPBDIV = 0x00000002; // Pclk =30 МГц
IODIR1 = 0x00FF0000; // Р1.16...Р1.23 - выходы
ADCR 0x00270601; и Инициализируем АЦП: 10 бит, AIN0, 3 МГц
ADCR I= 0x01000000; II Запускаем преобразование
while(1)
{
do
{
val = ADDR; ' //Читаем регистр данных АЦП
} while((val & 0x80000000) == 0); //Ждем завершения преобразования
}
Упражнение 23. Аналого-цифровой преобразователь
В этом упражнении мы будем измерять с помощью АЦП напряжение внешнего
источника и модулировать свечение группы СИД значением результата преобра-
зования.
122
Цифро-аналоговый преобразователь
Цифро-аналоговый преобразователь
В моделях LPC2132/2138 реализован 10-битный цифро-аналоговый преобра-
зователь (ЦАП). Это очень простой в использовании модуль, управляемый всего
одним регистром.
Разрешение работы модуля ЦАП осуществляется записью 1 в биты 18 и 19 ре-
гистра PINSEL1 и переключением вывода Р0.25 с порта ввода/вывода на функ-
цию AOUT. Обратите внимание, что аналого-цифровой преобразователь тоже ис-
пользует этот вывод.
BIAS VALUE
15 6
I
О
Рис. 4.36. Регистр управления ЦАП
Модуль ЦАПуправляется
всего одним регистром. В него
записывается преобразуемое
значение вместе со значением
смещения
31
После разрешения работы модуля преобразование может быть начато за-
писью числа в поле VALUE регистра управления (Рис. 4.36). Время преобразова-
ния зависит от значения, находящегося в бите BIAS регистра. Если этот бит уста-
новлен, то преобразование займет 2.5 мкс, при этом ток нагрузки может состав-
лять 700 мкА. Если же бит BIAS сброшен, время преобразования уменьшится до
1.0 мкс, а максимальный ток нагрузки составит 350 мкА. При этом суммарное
время преобразования также зависит и от внешнего импеданса. На момент напи-
сания книги графики зависимостей импеданса для модуля ЦАП опубликованы
не были.
Упражнение 24. Цифро-аналоговый преобразователь
В этом упражнении симулируется генерация синусоидального сигнала, отсчеты ко-
торого считываются АЦП. Эти значения загружаются в ЦАП для восстановления
синусоидального сигнала. Оба сигнала можно сравнить в окне логического анализато-
ра ИС Р.
Контроллер интерфейса CAN
В ряде моделей микроконтроллеров семейства LPC2000 имеется до 4-х неза-
висимых контроллеров интерфейса CAN. Контроллер интерфейса CAN является
одним из наиболее сложных периферийных устройств микроконтроллеров се-
мейства. В этой части книги мы рассмотрим протокол CAN и модуль CAN, реа-
лизованный в семействе LPC2000.
Протокол CAN (Controller Area Network) был разработан фирмой Robert Bosch
GmbH в 1982 году для нужд автомобильной промышленности. За последующие
22 года протокол CAN стал стандартом в области создания бортовых сетей авто-
123
Глава 4. Периферийные устройства общего назначения
мобилей. Кроме того, он получил широкое распространение в областях, не
имеющих никакого отношения к автомобильной промышленности, однако
требующих объединения в сеть небольшого количества встроенных устройств.
У протокола CAN много особенностей, привлекательных для разработчиков
встраиваемых систем. Он позволяет создавать дешевые и простые в реализации
одноранговые сети с развитыми средствами контроля ошибок и скоростью пере-
дачи до 1 Мбит/с. Все пакеты в протоколе CAN довольно короткие и могут содер-
жать не более восьми байт данных. Это обстоятельство делает протокол CAN
пригодным для реализации небольших встраиваемых сетей, требующих надеж-
ной передачи критических данных между узлами.
Семиуровневая модель ISO
Протокол CAN реализует второй уровень (уровень канала передачи данных)
семиуровневой модели ISO (Рис. 4.37), т.е. формирование пакетов сообщений,
ограничение распространения ошибок (error containment), подтверждение при-
ема и арбитраж.
Объектный уровень
Обработка сообщений схемы приоритетов
Фильтрация приема
Прикладной уровень /
Уровень представлений /
Сеансовый уровень /
Транспортный уровень / /
Сетевой уровень / /
Уровень канала передачи данных /
Физический уровень
Уровень передачи
Локализация сбоев
Обнаружение ошибок
Подтверждения
Кадрирование сообщений
Арбитраж
Физический уровень
Представление битов
Скорость передачи
Уровни сигналов и временные характеристики
Среда передачи
Рис. 4.37. Семиуровневая модель ISO
В протоколе CAN отсутствует строгое определение физического уровня, по-
этому для транспортировки сообщений CAN могут использоваться различные
физические среды. Тем не менее, наиболее распространенной средой передачи
является витая пара, для которой выпускаются стандартные микросхемы драйве-
ров линии. Другие уровни модели ISO совершенно не определены, поэтому при-
кладная программа работает непосредственно с регистрами модуля CAN. Вообще
говоря, модуль CAN можно использовать так же, как и общераспространенный
UART, не реализуя дорогостоящий и сложный стек протоколов. Поскольку про-
токол CAN используется и в области автоматизации промышленного производ-
ства, существует определенное количество спецификаций ПО, определяющих,
каким образом сообщения CAN используются для передачи данных между
124 оборудованием различных производителей. Наиболее распространенными стан-
Контроллер интерфейса CAN
дартами прикладного уровня являются CANopen и DeviceNet. Единственное на-
значение этих стандартов — обеспечение взаимодействия между оборудованием
различных производителей. Если вы разрабатываете собственную закрытую сис-
тему, у вас нет необходимости использовать эти протоколы прикладного уровня,
и вы свободно можете реализовать свой внутренний протокол, как это делает
большинство разработчиков.
Структура узла сети CAN
Типичный узел сети CAN изображен на Рис. 4.38. Каждый узел состоит из
микроконтроллера и специализированного контроллера CAN. Этот контроллер
может быть расположен на одном кристалле с микроконтроллером (как в микро-
контроллерах семейства LPC2000), а может быть и отдельной микросхемой. Че-
рез драйвер контроллер CAN подсоединяется к линии на витой паре, на концах
которой подключены согласующие резисторы сопротивлением 120 Ом. Наиболее
распространенной ошибкой, совершаемой разработчиками при построении сво-
ей первой сети CAN, является отсутствие этих согласующих резисторов, без кото-
рых сеть оказывается неработоспособной.
Рис. 4.38. Структура узла CAN
Одна из важных особенностей конструкции узла сети CAN заключается в том,
что контроллер CAN имеет независимые каналы приема и передачи данных от/к
драйверу линии. Так что, одновременно с выдачей данных на шину, узел может
считывать их обратно. На этой особенности основан арбитраж сообщений и об-
наружение ряда ошибок.
Логические уровни в витой паре формируются следующим образом. Логичес-
кой единице, или свободной шине, соответствует подача на оба провода напря-
жения, равного половине разности напряжений между 0 и Vcc. Логическому ну-
лю соответствует подача на провода линии дифференциального напряжения
(Рис. 4.39).
125
Глава 4. Периферийные устройства общего назначения
Логическому нулю на шине CAN
соответствует максимальная
разность напряжений,
или так называемое
доминантное состояние,
а логической единице — свободная
шина, или так называемое
рецессивное состояние.
Доминантный бит будет
затирать рецессивный бит
Рис, 4.39. Сигналы физического уровня CAN
В терминах протокола CAN логическая единица называется рецессивным би-
том, а логический ноль называется доминантным битом. Во всех случаях доми-
нантный бит будет затирать рецессивный. То есть, если десять узлов запишут на
шину рецессивный бит, а один — доминантный, то обратно всеми узлами будет
считан доминантный бит. Шина CAN позволяет передавать данные со скоростью
до 1 Мбит/с. Обычно такая скорость достигается при длине кабеля не более 40 м.
Снижая скорость передачи, можно реализовывать более протяженные сети. На
практике с использованием стандартных драйверов можно реализовать сеть дли-
ной 1500 м со скоростью передачи 10 Кбит/с.
Объекты сообщений CAN
В спецификации шины CAN определены два объекта сообщений, которые
могут формироваться прикладным ПО. Объект сообщения используется для пе-
редачи данных по сети. Формат пакета сообщения показан на Рис. 4.40.
Пакет сообщения формируется контроллером CAN,
прикладное ПО предоставляет только байты данных,
идентификатор сообщения и значение бита RTR
S
О
F
Поле арбитража
Контроль-
ное
поле
Поле данных
Контроль ошибок и конец кадра
29-битный
идентификатор
R
т DLC
R
От 0 до 8 байтов данных
15-битный
CRC
EOF
Запрос на удаленную передачу
Код размера поля данных
126
Рис. 4.40. Пакет сообщения CAN
Контроллер интерфейса CAN
Пакет сообщения начинается с доминантного бита, являющегося призна-
ком начала кадра (Start Of Frame — SOF). Затем идет 29-битный идентифика-
тор сообщения. Идентификатор сообщения используется для идентификации
данных, посланных в этом пакете. Протокол CAN является протоколом типа
«производитель/потребитель» (producer/consumer). Каждое конкретное сооб-
щение, «произведенное» каким-либо уникальным узлом, может быть одновре-
менно «потреблено» любым количеством узлов сети. Можно осуществлять и
обмен типа «точка — точка», если сделать так, чтобы данный идентификатор
принимался только одним узлом сети. После этого сообщение может быть
послано узлом-производителем какому-либо конкретному узлу-потребителю
сети. В пакете сообщения бит RTR всегда сброшен (назначение этого бита мы
скоро обсудим). В поле DLC (Data Length Code — код длины данных) содер-
жится число от 0 до 8, показывающее количество байтов данных, передавае-
мых в пакете.
Таким образом, несмотря на то, что в сообщении можно посылать 8 байт дан-
ных, у вас есть возможность уменьшения длины пакета сообщения для сохране-
ния пропускной способности шины CAN. Вслед за байтами данных передается
15-битный циклический избыточный код. Этот код обеспечивает обнаружение и
коррекцию ошибок в битах сообщения от начала кадра до начала поля CRC. Пос-
ле поля CRC располагается слот подтверждения. Передающий узел ожидает, что
принимающий узел выставит подтверждение в этом бите во время передачи паке-
та. На практике передатчик посылает рецессивный бит, а все узлы, которые при-
няли сообщение до этой точки, выдают на шину доминантный бит, генерируя, та-
ким образом, подтверждение. То есть передатчику все равно, сколько узлов под-
твердили прием сообщения — 1 или 100. Поэтому при разработке своих программ
прикладного уровня следует учитывать, что данное подтверждение можно рас-
сматривать только как предварительное, а не полное подтверждение того, что со-
общение дошло до всех адресатов. После слота подтверждения формируется при-
знак конца кадра (End Of Frame — EOF).
Шина CAN может работать и в режиме ведущий/ведомый. Узел сети CAN мо-
жет послать по сети запрос на удаленную передачу, передав пакет сообщения, не
содержащий данных, но с установленным флагом RTR (кадр удаленного запро-
са). Этот кадр запрашивает передачу пакета сообщения с идентификатором, соот-
ветствующим идентификатору в запросе (Рис. 4.41). При приеме кадра удаленно-
го запроса узел, который формирует требуемое сообщение, передаст соответству-
ющий кадр сообщения.
Кадр RTR используется
в качестве транзакции ведущий/ведомый
для запроса пакетов сообщений от устройств,
подключенных к сети
\_______________________________________Z
S 0 F Идентификатор RTR DLC CRC АСК EOF
Рис. 4.41. Запрос на удаленную передачу
127
Глава 4. Периферийные устройства общего назначения
Как уже было отмечено, идентификатор сообщения в протоколе CAN являет-
ся 29-битным. Вообще говоря, существует две версии протокола CAN, отличаю-
щиеся только длиной поля идентификатора (см. Табл. 4.2).
Таблица 4.2 Таблица 4.3
Протокол Идентификатор
2.0А 11-битный
2.0B Passive 11 -битный
2.0В Active 29-битный
Кадре 11-битным идентификатором Кадр с 29-битным идентификатором
Модуль CAN V2.0B Active Tx/Rx ОК Tx/Rx ОК
Модуль CAN V2.0B Passive Tx/Rx ОК Игнорируется
Модуль CAN V2.0A Tx/Rx ОК Ошибка на шине
На одной шине можно использовать обе версии протокола, единственное, что
нельзя делать, — это посылать сообщения с 29-битным идентификатором уст-
ройствам стандарта 2.0 А (Табл. 4.3).
Арбитраж на шине CAN
Если планируется передача сообщения, и шина свободна, то сообщение
будет передано и сможет быть принято любым заинтересованным в нем узлом.
Если передача сообщения запланирована, а шина активна, то, прежде чем
приступить к передаче сообщения, необходимо дождаться освобождения ши-
ны. Если запланирована передача нескольких сообщений, то при освобожде-
нии шины они начнут передаваться одновременно, синхронизируясь по при-
знаку начала кадра. В этом случае на шине начнется процесс арбитража, зада-
ча которого — определить, какое именно из сообщений захватит шину и будет
передано.
Арбитраж сообщений на шине CAN осуществляется методом, который назы-
вается «неразрушающий побитовый арбитраж». На Рис. 4.42 изображены три со-
общения, ожидающих передачи. После освобождения шины и синхронизации
кадров сообщений по старт-биту, на шину начинают выдаваться все три иденти-
фикатора. При передаче первых двух битов все три узла выставляют на шину оди-
наковые логические уровни и соответственно считывают те же значения, поэтому
они все продолжают передачу. Однако при передаче третьего бита узлы А и С вы-
ставляют на шину доминантный бит, а узел В — рецессивный. То есть узел В, вы-
ставивший рецессивный бит, считывает доминантный. В этом случае он осво-
бождает шину и начинает следить за ее состоянием. Узлы А и С продолжают пере-
дачу до тех пор, пока узел С не выдаст рецессивный бит, а узел А — доминантный.
При этом узел С прекращает передачу и начинает следить за состоянием шины.
С этого момента шина захватывается узлом А, который передает свое сообщение.
После того как узел А завершит передачу, начинают передачу узлы В и С, причем
узел С захватывает шину и передает свое сообщение. Последним передает свое
сообщение узел В. Если бы узел А снова захотел передать сообщение, он бы снова
захватил шину, несмотря на то, что узлы В и С ждут ее освобождения. Таким обра-
зом, первым по шине CAN передается сообщение с наименьшим идентифика-
128 тором.
Контроллер интерфейса CAN
Арбитраж сообщений гарантирует, что наиболее важное сообщение
захватит шину и будет передано без задержки. Затем будут переданы
приостановленные сообщения согласно их приоритетам
(сообщение с наименьшим идентификатором передается первым)
Узел А
Узел В
Узел С
Узел В потерял Узел С потерял
приоритет приоритет
Рис. 4.42. Арбитраж на шине CAN
Тактовая синхронизация
В отличие от многих других протоколов последовательной передачи данных,
скорость передачи по шине CAN определяется совсем не предделителем скоро-
сти передачи. В модуле CAN есть такой делитель, однако он используется для
формирования квантов времени, т.е. временных слотов. Для передачи одного би-
та сообщения используется несколько таких квантов.
Интервал передачи бита состоит из трех сегментов (Рис. 4.43). Первым
является сегмент Sync, длительность которого фиксирована и равна одному кван-
ту времени. Следующие два сегмента называются Tsegl и Tseg2, количество кван-
тов в каждом из сегментов определяется пользователем. Наименьшее количество
квантов времени, составляющих интервал передачи бита, равно 8, а наиболь-
шее — 25. Точка выборки бита принимающим устройством расположена в конце
сегмента Tsegl, так что при изменении соотношения между Tsegl и Tseg2 точка
выборки смещается. Эта особенность позволяет подстраивать протокол CAN под
характеристики конкретного канала передачи. Если вы работаете на длинных ли-
ниях, точку выборки можно сдвинуть назад. Если используется генератор с боль-
шим дрейфом частоты, точку выборки желательно сдвинуть вперед. Более того,
принимающее устройство может подстраивать свою битовую скорость передачи
(Bit Rate — BR) для синхронизации с передающим устройством. Значение, на ко-
торое может подстраиваться каждый бит, называется шириной скачка синхрони-
зации (Synchronization Jump Width — SJW) и может быть установлено в пределах
от 1 до 4-х квантов времени. Это значение также определяется пользователем. 429
Глава 4. Периферийные устройства общего назначения
В отличие от других последовательных протоколов, интервал передачи бита
на шине CAN состоит из нескольких сегментов, благодаря чему можно подогнать
скорость передачи данных по шине к характеристикам используемого канала
i------------- Время передачи ---------►
1 бита
-1 ........................ I г-
| Tsegl|Tseg2
Sync Точка
Seg выборки
Рис. 4.43. Тактовая синхронизация на шине CAN
130
Для вычисления интервала передачи бита используется следующая формула:
BR = PClk/(BRP х (1 + Tsegl + Tseg2)),
где BRP (Baud Rate Prescaler) — значение предделителя генератора скорости пе-
редачи.
В этом выражении содержится много неизвестных. Допустим, мы хотим по-
лучить скорость передачи, равную 125 Кбит/с при Pclk = 60 МГц, и положение
точки выборки около 70%. Теперь нам остается вычислить значение BRP.
Общее количество квантов времени в интервале передачи бита равно (1 +
Tsegl + Tseg2). Назовем эту величину QUANTA и перепишем уравнение относи-
тельно значения предделителя:
BRP = PCLk/(BR х QUANTA).
Подставляя известные значения, получаем:
BRP = 60 МГц/(125К х QUANTA).
Теперь вспоминаем, что в интервале передачи бита может содержаться от 8 до
25 квантов времени. Поэтому нам надо подобрать такое целое значение перемен-
ной QUANTA между 8 и 25, чтобы получить целое значение BRP.
В нашем случае
QUANTA = 16, BRP = 30.
Тогда
16 = QUANTA = (1 + Tsegl + Tseg2).
Теперь мы можем подобрать соотношение между Tsegl и Tseg2, которое даст
нам желаемое положение точки выборки SP (Sample Point):
SP = (QUANTA х 70)/100.
Контроллер интерфейса CAN
В нашем случае 16 х 0.7 = 11.2. Этому числу соответствует Tsegl = 10,
Tseg2 = 5, а действительное положение точки выборки будет равно 68.8%.
Величину ширины скачка синхронизации можно вычислить, используя сле-
дующие эмпирические формулы:
Если
Tseg2 > 5,
то
SJW = 4.
Если
Tseg2 < 5,
то
SJW=(Tseg2— 1).
В нашем случае SJW = 4.
Передача сообщений CAN
В микроконтроллерах семейства LPC2000 каждый контроллер CAN имеет не-
сколько регистров состояния и регистров управления (Табл. 4.4), а также три бу-
фера передачи и один буфер приема.
Таблица 4.4. Регистры контроллера CAN
Название Описание
CANMOD Управление режимом работы
CANCMR Регистр управления
CANGSR Глобальный регистр состояния
CANICR Состояние прерывания
CANIER Разрешение прерывания
CANBTR Регистр тактовой синхронизации
CANEWL Предел сообщений об ошибках
CANSR Регистр состояния
Чтобы сконфигурировать контроллер, мы должны занести требуемые значе-
ния в регистр тактовой синхронизации (Рис. 4.44). Однако этот регистр является
защищенным, т.е. запись в него может осуществляться только тогда, когда конт-
роллер CAN находится в состоянии сброса. Для перевода контроллера в это со-
стояние предназначен 0-й бит регистра режима работы.
Мы можем использовать ранее вычисленные значения для инициализации
одного из контроллеров CAN для работы со скоростью 125 Кбит/с. Необходимо
отметить, что в регистр заносятся числа, которые на единицу меньше вычислен-
ных значений. Таким образом, гарантируется, что ни один из временных сегмен-
тов не будет равен нулю. После того как контроллер CAN будет инициализиро-
ван, можно сразу же передавать сообщения, записывая данные в буфер передачи.
Каждый буфер передачи контроллера может хранить до 4-х слов (Табл. 4.5).
131
Глава 4. Периферийные устройства общего назначения
SAM — Количество выборок
TSEG2 — Сегмент Tseg2
TSEG1 — Сегмент Tsegl
SJW — Ширина скачка синхронизации
BRP — Предделитель скорости передачи
Тактовая
синхронизация
модуля CAN
определяется
пятью
отдельными
параметрами
Рис. 4.44. Регистр тактовой синхронизации
Таблица 4.5. Регистры буфера передачи
Название Описание
CANTFIx Информация о передаваемом кадре
CANTIDx Идентификатор передаваемого сообщения
CANTDAx Передаваемые данные, байты 1...4
CANTDBx Передаваемые данные, байты 5...8
Два слова используются для хранения 8 байт данных, а одно — для хранения
идентификатора сообщения. Еще один регистр — регистр информации о переда-
ваемом кадре (Рис. 4.45).
FF DTR DLC PRIO
31 23 19 16 7 О
FF — Формат кадра DLC — Код длины данных
DTR — Запрос на удаленную передачу PRIO — Приоритет
Параметры
сообщения
задаются
для каждого
буфера
сообщений
Рис. 4.45. Регистр информации о передаваемом кадре
В этом регистре хранится значение поля DLC и флага RTR. Кроме того, он
содержит флаг формата кадра (FF), определяющий тип идентификатора сообще-
ния (11- или 29-битный). Поскольку имеется три буфера, можно задать внутрен-
ний приоритет каждого из них. Если планируется передача данных одновременно
из нескольких буферов, контроллер CAN будет использовать внутренний арбит-
раж для определения сообщения, передаваемого первым. Арбитраж может осу-
ществляться одним из двух способов. Если бит ТРМ регистра управления
CANMOD сброшен, первым будет передаваться сообщение, имеющее наимень-
ший идентификатор. Если же бит ТРМ установлен, то для арбитража будет ис-
пользоваться значение, находящееся в поле PRIO регистра информации о кадре,
и первым будет посылаться содержимое буфера, имеющего наименьшее значение
132
Контроллер интерфейса CAN
поля PRIO. После заполнения буфера данными сообщения начать передачу мож-
но, установив бит «Запрос на передачу» (TR) регистра CANCMR. На следующем
листинге приведены фрагменты программы, в которых выполняется инициали-
зация контроллера CAN и передача сообщения.
C2MOD = 0x00000001; C2BTR = OxOOlCOOlD; C2MOD = 0x00000000; // Переводим контроллер CAN в состояние сброса // Устанавливаем скорость передачи 125 Кбит/с // Запускаем контроллер CAN
if(C2SR & 0x00000004) // Проверяем, освободился ли 1-й буфер передачи
C2TFI1 - 0x00040000; C2TID1 - 0x00000022; C2TDA1 = NetworkData; C2CMR = 0x00000001; // Задаем DLC, равный 4 байтам // Устанавливаем адрес 0x22 (стандартный кадр) // Копируем требуемые данные в первые 4 байта // Передаем сообщение
Упражнение 25. Передача по интерфейсу CAN
В этом упражнении мы сконфигурируем второй канал CAN для работы на скорости
125 Кбит/с и начнем периодически передавать кадр сообщений.
Ограничение распространения ошибок
В спецификации протокола CAN определено пять методов ограничения рас-
пространения ошибок, реализованных на аппаратном уровне. При обнаружении
любой ошибки передающее устройство повторяет посылку сообщения, поэтому
ЦПУ не нужно вмешиваться до тех пор, пока на шине не возникнет грубая ошиб-
ка. Предусмотрено три метода обнаружения ошибок на уровне пакетов (контроль
формата, CRC и подтверждение) и два метода на уровне битов (контроль битов и
битстаффинг). Для реализации этих методов используется несколько полей, до-
бавляемых к основному сообщению. При приеме осуществляется проверка, все
ли поля присутствуют в сообщении (Рис. 4.46). Если нет, то сообщение игнориру-
ется и генерируется кадр ошибки. Это гарантирует получение полного сообще-
ния, имеющего корректный формат.
Каждое сообщение должно подтверждаться вставкой доминантного бита
в поле подтверждения (Рис. 4.47). Если подтверждение не принято, переда-
ющий узел будет передавать сообщение до тех пор, пока не получит под-
тверждения.
Пакет сообщения CAN содержит также 15-битное значение CRC ( Рис. 4.48),
которое автоматически генерируется передатчиком и проверяется приемником.
С помощью этого кода можно обнаружить и исправить ошибку в 4-х битах сооб-
щения от начала кадра до начала поля CRC. Если CRC неверен и сообщение иг-
норируется, то передается кадр ошибки.
После того как узел выиграет арбитраж, он начнет передачу своего сообщения
по шине. Как и во время арбитража, CAN-контроллер считывает обратно каждый
бит, выдаваемый им на шину. Поскольку узел уже выиграл арбитраж, больше
никто не должен передавать данные по шине, поэтому значение каждого выдан-
ного на шину бита должно соответствовать значению, считанному обратно с ши-
ны (Рис. 4.49). Если считано неверное значение, передатчик генерирует кадр
Глава 4. Периферийные устройства общего назначения
При операции контроля кадра проверяется,
имело ли принятое сообщение CAN корректный формат
Стандартный 8-байтный кадр данных
Интервал между кадрами
Должен
быть
рецессивным
1117 3
Должен
быть
доминантным
1 (Рецессивный)
◄— 0 (Доминантный)
Пауза
Конец кадра
Разделитель АСК
Слот АСК
Разделитель CRC
Значение CRC
Поле данных
Код длины данных
Зарезервированный бит (Д)
Бит IDE (Д)
Бит RTR (Д)
Поле идентификатора
Начало кадра
Рис. 4.46. Контроль кадра
Все кадры протокола CAN должны подтверждаться. Если подтверждения не было,
сообщение передается повторно
Стандартный 8-байтный кадр данных Интервал между кадрами
134
Рис. 4.47. Подтверждение
Контроллер интерфейса CAN
15-битный CRCявляется автоматически генерируемой
взвешенно-полиноминальной контрольной суммой,
которая обеспечивает контроль и коррекцию ошибок
во всем пакете сообщения
Стандартный 8-байтный кадр данных
Интервал между кадрами
В каждом кадре
сообщения /
содержится
15-битный CRC
(контрольная
сумма)
Значение CRC
вычисляется
с использо-
ванием всех
предыдущих
битов кадра
(согласующие
биты не
учитываются)
.т—г—।—-|—гт-тт ◄— 1 (Рецессивный)
1 1 1 7 3 \\\
—1—1---------◄— 0 (Доминантный)
t----------- Пауза
---------------- Конец кадра
------------------- Разде л ите л ь АС К
--------------------- Слот АСК
----------------------- Разделитель CRC
------------------------ Значение CRC
------------------------ Поле данных
------------------------ Код дл и н ы дан н ых
------------------------ Зарезервированный бит (Д)
------------------------ Бит IDE (Д)
------------------------ БитРТР(Д)
------------------------ Поле идентификатора
------------------------ Начало кадра
Рис. 4.48. CRC
После завершения арбитража используется механизм записи
и повторного считывания для побитового контроля ошибок
Стандартный 8-байтный кадр данных
Интервал между кадрами
1114
Передающий
узел ожидает,
что состояние
шины будет
соответствовать
передаваемому.
15 1 1 1
Не допускается
передача
несколькими
узлами
сообщений
с одинаковыми
иденти-
фикаторами
◄— 1 (Рецессивный)
◄— 0 (Доминантный)
------ Пауза
------ Конец кадра
------ Разделитель АСК
------ Слот АСК
------ Разделитель CRC
------ Значение CRC
------ Поле данных
------ Код длины данных
------ Зарезервированный бит (Д)
------ Бит IDE (Д)
------ БитРТР(Д)
------ Поле идентификатора
------ Начало кадра
Рис. 4.49. Ошибка контроля бита
135
Глава 4. Периферийные устройства общего назначения
ошибки и снова ставит сообщение в очередь. Это сообщение будет послано в сле-
дующем слоте сообщений, однако при этом оно должно пройти через процесс ар-
битража с другими запланированными сообщениями.
Отсюда вытекает одно из золотых правил разработки сетей CAN — каждый
идентификатор должен быть уникальным. То есть сообщения с одним и тем же
идентификатором не должны посылаться двумя различными узлами. В этом слу-
чае возможно возникновение ситуации, при которой два сообщения с одинако-
выми идентификаторами начнут передаваться одновременно, оба будут бороться
за контроль над шиной и оба выиграют арбитраж, поскольку имеют одинаковые
идентификаторы. После выигрыша арбитража оба сообщения начнут выставлять
свои данные на шину. В какой-то момент данные окажутся различными, что при-
ведет к возникновению ошибки контроля бита. Оба сообщения будут снова
поставлены в очередь передачи, выиграют арбитраж и снова вызовут ошибку.
В принципе, эта «тупиковая ситуация» может полностью заблокировать сеть, так
что будьте внимательны!
На уровне битов в протоколе CAN реализован также метод вставки бита
(битстаффинг). После каждой последовательности из пяти доминантных битов
вставляется рецессивный бит (Рис. 4.50).
После каждой последовательности из пяти единичных битов
вставляется нулевой бит. Исключением из этого правила является кадр ошибки,
представляющий собой последовательность из шести доминантных битов
Арбитраж/данные
Рис. 4.50. Битстаффинг
Этот метод позволяет предотвратить появление на шине постоянных уровней
и обеспечивает наличие в потоке битов достаточного количества переходов, ис-
пользуемых для повторной синхронизации. Кадр ошибки в протоколе CAN пред-
ставляет собой простую последовательность из шести доминантных битов. Это
позволяет любому контроллеру CAN формировать на шине сообщение об ошиб-
ке сразу же после ее обнаружения, не дожидаясь конца сообщения. В каждом
контроллере CAN имеется два счетчика ( Рис. 4.51).
Этими счетчиками являются счетчик ошибок приема и счетчик ошибок пере-
дачи. Изменение состояния этих счетчиков происходит при приеме или передаче
кадра ошибки. Когда любой счетчик достигает значения 128, контроллер CAN
переходит в режим «error passive». В этом режиме он продолжает отзываться на
кадры ошибки, однако при генерации кадра ошибки он вместо доминантных би-
тов выставляет на шину рецессивные. Если счетчик ошибок передачи достигает
значения 255, то контроллер CAN переходит в режим «bus-off» и больше не при-
136 нимает участия в обмене по шине. Для возобновления обмена необходимо
Контроллер интерфейса CAN
Сброс
и конфигурирование
Контроллер CAN переходит между
несколькими состояниями ошибки,
что позволяет при сбое узла избежать
блокирования шины
REC — Счетчик ошибок приема
ТЕС — Счетчик ошибок передачи
Рис. 4.51. Счетчики ошибок
вмешательство процессора, который повторно инициализирует контроллер и
подключает его обратно к шине. Оба этих механизма предназначены для того,
чтобы узел при возникновении неисправности не заблокировал шину непрерыв-
ной генерацией кадров ошибки.
Контроллер CAN, реализованный в микроконтроллерах семейства LPC2000,
имеет несколько механизмов обнаружения ошибок. Прежде всего из глобального
регистра состояния CANGSR можно считать текущее состояние счетчиков оши-
бок приема и передачи.
Также в этом регистре имеется два флага ошибок. Флаг состояния шины (BS)
устанавливается при достижении максимального количества ошибок и отключе-
нии контроллера CAN от шины. Второй флаг, флаг состояния ошибки (ES), уста-
навливается при достижении счетчиками ошибок порогового значения. Это зна-
чение является произвольной величиной, записываемой в регистр CANEWL. По
умолчанию в этом регистре находится число 96. Как и регистры тактовой синхро-
низации, регистр CANEWL можно изменять только при нахождении контролле-
ра в состоянии сброса. Кроме того, регистр захвата прерывания CANICR предо-
ставляет огромное количество диагностической информации для управления со-
бытиями на шине CAN.
В контроллере CAN имеются следующие источники прерываний:
1. Прерывание передачи (по одному для каждого буфера)
2. Прерывание приема
3. Предупреждение об ошибке (Error Warning)
4. Перезапись данных (Data Overrun)
5. Пробуждение (Wake Up)
6. Режим ошибки (Error Passive)
7. Потеря арбитража (Arbitration Lost)
8. Ошибка на шине (Bus Error)
9. Готовность идентификатора (ID Ready)
137
Глава 4. Периферийные устройства общего назначения
Прием сообщений CAN
После инициализации контроллер CAN также может принимать сообщения в
свой буфер приема, структура которого (Табл. 4.6) похожа на структуру буфера
передачи.
Таблица 4,6, Регистры буфера приема
Название Описание
CANRFS Состояние принятого кадра
CANRID Идентификатор принятого сообщения
CANRDA Принятые данные, байты 1...4
CANRDB Принятые данные, байты 5... 8
Регистр состояния принятого кадра CANRFS содержит ту же информацию,
что и регистр информации о передаваемом кадре. При этом в регистре CANRFS
есть еще два дополнительных элемента — поле индекса идентификатора и флаг
ВР. Эти параметры мы рассмотрим в следующем подразделе.
В следующем примере программы показано, как осуществляется прием сооб-
щения CAN:
int main(void)
{
VPBDIV IODIR1 = 0x00000001; = OxOOFFOOOO; // Устанавливаем Pclk = 60 МГц // Все порты - выходы
PINSEL1 1= 0x00040000; // Р0.25 - CAN1 RX
C1MOD = 0x00000001; // Переводим контроллер CAN в состояние
// сброса
C1BTR = OxOOlCOOlD; // Устанавливаем скорость передачи
// 125 Кбит/с
C1IER = 0x00000001; // Разрешаем прерывание приема
VICVectCntIO = ОхООООООЗА; // Задаем слот для данного прерывания
VICVectAddrO = (unsigned)CAN1IRQ; // Передаем адрес обработчика в VIC
VICIntEnable = 0x04000000; // Разрешаем прерывание
AFMR - 0x00000001; // Запрещаем фильтрацию сообщений
C1MOD = 0x00000000; // Запускаем контроллер CAN
while(1)
}
}
void CAN1IRQ (void) ____irq
{
IOCLR1 = -C1RDA;
IOSET1 = C1RDA;
C1CMR = 0x00000004;
VICVectAddr = 0x00000000;
// Сбрасываем выходы
// Устанавливаем выходы
// Освобождаем буфер приема
// Индицируем завершение прерывания
138 >
Контроллер интерфейса CAN
Фильтрация сообщений
Несмотря на то что приведенный выше пример программы приема сообще-
ний будет вполне хорошо работать, он имеет два недостатка. Во-первых, будут
приниматься все сообщения, передаваемые по шине. В случае полностью загру-
женной шины CAN это означает, что сообщения будут приниматься каждые
72 мкс. Так как микроконтроллер семейства может иметь до 4-х контроллеров
CAN, ЦПУ придется потратить массу времени только для управления шинами
CAN. Во-вторых, после приема сообщения контроллер CAN должен прочитать и
декодировать идентификатор сообщения, чтобы решить, что с ним делать. Для
преодоления этих проблем контроллеры CAN семейства LPC2000 имеют разви-
тую схему фильтрации сообщений. Фильтр сообщений используется в качестве
экрана между контроллером и шиной CAN. Его можно запрограммировать на
пропуск или блокировку поступающих на обработку в контроллер CAN сообще-
ний с определенными идентификаторами. Это предотвращает загрузку в буфер
приема контроллера нежелательных сообщений и, соответственно, значительно
уменьшает непроизводительные затраты ресурсов ЦПУ. В составе фильтра сооб-
щений имеется блок ОЗУ объемом 2К (512 х 32), которое может использоваться в
качестве таблицы идентификаторов (Рис. 4.52). Благодаря наличию такой табли-
цы в буфер приема контроллера CAN могут проходить как отдельные сообщения,
так и заданные диапазоны сообщений.
5. Если разрешено, генерируется
прерывание приема
IRQ
3. При обнаружении соответствия
сообщение загружается
в буфер приема
4. Значение INDEX
загружается в регистр CANRFS
Каждый модуль CAN имеет
блок ОЗУ объемом 2К,
используемый для хранения
таблиц фильтра.
Они обеспечивают
эффективную обработку
сообщений при большой
загрузке шины,
не приводящую
к перегрузке ЦПУ
Фильтр сообщений
стаблицей
1. Принято сообщение CAN
2. Сканируются таблицы
Рис, 4.52. Фильтрация сообщений
139
Глава 4. Периферийные устройства общего назначения
После прохождения сообщения через фильтр, ему присваивается определен-
ный индекс — целое число, соответствующее смещению идентификатора сооб-
щения в таблице фильтра сообщения. Значение индекса сохраняется в регистре
состояния принятого кадра. Таким образом, чтобы определить, какое именно со-
общение было принято, вместо декодирования самого идентификатора гораздо
быстрее и проще использовать его индекс.
1. Принято
сообщение CAN
В режиме FullCAN
блок ОЗУ контроллера может
использоваться в качестве
дополнительных буферов приема,
в которых будут храниться
полученные данные.
ЦПУ будет считывать
эти данные
по мере необходимости
\_______________________________/
3. При нахождении
соответствия
сообщение загружается
в уникальный
буфер сообщения
Рис, 4.53. Режим FullCAN
2. Идентификатор
ищется в таблицах
ЦПУ может прочитать
сообщения в любой
момент времени
Фильтр сообщений, кроме того, может работать в режиме FullCAN
(Рис. 4.53). В этом режиме также осуществляется прием сообщений и поиск в
таблице допустимых идентификаторов. Однако при нахождении соответствия со-
общение загружается не в приемный буфер контроллера CAN, а в специальный
буфер, расположенный в памяти блока фильтрации сообщений. При этом каждое
сообщение имеет свой уникальный буфер с фиксированным адресом, что обеспе-
чивает легкий доступ процессору ко всем данным, принятым с шины.
140
Контроллер интерфейса CAN
Конфигурирование фильтра сообщений
Конфигурация фильтра сообщений определяется семью регистрами. Управ-
ление фильтром осуществляется через регистр режимов, следующие пять регист-
ров используются для конфигурирования различных таблиц идентификаторов, а
последний регистр является регистром сообщений об ошибках.
Прежде чем приступить к конфигурированию фильтра сообщений, его необ-
ходимо отключить. Эта операция выполняется установкой бита AccOff и сбро-
сом бита АссВР регистра режимов (Рис. 4.54). Если при такой конфигурации за-
пустить контроллер CAN, он будет принимать все сообщения, появляющиеся на
шине.
Рис. 4.54. Регистр режима
После отключения фильтра сообщений можно приступить к конфигурирова-
нию любой из четырех следующих таблиц:
• Индивидуальные стандартные идентификаторы
• Группы стандартных идентификаторов
• Индивидуальные расширенные идентификаторы
• Группы расширенных идентификаторов
(11-битный ID)
(11-битный ID)
(29-битный ID)
(29-битный ID)
Область ОЗУ фильтра сообщений начинается с адреса 0хЕ0038000. Каждая
таблица должна быть определена и размещена по конкретному адресу ОЗУ
фильтра. Начальные адреса каждой таблицы затем заносятся в соответствующие
регистры фильтра сообщений. Таблицы должны начинаться с первого адреса ОЗУ
и располагаться в памяти непрерывно. Адрес последней используемой ячейки
ОЗУ необходимо записать в регистр адреса конца таблиц ENDofTable. После это-
го включите фильтр сообщений установкой бита ACCoff и сбросом бита АссВР.
Форматы соответствующих таблиц приведены на Рис. 4.55, 4.56, 4.57.
31 29 26 16
15 13 10 0
№ контроллера Запре- тить Не исп. Идентификатор
Рис. 4.55. Формат таблицы индивидуальных стандартных идентификаторов
141
Глава 4. Периферийные устройства общего назначения
Таблица индивидуальных стандартных идентификаторов позволяет вам опре-
делить отдельные 11-битные идентификаторы, которые будут пропускаться
фильтром сообщений. Каждое определение занимает два байта, 11 первых битов
которых содержат идентификатор пропускаемого сообщения. Затем идет флаг, с
помощью которого можно динамически разрешать/запрещать данный элемент
фильтра. Старшие три бита устанавливают соответствие между данным элемен-
том фильтра и конкретным контроллером CAN.
31 29 26 16
№ контроллера Запретить Не исп. Наименьший идентификатор группы № контроллера Запретить Не исп. Наибольший идентификатор группы
Рис. 4.56. Формат таблицы групп стандартных идентификаторов
В таблице групп стандартных идентификаторов используется тот же формат,
просто в каждом элементе таблицы используется два определения, устанавливаю-
щие нижнюю и верхнюю границы диапазона идентификаторов сообщений, про-
пускаемых фильтром.
31 29 28
О
№ контроллера Идентификатор
Рис. 4.57. Формат таблицы индивидуальных расширенных идентификаторов
В таблице индивидуальных расширенных идентификаторов для каждого эле-
мента таблицы используется 4 байта, как показано на Рис. 4.57. Первые 29 битов
определяют идентификатор сообщения, пропускаемого через фильтр, а старшие
3 бита устанавливают соответствие между данным элементом фильтра и конкрет-
ным контроллером CAN. В каждом элементе таблицы групп расширенных иден-
тификаторов используются два слова в этом же формате, определяющие началь-
ное и конечное значения идентификаторов, аналогично таблице групп стандарт-
ных идентификаторов.
В следующем примере показано, как можно сконфигурировать фильтр при-
ема для работы в базовом режиме.
unsigned int StandardFilter[2] _at_ 0xE0038000; // Объявляем стандартную таблицу
// фильтра сообщений
unsigned int GroupStdFilter[2] _at_ 0xE0038008; // Объявляем стандартную
// групповую таблицу фильтра
unsigned int IndividualExtFilter[2] _at_ 0xE0038010; // Объявляем расширенную
// таблицу фильтра
unsigned int GroupExtFilter[2] _at_ 0xE0038018; // Объявляем расширенную
// групповую таблицу фильтра
>|Д2 AFMR = 0x00000001;
// Выключаем фильтр приема для конфигурирования таблиц
Полноскоростной интерфейс USB 2.0
StandardFilter[0] = 0x20012002;
StandardFilter[1] = 0x20032004;
// Инициализируем стандартную таблицу
// Разрешаем идентификаторы 1, 2, 3 и 4
SFF.sa = 0x00000000; // Указываем начальный адрес стандартной таблицы
SFF_GRP_sa = 0x00000010; // // Указываем групповой начальный адрес стандартной таблицы
EFF_sa = 0x00000018; // Указываем начальный адрес расширенной таблицы
EFF_GRP_sa = 0x00000020; // // Указываем групповой начальный адрес расширенной таблицы
ENDofTable = 0x00000028; // Указываем адрес конца таблиц
AFMR = 0x00000000; // Включаем фильтр приема
C1MOD = 0x00000000; // Запускаем контроллер CAN
Упражнение 26. Прием по интерфейсу CAN
Как и в предыдущем упражнении, в этом упражнении мы сконфигурируем второй ка-
нал CAN для работы на скорости 125 Кбит/с, а фильтр приема — для приема одного
из трех кадров сообщения.
Полноскоростной интерфейс USB 2.0
Одним из наиболее сложных периферийных устройств микроконтроллеров
семейства LPC2000 является модуль интерфейса USB, входящий в состав моделей
LPC214x. Чтобы досконально разобраться в работе этого модуля, вы должны хо-
рошо понимать принципы работы шины USB, а также принципы организации
систем на основе этой шины. Кроме того, вы должны иметь представление о том,
как следует писать программы для ПК, чтобы они могли работать с шиной USB.
Таким образом, от вас потребуется значительный объем дополнительных знаний,
а также навыки программирования для ПК (в частности, для операционных сис-
тем семейства Windows), что, как правило, находится вне компетенции разработ-
чика программного обеспечения встраиваемых систем.
Введение в USB
Прежде чем приступить к изучению собственно модуля интерфейса USB, да-
вайте разберемся, что представляет собой шина USB. Первоначально (в
Windows 98) поддержка интерфейса USB осуществлялась установкой дополни-
тельных драйверов. В последующих версиях Windows (2000 и ХР) эти драйверы
вошли в состав системы. Разработка шины USB преследовала несколько целей,
основной из которых было обеспечение простого подключения внешних уст-
ройств к ПК по принципу «plug and play» (подключи и работай). Первая офици-
альная версия стандарта на шину USB (спецификация USB 1.0) была опублико-
вана в 1996 году. Вскоре, в 1998 году, появился доработанный вариант (специфи-
кация USB 1.1). В настоящее время используется спецификация USB 2.0,
опубликованная в 2000 году. Поддержка спецификации осуществляется форумом
разработчиков USB (www.usb.org). На этом сайте можно найти подробную доку-
ментацию по всем версиям стандарта. Модуль USB на базе LPC214x поддержива-
ет спецификацию USB 2.0, поэтому мы будем работать именно с этой версией до-
кумента. 143
Глава 4. Периферийные устройства общего назначения
Физическая организация шины USB
Шина USB поддерживает три режима передачи (Табл. 4.7): низкоскоростной
(Low Speed LS), полноскоростной (Full Speed — FS) и высокоскоростной (High
Speed — HS). Низкоскоростной режим обеспечивает скорость передачи до
1.5 Мбит/с и используется для подключения простых устройств, таких как клави-
атура и мышь. Полноскоростной режим обеспечивает скорость передачи уже до
12 Мбит/с и подходит практически для всех остальных периферийных устройств
ПК. Самым быстрым является высокоскоростной режим, скорость передачи в
котором может достигать 480 Мбит/с. Этот режим предназначен для видеоуст-
ройств, которым требуется широкая полоса пропускания.
Таблица 4.7. Режимы передачи по шине USB
Скорость Применение Отличительные особенности
Низкоскоростной режим (LS) Устройства ручного ввода 10... 100 Кбит/с Клавиатуры, мыши, игровые манипуляторы, конфигурирование мониторов Низкая стоимость, «горячее» подключение, простота использования, разнообразная периферия
Полноскоростной режим (FS) Телефония, звук, сжатое видео 500 Кбит/с... 10 Мбит/с Принтеры, сканеры, телефонная аппаратура, аудиоаппаратура Низкая стоимость, «горячее» подключение, простота использования, гарантированные задержки, гарантированная ширина полосы пропускания, разнообразная периферия
Высокоскоростной режим (LS) Видео, устройства хранения 25...480 Мбит/с Видеоаппаратура, устройства массовой памяти Высокая пропускная способность, гарантированные задержки, простота использования
В спецификации USB также определены физические параметры соедини-
тельных кабелей и разъемов. Благодаря этому гарантируется, что любой пользо-
ватель вставит вилку именно в соответствующее ей гнездо. Фотографии двух раз-
личных соединителей показаны на Рис. 4.58. Полные спецификации на эти вил-
ки и соответствующие им розетки можно найти на сайте www.usb.org.
В USB-xocmax
и периферийных устройствах
используются стандартизованные
вилки и розетки, что обеспечивает
легкость соединения
Рис. 4.58. Два варианта вилки USB
Кабель состоит из четырех экранированных проводников (Рис. 4.59). По двум
из них передается напряжение питания, а два других используются для передачи
данных. На линии питания подается напряжение +5 В, потребляемый ток не дол-
144 жен превышать 500 мА. Линии данных обозначаются как D+ и D—. Максималь-
Полноскоростной интерфейс USB 2.0
ная длина экранированного кабеля для полноскоростной передачи равна пяти
метрам. Поскольку трансивер физического уровня шины USB уже встроен в мик-
роконтроллер, разработчику достаточно просто соединить линии данных D+ и
D- с соответствующими контактами микроконтроллера, добавив, как мы увидим
позже, пару внешних элементов.
Стандартный USB-кабель
состоит из 4 проводников:
два проводника для питания
(Vbus и GND) и два проводника
для передачи данных (D+ и D-)
Рис. 4.59. Структура USB-кабеля
Передача сигналов по шине осуществляется с использованием метода NRZI
(Non Return to Zero Inverted — кодирование без возвращения к нулю и с инверси-
ей). То есть изменение логического уровня на шине USB происходит всякий раз,
когда в потоке данных появляется нулевой бит (Рис. 4.60). Использование этого
метода позволяет удален ным устройствам выделять данные и тактовый сигнал, по
которому они синхронизируются. Поскольку на физическом уровне реализация
шины USB довольно сложна, вам, как правило, не требуется изучать сигналы,
присутствующие на ней. Отладка обычно ограничивается исследованием тран-
закций на уровне пакетов данных. Тем не менее, существует определенная терми-
нология, которую нужно знать, чтобы ориентироваться при рассмотрении про-
цесса передачи данных на битовом уровне. В полноскоростном USB-кабеле логи-
ческой единице соответствует напряжение +5 В; это состояние обозначается
символом К (K-state). Логическому нулю соответствует напряжение 0 В, а обоз-
начается это состояние символом J (J-state). Обратите внимание, что при переда-
че данных в низкоскоростном режиме полярность сигналов на шине инвертиру-
ется, т.е. состояние К соответствует напряжению 0 В, а состояние J — напряже-
нию +5 В.
Для формирования битового потока используется кодирование по методу NZRI
(кодирование без возвращения к нулю и с инверсией).
Это позволяет передавать данные вместе с тактовым сигналом,
который восстанавливается приемником
Idle 01101000111010
ДАННЫЕ
NRZI
Рис. 4.60. Формирование битового потока на шине
145
Глава 4. Периферийные устройства общего назначения
Физическое соединение устройств осуществляется по топологии многоярус-
ной звезды, как показано на Рис. 4.61. Корневым узлом на шине должен быть ПК
(или другой контроллер), имеющий один порт для подключения периферийного
USB-устройства. Если требуется подсоединить большее количество периферий-
ных устройств, к порту корневого узла можно подключить так называемый хаб
(hub), который обеспечит требуемое количество портов. При большом количестве
периферийных устройств в сеть можно включать другие хабы, обеспечивающие
дополнительные порты USB. В общей сложности в сети USB может быть 127 узлов
(хабов и устройств), шесть ярусов хабов и один контроллер шины (bus master).
Физическое соединение устройств
осуществляется по топологии
многоярусной звезды, имеющей
до 127узлов и до шести ярусов
Рис, 4.61. Физическая топология шины USB
Логическая организация шины USB
В отличие от физической организации, на логическом уровне шина USB име-
ет топологию обычной звезды. То есть если программист не работает именно с ха-
бами, то для него они, по существу, невидимы. Так что не имеет значения, к како-
му порту будет подключаться разрабатываемое вами устройство — к корневому
порту ПК или же к порту одного из дополнительных хабов. Таким образом, для
разработчика шина USB представляет собой обычную сеть с топологией звезды, в
центре которой находится ПК, а все устройства являются адресуемыми узлами,
как показано на Рис. 4.62. Другой особенностью шины USB является ее построе-
ние по схеме «ведущий — ведомый». Работой всей шины управляет ПК, являю-
щийся единственным устройством, способным инициировать обмен данными.
В соответствии со спецификацией USB 2.0 обмен данными между узлами невоз-
можен, поэтому устройство, построенное на базе микроконтроллера LPC214x,
может работать только в качестве ведомого. В настоящее время уже имеется новая
версия спецификации, которая называется «USB on the go», поддерживающая
непосредственный обмен данными между узлами, что позволит, к примеру, пере-
писывать снимки с цифрового фотоаппарата сразу на USB флэш-драйв без учас-
тия ПК или какого-либо другого контроллера шины.
146
Полноскоростной интерфейс USB 2.0
Рис. 4.62. Логическая топология шины USB
Скорость передачи данных
Поскольку при разработке шины USB основной упор был сделан на под-
держку принципа «plug and play», ПК ничего не будет знать о новом устройстве
при его первом подключении к шине. Первое, что необходимо сделать компьюте-
ру, это узнать скорость обмена, поддерживаемую новым устройством. Для этого в
устройстве к линии D+ или D— подключается подтягивающий резистор. Если к
питанию подтянута линия D—, устройство является низкоскоростным, если же
D+ — полноскоростным. Высокоскоростные устройства при подключении опре-
деляются как полноскоростные, а после установления соединения переключают-
ся в высокоскоростной режим.
Каналы шины USB
После обнаружения компьютером нового устройства и определения под-
держиваемой им скорости обмена, ПК может приступать к обмену данными с
этим устройством. Пересылка пакетов данных осуществляется при помощи ло-
гических соединений, называемых каналами (pipe). Каналы образуются между
буфером в ПК и удаленным устройством с конкретным адресом (Рис. 4.63).
Каждый канал оканчивается в определенной конечной точке (endpoint), являю-
щейся частью USB-устройства. С точки зрения микроконтроллера, конечную
точку можно считать буфером, в котором сохраняются данные, и одновремен-
но прерыванием, которое указывает процессору на поступление нового пакета
данных.
Логические каналы формируются на последовательной шине методом вре-
менного уплотнения (то есть путем разделения каналов по времени). Каждую
миллисекунду ПК выдает на шину маркеры начала кадра (Start Of Frame — SOF),
разбивающие всю полосу пропускания 12 Мбит/с на последовательность кадров
(Рис. 4.64). Для каждого канала во всех кадрах выделяется определенный
временной интервал, в течение которого передаются требуемые данные.
147
Глава 4. Периферийные устройства общего назначения
хост
УСТРОЙСТВО
Рис. 4.63. Модель взаимодействия хоста с USB-устройством
SOF
1 мс
Логические каналы
формируются на шине USB
посредством временного уплотнения.
Шина разбивается на кадры
длительностью 1 мс.
В течение кадра может выполняться
транзакция по каждому из каналов
Рис. 4.64. Формирование каналов на шине USB
В спецификации USB определено несколько типов каналов с различными ха-
рактеристиками для поддержки самых разнообразных приложений. Можно даже
разработать USB-устройство, поддерживающее несколько различных конфигура-
ций, которые можно будет менять в процессе работы, с тем чтобы они соответ-
ствовали выполняющейся на ПК программе. Различают следующие типы кана-
лов: управляющие каналы (control), каналы передачи по прерываниям (interrupt),
каналы передачи массивов данных (bulk) и каналы изохронной передачи
(isochronous). Все эти каналы, за исключением управляющего, являются однона-
правленными. Управляющий канал зарезервирован для запрашивания и переда-
чи компьютером конфигурационных параметров устройства и обычно не исполь-
зуется прикладным ПО. Управляющий канал есть в любом устройстве, и он всегда
подключается к нулевой конечной точке (Endpoint Zero). Соответственно, при
подключении к шине нового устройства оно всегда распознается как устройство с
нулевым адресом, и ПК может осуществлять с ним обмен, посылая управляющую
148
Полноскоростной интерфейс USB 2.0
информацию нулевой конечной точке. Остальные типы каналов используются
только прикладным ПО. В частности, микроконтроллеры моделей LPC214x под-
держивают до 15 пользовательских конечных точек, которые подключаются к ка-
налам остальных трех типов.
Канал передачи по прерыванию
Сначала рассмотрим канал передачи данных по прерыванию. Основная осо-
бенность канала прерывания состоит в том, что его как бы не существует. Пос-
кольку инициировать передачу данных может только ПК, то ни одно из устройств
на шине не может обмениваться данными с ПК в асинхронном режиме. Исполь-
зуя канал передачи по прерыванию, разработчик устройства может определить,
как часто будет требоваться передача данных между ПК и удаленным устрой-
ством. Значение этого интервала может лежать в пределах 1...255 мс. Таким обра-
зом, канал передачи по прерыванию имеет определенную частоту опроса. Для
USB-мыши, к примеру, мы можем задать передачу данных каждые 10 мс. На са-
мом деле, задание частоты опроса гарантирует не то, что пакет данных будет пере-
даваться каждые 10 мс, а то, что транзакции будут осуществляться в течение каж-
дого десятого фрейма. Таким образом, все транзакции по шине USB подвержены
определенному временному дрожанию (джиттеру).
Канал изохронной передачи
Вторым типом пользовательских каналов является канал изохронной переда-
чи данных. Каналы этого типа используются для передачи данных в реальном
времени, таких как аудио и видео. Контроль ошибок в каналах изохронной пере-
дачи отсутствует, а новые пакеты данных передаются в каждом кадре, независимо
от того, успешно ли был принят предыдущий пакет. Таким образом, в аудиопри-
ложениях пропущенный или поврежденный пакет с аудиоданными звучит как
шум на линии, который будет продолжаться вплоть до успешного приема следую-
щего пакета. Важным свойством изохронной передачи данных является то, что
они должны передаваться с постоянной скоростью. Как и каналы передачи по
прерыванию, каналы изохронной передачи подвержены определенному джитте-
ру, описанному выше, поэтому прерывания при изохронной передаче генериру-
ются не при поступлении данных в буфер конечной точки, а при появлении мар-
кера начала кадра. В результате прерывания генерируются с постоянным перио-
дом, равным 1 мс, что позволяет считывать данные с постоянной скоростью.
Канал передачи массивов данных
Канал передачи массивов данных используется для передачи данных всех ос-
тальных типов (не управляющих, не по прерыванию, не изохронных). Данные пе-
редаются таким же образом и с такими же размерами пакетов, как по каналу пере-
дачи по прерыванию, за исключением того, что каналы передачи массивов данных
не имеют определенного периода опроса. Канал передачи массивов данных зани-
мает всю полосу пропускания шины, оставшуюся после завершения передач по
другим каналам, поэтому при большой загруженности шины пересылка массива
данных может быть отложена. И наоборот, если шина свободна, в каждом кадре
может осуществляться несколько таких передач, в отличие от остальных каналов,
149
Глава 4. Периферийные устройства общего назначения
ограниченных максимум одним пакетом на кадр. Примером передачи массивов
данных может служить передача данных в принтер. Пока печать осуществляется за
разумное время, точная скорость передачи данных не особо важна.
Распределение полосы пропускания шины
Таким образом, управляющие каналы занимают 10% полосы пропускания,
каналы изохронной передачи и передачи по прерываниям — 90%, а передача мас-
сивов данных осуществляется в моменты освобождения шины (Табл. 4.8). Эти
цифры соответствуют максимальной загруженности шины, однако очевидно, что
в большинстве реальных случаев часть полосы пропускания останется незадейс-
твованной. Распределением полосы пропускания занимается операционная сис-
тема ПК, которая не должна допускать подключения нового устройства к шине
при отсутствии ресурсов для его обслуживания.
Таблица 4,8, Характеристики каналов передачи
Ъшы каналов Управляющие Изохронные (FS и HS) По прерыванию Передачи массивов данных (FS и HS)
Формат данных Предопределенный спецификацией или производителем Поток Не структурированы Поток
Направление передачи Двунаправленная Однонаправленная Вход или выход Вход или выход
Размер пакета [байт] 8, 16, 32 или 64 1...1023 LS: < 8 FS: < 64 8, 16, 32 или 64
Предоставле- ние доступа к шине Первоочередной <90% периодический <90% 1...255 мс Низший приоритет
Последова- тельность данных Setup, данные и статус Без подтверждения, признак данных инвертируется С подтверждением, признак данных инвертируется С подтверждением, признак данных инвертируется
Транзакции на шине USB
Как мы с вами видели, для передачи данных по шине USB используется муль-
типлексирование с разделением по времени. Шина разбивается на отдельные
кадры путем посылки каждые 1 мс маркера начала кадра, а передача данных по
каналам производится пакетами данных в течение этих кадров. Каждая транзак-
ция на шине состоит из трех пакетов, как показано на Рис. 4.65.
Все транзакции на шине USB делятся на три фазы — фазу маркера,
во время которой указывается тип посылки, фазу данных и фазу квитирования
Фаза маркера Фаза данных Фаза квитирования
Одна транзакция
Рис. 4,65. Транзакция на шине USB
150
Полноскоростной интерфейс USB 2.0
Подавляющее большинство транзакций состоит из трех фаз. Сначала переда-
ется маркер, указывающий тип данной транзакции. После маркера осуществля-
ется передача требуемых данных. Завершается транзакция пакетом квитирова-
ния, указывающим на ее успешное завершение. Все эти пакеты имеют одинако-
вую структуру и содержат поле типа пакета, поле адреса приемника и конечной
точки, поле данных (если требуется), а также поле контроля ошибок ( Рис. 4.66).
Пакеты, передаваемые на каждом из этапов, имеют одинаковую структуру
Поле синхронизации Идентификатор пакета Данные пакета CRC ЕОР
Пакет
Рис. 4.66. Структура пакетов, передаваемых по шине USB
Фаза маркера
В спецификации USB 2.0 определено пять различных маркеров. Мы уже
познакомились с маркером начала кадра (SOF — Start Of Frame), который ис-
пользуется для отметки начала 1-мс кадра. У этого маркера отсутствуют связан-
ные с ним пакеты данных и подтверждения. Маркер IN предваряет передачу дан-
ных в ПК (входящая транзакция), а маркер OUT предваряет передачу данных из
ПК в устройство (исходящая транзакция). Направление передачи данных всегда
указывается относительно ПК, т.е. в ПК (IN) или из ПК (OUT). Маркер Setup пе-
редается только по управляющему каналу и используется для передачи команд в
USB-устройство. В частности, этими командами может быть команда запроса
конфигурации или команда на установку определенной конфигурации. И, нако-
нец, маркер PREAMBLE используется для указания начала низкоскоростной
транзакции. Обнаружение этого пакета приводит к отключению HS- и FS-портов
хабов и включению LS-портов. После завершения низкоскоростной транзакции
порты переключаются в исходное состояние.
Фаза данных
После посылки персональным компьютером маркера осуществляется переда-
ча пакета данных. Различают два типа пакета данных, называемых DATA0 и
DATA1. Эти пакеты выполняют одну и ту же функцию и отличаются только зна-
чением бита синхронизации (data toggle bit), используемого для обнаружения
ошибок. Назначение этого бита я объясню позже, когда мы приступим к рассмот-
рению методов контроля ошибок, применяющихся в протоколе USB.
Фаза квитирования
Последней фазой транзакции является передача пакета квитирования. На
этом этапе используются три различных пакета, сигнализирующих об успешном
или неуспешном прохождении транзакции. 151
Глава 4. Периферийные устройства общего назначения
Пакет АСК используется для подтверждения успешной передачи данных. Он
завершает транзакцию на шине и после его получения ПК начнет новую транзак-
цию посылкой нового пакета маркера. Пакет NAK, наоборот, сигнализирует о
том, что при передаче произошел сбой, обнаруженный схемой контроля ошибок.
Пакет NAK может генерироваться также в том случае, если буфер конечной точки
не готов к приему транзакции. Таким образом, при нахождении в буфере данных
от предыдущей исходящей транзакции USB-устройство будет генерировать пакет
квитирования NAK до тех пор, пока ЦПУ не прочитает все данные из буфера.
При получении пакета NAK компьютер попытается выполнить эту же транзак-
цию в следующем кадре. Следует напомнить, что при изохронной передаче фаза
квитирования отсутствует. Если буфер конечной точки заполнен и ЦПУ не может
его очистить, то мы получим непрерывную (в каждом кадре) генерацию пакета
NAK в канале. Это приведет к непроизводительному расходу полосы пропуска-
ния шины. Поэтому был введен третий пакет квитирования, называемый STALL.
Пакет STALL используется для того, чтобы сообщить ПК о невозможности обме-
на данными с устройством по этому каналу. Например, если в принтере закончи-
лась бумага, а буфер полон, дальнейшая передача данных документа приведет к
постоянной генерации пакета NAK. В этом случае принтер посредством пакета
STALL может сообщить ПК о невозможности приема новых данных, и процесс
обмена по этому каналу будет приостановлен. Затем ПК может попытаться опре-
делить причину останова, запрашивая пакеты данных по входящему каналу,
предназначенному для передачи диагностической информации.
Ограничение распространения ошибок
В протоколе USB используется шесть различных механизмов контроля оши-
бок. Для контроля ошибок на уровне пакетов используется контрольная сумма
(CRC), контроль идентификатора пакета и перестановка битов. Во время переда-
чи пакета имеется возможность обнаружения ложного конца пакета, тайм-аута
шины, потери активности на шине и «забивания» канала, при котором узел про-
должает передачу после завершения пакета. А при передаче пакетов данных конт-
ролируется их перемежение, поскольку вслед за пакетом DATA1 должен следо-
вать пакет DATA0, и наоборот. Таким образом, если, к примеру, будет потерян па-
кет данных DATA1, принимающий данные узел примет подряд два пакета DATA0
и ошибка будет обнаружена. Все эти методы контроля и обнаружения ошибок ре-
ализуются аппаратурой USB и практически прозрачны для программиста.
Конфигурация устройства
При первом подключении устройства к компьютеру определяется поддержи-
ваемая устройством скорость обмена, а в самом устройстве будет присутствовать
нулевая конечная точка, сконфигурированная для подключения к управляющему
каналу. Кроме того, каждому новому устройству, подключаемому к шине, присва-
ивается нулевой адрес. Таким образом, ПК «знает», с какой скоростью можно пе-
редавать данные по управляющему каналу, связанному с нулевой конечной точ-
152 кой по нулевому адресу. Этот управляющий канал впоследствии будет использо-
Полноскоростной интерфейс USB 2.0
ваться компьютером для определения возможностей нового устройства и
добавления его в сеть. Процесс, используемый ПК для сбора этой информации,
называется нумерацией (enumeration). Так что, помимо собственно конфигуриро-
вания периферийного модуля USB микроконтроллера LPC214x, вам потребуется
написать определенный код, который будет отвечать на запросы, посылаемые
компьютером во время процедуры нумерации. Все данные, запрашиваемые ПК,
описываются набором дескрипторов, имеющим иерархическую структуру, кото-
рая показана на Рис. 4.67.
Рис. 4.67. Стандартные дескрипторы USB-устройства
Дескрипторы представляют собой обычные массивы данных, которые долж-
ны передаваться ПК в ответ на запросы, посылаемые в процессе нумерации. Как
видно из Рис. 4.67, устройство может иметь достаточно сложные конфигурации,
поскольку шина USB разрабатывалась с точки зрения максимальной гибкости и
расширяемости. Тем не менее, существует минимально необходимый набор де-
скрипторов, которые должны присутствовать в любом USB-устройстве: дескрип-
тор устройства, дескриптор конфигурации, дескриптор интерфейса и три де-
скриптора конечных точек (один управляющий канал, один входящий и один ис-
ходящий).
Дескриптор устройства
На вершине иерархии находится дескриптор устройства (Device Descriptor),
содержащий основную информацию о USB-устройстве. Структура этого де-
скриптора приведена в Табл. 4.9. В частности, именно в этом дескрипторе хра- 153
Глава 4. Периферийные устройства общего назначения
нится идентификатор изготовителя (vendor ID) и идентификатор изделия
(product ID). Они представляют собой два уникальных числа, используемых для
идентификации данного конкретного устройства. Операционная система ис-
пользует эти значения для определения, какой именно драйвер устройства следу-
ет загрузить. Значение идентификатора изготовителя присваивается любой ком-
пании, изготавливающей USB-устройства. Назначением этих идентификаторов
занимается форум разработчиков USB. Минимальная плата за получение этого
идентификатора через сайт форума (www.usb.org) составляет $1500. Если же вы
хотите использовать в своей продукции логотип USB, вам придется выложить
уже $2500. Так или иначе, если хотите продавать свое USB-устройство на откры-
том рынке, вы должны получить идентификатор изготовителя. Идентификатор
изделия представляет собой 16-битное число, присваиваемое данному продукту
изготовителем (с целью его идентификации). Кроме того, в дескрипторе устрой-
ства содержится информация о максимальном размере пакета для управляющего
канала.
Таблица 4.9. Структура стандартного дескриптора устройства
Смещение (десятичное) Мнемоника Размер [байт] Описание
0 bLength 1 Размер дескриптора в байтах
1 bDescriptorType 1 Тип дескриптора (DEVICE = 01h)
2 bcdUSB 2 Номер версии спецификации USB в формате BCD
4 bDeviceClass 1 Код класса устройства
5 bDeviceSubCIass 1 Код подкласса устройства
6 bDevice Protocol 1 Код протокола
7 bMaxPacketSize 1 Максимальный размер пакета для нулевой конечной точки
8 idVendor 2 Идентификатор производителя
10 idProduct 2 Идентификатор изделия
12 bcdDevice 2 Номер версии устройства в формате BCD
14 iManufacturer 1 Индекс дескриптора строки, описывающей изгото- вителя
15 iProduct 1 Индекс дескриптора строки, описывающей продукт
16 iSerialNumber 1 Индекс дескриптора строки, содержащей серийный номер устройства
17 bNumConfigurations 1 Количество возможных конфигураций
Дескриптор конфигурации
В дескрипторе конфигурации содержится информация о потребляемой мощ-
ности устройства и количестве поддерживаемых интерфейсов (Табл. 4.10). Любое
устройство может иметь несколько конфигураций, и ПК может выбирать ту, ко-
торая наиболее соответствует требованиям используемого в данный момент про-
154 граммного обеспечения.
Полноскоростной интерфейс USB 2.0
Таблица 4.10. Структура стандартного дескриптора конфигурации
Смещение (десятичное) Мнемоника Размер [байт] Описание
0 bLength 1 Размер дескриптора в байтах
1 bDescriptorType 1 Тип дескриптора (CONFIGURATION = 02h)
2 wTotalLength 2 Общий объем данных в байтах, возвращаемый для этой конфигурации
4 bNumlnterfaces 1 Количество интерфейсов, поддерживаемых конфи- гурацией
5 bConfigurationValue 1 Идентификатор для запросов SET CONFIGURATION и GETCONFIGURATION
6 iConfiguration 1 Индекс дескриптора строки, описывающей данную конфигурацию
7 bmAttributes 1 Собственный источник питания/питание от шины и возможность пробуждения по внешнему сигналу
8 MaxPower 1 Код мощности, равный значению максимального тока, потребляемого от шины, в мА, деленному на 2
Дескриптор интерфейса
Дескриптор интерфейса (Табл. 4.11) описывает совокупность конечных точек.
Каждому интерфейсу соответствует набор каналов, используемых для конкрет-
ной задачи. В каждой конфигурации может быть доступно несколько интерфей-
сов, и эти интерфейсы могут активироваться одновременно или могут динами-
чески выбираться компьютером.
Таблица 4.11. Структура стандартного дескриптора интерфейса
Смещение (десятичное) Мнемоника Размер [байт] Описание
0 bLength 1 Размер дескриптора в байтах
1 bDescriptorType 1 Тип дескриптора (INTERFACE = 04h)
2 blnterfaceNumber 1 Порядковый номер интерфейса
3 b Alternate Setting 1 Код варианта для данного интерфейса
4 bNumEndpoints 1 Количество поддерживаемых конечных точек, за вычетом нулевой конечной точки
5 blnterfaceClass 1 Код класса интерфейса
6 blnterfaceSubClass 1 Код подкласса интерфейса
7 BlnterfaceProtocol 1 Код протокола
8 ilnterface 1 Индекс дескриптора строки, описывающей интер- фейс
Дескриптор конечной точки
Дескриптор конечной точки (Табл. 4.12) содержит всю информацию об одной
из конечных точек, доступных при использовании данного интерфейса. В де-
скрипторе хранится тип передачи, поддерживаемый данной конечной точкой,
максимальный размер пакета, номер конечной точки и частота опроса (для кана-
ла прерывания). И 55
Глава 4. Периферийные устройства общего назначения
Таблица 4.12. Структура стандартного дескриптора конечной точки
Смещение (десятичное) Мнемоника Размер [байт] Описание
0 bLength 1 Размер дескриптора в байтах
1 bDescriptorType 1 Тип дескриптора (ENDPOINT = 05h)
2 bEndpointAddress 1 Номер конечной точки и направление передачи
3 bmAttributes 1 Поддерживаемый тип передачи
4 wMaxPacketSize 2 Максимальный размер пакета
6 blnterval 1 Макс, задержка/интервал опроса/частота NAK
Это далеко не полный перечень всех возможных дескрипторов, которые могут
быть запрошены компьютером, однако указанные дескрипторы должны предо-
ставляться хосту любым USB-устройством.
Нумерация
Процесс нумерации осуществляется по управляющему каналу, соединенному
с нулевой конечной точкой, при первом подключении устройства. При этом ПК
посылает устройству ряд управляющих посылок (запросов), в ответ на которые
USB-устройство должно будет передать содержимое своих дескрипторов.
A SET UP
Ц DAT АО
о ACK
ADDR/EP
DATA
0x00/0x00
(8) 80 06 00 01 00 0040 00
Смещение Значение Расшифровка
0 80 Стандартный запрос, передача от устройства хосту
1 • 06 Получить дескриптор
- 2 ' .. 00 Индекс дескриптора
3 01 Дескриптор устройства
4 0000 Индекс
6 0040 Размер дескриптора
Рис. 4.68. Стандартный запрос к устройству
Запросы передаются в так называемых Setup-пакетах, состоящих из маркера
Setup и пакета данных, содержимое которого определяет тип запроса и его пара-
метры (Рис. 4.68). После подтверждения запроса компьютер передает маркер IN,
в ответ на который USB-устройство возвращает пакет данных, содержащий за-
прошенную информацию (как правило, дескриптор). Как минимум, во время ну-
мерации выполняются следующие действия.
• Получение восьми первых байтов дескриптора устройства
При первом обнаружении устройства для обмена с нулевой конечной точкой ПК
Л 56 будет использовать пакеты наименьшего размера. В результате запроса компью-
Полноскоростной интерфейс USB 2.0
тер получает идентификатор изготовителя, идентификатор изделия, а также зна-
чение максимального размера пакета для нулевой конечной точки. При после-
дующих транзакциях ПК сможет передавать пакеты данных наибольшего
размера, поддерживаемого нулевой конечной точкой, уменьшая, таким обра-
зом, количество посылок, необходимых для завершения процесса нумерации.
• Сброс узла
После установления соединения с нулевой конечной точкой ПК посылает ус-
тройству команду сброса для перевода его в определенное состояние.
• Присвоение адреса
Поскольку устройствам при подключении всегда присваивается нулевой ад-
рес, его необходимо освободить. Поэтому после сброса ПК назначает уст-
ройству уникальный сетевой адрес, используемый в дальнейшем.
• Запрос дескриптора устройства
После присвоения устройству нового адреса ПК запрашивает полный де-
скриптор устройства, вместе с которым передаются остальные дескрипторы
(конфигурации, интерфейса и конечных точек).
После завершения процесса нумерации ПК выбирает подходящий драйвер
устройства на основании значений идентификаторов изготовителя и изделия.
При необходимости, используя дополнительные управляющие посылки, ком-
пьютер может задать желаемые конфигурацию и интерфейс для последующего
обмена с устройством. Теперь устройство полностью готово к работе.
В спецификации USB определены одиннадцать стандартных запросов, кото-
рые указаны в Табл. 4.13. Если устройство не поддерживает какую-либо команду,
оно должно возвратить пакет квитирования STALL для прекращения команды и
ПК начнет передачу следующей управляющей посылки.
Таблица 4.13. Стандартные запросы
Код запроса Обозначение Описание
0 GET STATUS Определить состояние устройства
1 CLEAR_FEATURE Сбросить свойство
3 SET_FEATURE Установить свойство
5 SET_ADDRESS Установить адрес
6 GET_DESCRIPTOR Получить дескриптор
7 SET-DESCRIPTOR Загрузить дескриптор
8 GET_CONFIGURATION Получить код текущей конфигурации
9 SET-CONFIGURATION Установить конфигурацию
10 GET_INTERFACE Получить код интерфейса
11 SET-INTERFACE Установить интерфейс
12 SYNC_FRAME Кадр синхронизации
Теперь, когда мы в общих чертах познакомились с шиной USB и ее протоко-
лами, можно перейти к изучению модуля USB, встроенного в микроконтроллеры
LPC214x. Упрощенная структурная схема этого модуля приведена на Рис. 4.69.
Как и во всех микроконтроллерах семейства LPC2000, регистры модуля USB рас-
полагаются в адресном пространстве шины VPB. Кроме того, в этих микроконт-
роллерах имеется блок дополнительного ОЗУ объемом 8 Кбайт, подключенного к И57
Глава 4. Периферийные устройства общего назначения
шине АНВ. Обмен между этим ОЗУ и модулем USB осуществляется посредством
прямого доступа к памяти (DMA). Если режим DMA не задействован, это ОЗУ
можно использовать для хранения данных. Внутри модуля USB имеется блок па-
мяти типа FIFO объемом 2 Кбайта, в котором формируются буферы для всех ко-
нечных точек. В состав модуля также входят драйверы шины физического уров-
ня, так что микроконтроллер можно напрямую подключать к шине USB, добавив
только один подтягивающий регистр на линию D+.
Рис. 4.69. Структурная схема модуля USB
Все периферийные устройства в микроконтроллерах семейства LPC2000 син-
хронизируются сигналом PCLK, формируемым из тактового сигнала ЦПУ. Для ра-
боты модуля USB требуется тактовый сигнал частотой 48 МГц. Очевидно, что ис-
пользование сигнала Pclk в качестве тактового сигнала модуля USB приведет к
ограничению быстродействия всего кристалла. Поэтому в микроконтроллеры
был добавлен второй блок ФАПЧ, предназначенный для генерации тактового
сигнала модуля USB (Рис. 4.70). Этот блок работает от того же кварцевого резона-
тора, что и основная схема ФАПЧ, уменьшая, таким образом, конечную стои-
мость аппаратуры. Благодаря такому решению мы можем использовать для рабо-
ты с микроконтроллерами внешний генератор, имеющий частоту от 10 до 60 МГц.
158
Рис. 4.70. Формирование тактовой частоты модуля USB
Полноскоростной интерфейс USB 2.0
Как и следовало ожидать, такое сложное периферийное устройство, как мо-
дуль USB, имеет большое количество РСФ, используемых для управления моду-
лем. Все эти регистры делятся на 7 групп (Рис. 4.71).
Регистры прерываний устройства
Регистры прерываний конечных точек
гМодуль USB имеет огромное количество Л
регистров, которые можно разделить
на семь основных групп
Регистры управления конечными точками
Регистры передачи данных
Командные регистры
Системные регистры
Регистры DMA
Рис. 4.71. Группы регистров модуля USB
Модуль USB может работать в двух режимах — ведомого (Slave mode) и DMA
(DMA mode). В режиме ведомого ЦПУ должен отвечать на все транзакции USB.
Так как в модуле имеется 15 конечных точек, то при использовании этого режима
каждую миллисекунду может генерироваться до 15 прерываний, что при невоз-
можности своевременной обработки всех конечных точек приведет к формирова-
нию огромного числа пакетов квитирования NAK. Очевидно, что такой режим
работы очень сильно загружает ЦПУ. В режиме же DMA можно для каждой ко-
нечной точки определить в выделенном блоке ОЗУ буфер достаточно большого
размера, а выполнением последовательных операций обмена будет заниматься
контроллер прямого доступа к памяти (Рис. 4.72). В этом случае от ЦПУ потребу-
ется только управлять содержимым буферов в соответствии с запросами USB. Та-
ким образом, для создания простых устройств можно использовать режим ведо-
мого, а для высокопроизводительных устройств — режим DMA. В настоящее
время режим DMA поддерживается только микроконтроллером LPC2148, а в мо-
делях LPC2146 и LPC2144 реализован только режим ведомого.
Модуль USB имеет
два режима работы —
режим ведомого
и режим DMA
Рис. 4.72. Потоки данных в модуле USB
159
Глава 4. Периферийные устройства общего назначения
При инициализации модуля USB для работы в любом из режимов ЦПУ дол-
жен сконфигурировать конечные точки и их FIFO-буферы. Модуль USB может
поддерживать до 15 пользовательских конечных точек плюс обязательную нуле-
вую конечную точку для управления устройством. Типы пользовательских конеч-
ных точек жестко заданы (Табл. 4.14). Каждая конечная точка может использо-
ваться для входящей или исходящей передачи данных, но не для обоих направле-
ний одновременно. Таким образом, каждая логическая конечная точка соответс-
твует паре физических конечных точек, работа одной из которых должна быть
разрешена для поддержки требуемой логической конечной точки.
Таблица 4.14. Конечные точки модуля USB
Логическая конечная точка Физическая конечная точка Тйп конечной точки Направ- ление Размер пакета [байт} Двойная буферизация
0 0 Управляющая Out 8, 16, 32, 64 Нет
0 1 Управляющая In 8, 16, 32,64 Нет
1 2 По прерыванию Out 1...64 Нет
1 3 По прерыванию In 1...64 Нет
2 4 Передача массивов Out 8, 16, 32,64 Есть
2 5 Передача массивов In 8, 16, 32,64 Есть
3 6 Изохронная Out 1...1023 Есть
3 7 Изохронная In 1...1023 Есть
4 8 По прерыванию Out 1...64 Нет
4 9 По прерыванию In 1...64 Нет
5 10 Передача массивов Out 8, 16, 32,64 Есть
5 11 Передача массивов In 8, 16, 32, 64 Есть
6 12 Изохронная Out 1...1023 Есть
6 13 Изохронная In 1...1023 Есть
7 14 По прерыванию Out 1...64 Нет
7 15 По прерыванию In 1...64 Нет
8 16 Передача массивов Out 8, 16, 32,64 Есть
8 17 Передача массивов In 8, 16, 32,64 Есть
9 18 Изохронная Out 1...1023 Есть
9 19 Изохронная In 1...1023 Есть
10 20 По прерыванию Out 1...64 Нет
10 21 По прерыванию In 1...64 Нет
11 22 Передача массивов Out 8, 16, 32,64 Есть
11 23 Передача массивов In 8, 16, 32,64 Есть
12 24 Изохронная Out 1...1023 Есть
12 25 Изохронная In 1...1023 Есть
13 26 По прерыванию Out 1...64 Нет
13 27 По прерыванию In 1...64 Нет
14 28 Передача массивов Out 8, 16, 32, 64 Есть
14 29 Передача массивов In 8, 16, 32, 64 Есть
15 30 Передача массивов Out 8, 16, 32, 64 Есть
15 31 Передача массивов In 8, 16, 32, 64 Есть
160
Полноскоростной интерфейс USB 2.0
Кроме того, для каждой задействованной конечной точки необходимо выде-
лить буфер в FIFO-памяти. Разрешение конечных точек осуществляется установ-
кой соответствующих битов в регистре разрешения конечных точек USBReEp.
Для выделения буфера нужно записать в регистр индекса конечной точки
USBEpIn номер разрешенной конечной точки, после чего записать в регистр
максимального размера пакета конечной точки USBMaxPSize требуемый размер
буфера (Рис. 4.73).
Регистр разрешения
конечных точек USBReEp
Регистр индекса
конечной точки USBEpIn
Регистр макс, размера пакета
конечной точки USBMaxPSize
ЕРО Rx
ЕРОТх
Модуль USB имеет блок ОЗУ
размером 2 Кбайта, в котором
формируются буферы
для каждой конечной точких
Рис. 4.73. Создание FIFO-буфера конечной точки
Поскольку объем блока памяти FIFO ограничен (2 Кбайта), вам необходимо
заранее вычислить суммарный объем требуемой памяти, используя следующую
формулу:
N
RAMtotal= 32+ ERramsizeW ,
п = 0
где EPramsize = ((макс, размер пакета +3)/4) х db_status;
dbstatus = 1 для конечной точки с обычной буферизацией и 2 для конечной
точки с двойной буферизацией.
После инициализации модуля USB его можно использовать в режиме ведуще-
го или в режиме DMA. В режиме ведущего прерывание будет генерироваться по
каждой транзакции USB. В модуле VIC под прерывания модуля USB выделен
один канал, к которому подключены прерывания от всех конечных точек, а также
прерывания от блока DMA. В самом модуле USB можно для одной из конечных
точек задать более высокий приоритет, чем для остальных, так что прерывания от 461
Глава 4. Периферийные устройства общего назначения
нее будут обслуживаться быстрее, чем от других разрешенных конечных точек
(Рис. 4.74).
Рис. 4.74. Система прерываний модуля USB
Если устройство работает в режиме ведомого, то транзакция USB с разрешен-
ной конечной точкой вызовет генерацию прерывания. В случае исходящей по-
сылки (OUT) пакет данных будет передан в буфер указанной конечной точки, от-
куда ЦПУ сможет его прочитать (Рис. 4.75). Для выполнения этой операции сле-
дует установить бит разрешения чтения RD EN в регистре управления USB
USBCtrl и записать в этот же регистр номер конечной точки. Затем необходимо
считать из регистра размера принятого пакета USBRxPLen количество принятых
байтов. После этого можно приступать к считыванию данных из FIFO-буфера
посредством регистра приема данных USBRxData. Во время этой операции ко-
нечная точка будет заблокирована, поэтому при осуществлении новой исходящей
транзакции модуль USB отошлет пакет NAK, указывающий компьютеру повто-
рить транзакцию в следующем кадре. После того как ЦПУ прочитает данные из
FIFO-буфера, он может снова разрешить работу конечной точки, послав в ре-
гистр команд USB команду CLEAR BUFFER.
Исходящий пакет будет передан в буфер конечной точки.
Данные из буфера можно будет прочитать с помощью регистров
этой конечной точки
Буфер конечной
точки
Регистр размера
принятого пакета
Регистр приема
данных
Регистр управления
USB
Рис. 4.75. Получение пакета данных в режиме ведомого
Входящая транзакция в режиме ведущего выполняется в обратной последова-
тельности: ЦПУ заносит данные в буфер конечной точки, посылает в регистр ко-
манд USB команду VALIDATE BUFFER для разрешения конечной точки, после
162 чего ожидает появления на шине запроса данных.
Полноскоростной интерфейс USB 2.0
В каналах управления, передачи по прерыванию и передачи массивов данных
прерывание от конечной точки и в случае входящих, и в случае исходящих тран-
закций генерируется при готовности новых данных. Однако при изохронной пе-
редаче мы должны гарантировать регулярную генерацию прерываний, чтобы на-
ше приложение могло обрабатывать данные в реальном масштабе времени и, к
примеру, восстанавливать аудиоданные. Поскольку согласно спецификации USB
гарантируется только доставка изохронного пакета данных в течение 1-мс кадра,
то генерация прерывания по получению данных привела бы к возникновению
временного дрожания, как показано на Рис. 4.76. По этой причине для изохрон-
ных конечных точек прерывание генерируется при получении маркера начала
кадра, т.е. через точные промежутки времени. Это решение позволяет ЦПУ пере-
сылать в программу данные реального времени.
Маркер IN Маркер IN
Транзакция USB
Транзакции USB могут осуществляться
в каждом кадре. Однако их положение
в кадре может быть различным,
что приводит к временному дрожанию,
неприемлемому в случае изохронных
транзакций. Поэтому изохронные
конечные точки генерируют
прерывание в момент приема
маркера SOF
>
Время
Маркер IN Маркер IN
Рис. 4.76. Временное дрожание пакетов на шине USB
Для более требовательных приложений мы можем использовать модуль USB в
режиме DMA. Этот режим позволяет «сцепить» вместе несколько транзакций с
одной конечной точкой и осуществлять передачу в/из дополнительного ОЗУ мо-
дуля USB без участия ЦПУ. Как и FIFO-буферы конечных точек, дополнительное
ОЗУ модуля необходимо разбить на буферы для каждой используемой конечной
точки. Это осуществляется записью дескриптора DMA в ОЗУ модуля USB.
Структура такого дескриптора показана на Рис. 4.77.
Размер дескриптора для каналов по прерыванию и каналов передачи масси-
вов данных равен четырем словам, а для изохронных каналов — пяти. Управляю-
щий канал всегда используется в режиме ведомого, поскольку по нему, как прави-
ло, пересылается всего один или два пакета данных. Дескрипторы DMA могут
размещаться в любом месте ОЗУ модуля USB с выравниванием по границе слова.
В дескрипторах хранятся следующие параметры: начальный адрес DMA-буфера в
ОЗУ, размер буфера, начальный адрес следующего DMA-буфера, число передава-
емых байтов данных, статус процесса передачи и информация для управления
блоком DMA. Для изохронных конечных точек в дескрипторе также записывает-
ся указатель на текущий размер пакета и номер кадра, чтобы программа могла об-
Глава 4. Периферийные устройства общего назначения
Как и FIFO-память конечных точек,
дополнительное ОЗУ модуля USB разбивается на буферы,
каждый из которых описывается своим дескриптором
8 Кбайт
ОЗУ USB
Рис. 4.77. Дескриптор DMA
Режим АТЬЕ позволяет объединять
несколько массивов в непрерывный
поток данных, который затем
восстанавливается в ОЗУ USB
Данные,
посылаемые
драйвером хоста
Данные в пакетах,
передаваемых
по шине USB
Данные, сохраненные
в ОЗУ USB
контроллером DMA
Рис. 4.78. Использование режима ATLE
рабатывать данные реального времени. Блок DMA также поддерживает передачу
в режиме ATLE (с автоматическим определением длины посылки). В этом режи-
164 ме несколько отдельных буферов сцепляются вместе, передаются по USB и авто-
Полноскоростной интерфейс USB 2.0
матически восстанавливаются в ОЗУ USB, как показано на Рис. 4.78. За счет это-
го достигается максимальная пропускная способность шины USB при минималь-
ном вмешательстве ЦПУ.
Помимо изучения работы шины USB и модуля USB микроконтроллеров
LPC214x, нам придется разобраться, как можно обращаться к нашему USB-уст-
ройству из прикладной программы на ПК. Операционные системы семейства
Windows (98, 2000, Millenium и ХР) поддерживают USB с помощью встроенного
стека USB и дополнительных драйверов.
Модель драйвера Windows позволяет вам использовать
либо существующие драйверы, встроенные в ОС,
либо собственные драйверы
ПРИЛОЖЕНИЕ
Драйвер фильтра верхнего уровня (upper filter driver) обеспечивает поддержку возможностей, зависящих от конкретного устройства Драйвер пользовательской функции (custom function driver) определяет интерфейс пользователя для нестандартного аппаратного обеспечения
Драйвер класса функции (class function driver) определяет интерфейс пользователя для данного класса устройств
Драйвер фильтра нижнего уровня (lower filter driver) позволяет устройствам осуществлять обмен данными с драйверами USB операционной системы
Драйвер хаба USB (USBHUB.SYS): Инициализирует порты
Драйвер класса шины USB (USBD.SYS): Управляет транзакциями, питанием устройств, выполняет нумерацию устройств на шине
Драйвер контроллера USB (UHCI.SYS, OPENHCI.SYS EHCI.SYS): Обеспечивает обмен данными с устройством
Рис. 4.79. Модель драйвера Windows
Модель драйвера Windows, показанная на Рис. 4.79, позволяет вашей
программе использовать драйвер класса. Так называется драйвер USB-уст-
ройства, написанный для поддержки устройств конкретного класса, таких
как аудиоустройства, принтеры, устройства массовой памяти, или же вы мо-
жете предоставить собственный драйвер. Что касается собственного драйве-
ра, то он должен быть драйвером, работающим в режиме ядра системы 165
Глава 4. Периферийные устройства общего назначения
(kernel mode driver). Если вы знаете, как писать такие драйверы, это замеча-
тельно, в противном случае вам потребуется изучить огромное количество
информации об операционных системах семейства Windows. Замечу, что су-
ществуют уже написанные драйверы устройств общего назначения, для ис-
пользования которых требуется лишь задать идентификаторы изготовителя
и изделия. Оценочные версии таких драйверов можно найти на сайте
www.thesycon.com.
Если ваше USB-устройство может работать с одним из драйверов класса, вы
сможете сэкономить свои силы и средства на разработке собственного драйвера.
Наиболее интересными драйверами класса в Windows являются драйверы класса
HID-устройств (Human Interface Device) и класса устройств массовой памяти
(Mass Storage Device). Как следует из его названия, драйвер HID-устройств ис-
пользуется с клавиатурами, мышами, джойстиками и другими подобными уст-
ройствами. Однако вы также можете использовать драйвер HID для передачи и
приема любых данных, например, данных для лицевой панели (считывание со-
стояния кнопок, управление светодиодами) или обмена с удаленными датчика-
ми. Класс устройств массовой памяти позволяет USB-устройству выступать в ка-
честве сменного диска. Таким образом, драйвер HID-устройств обеспечивает
базовые средства двунаправленного обмена данными между ПК и USB-устройс-
твом, а драйвер устройств массовой памяти обеспечивает передачу больших объ-
емов данных. Так что возможностей этих драйверов будет более чем достаточно
для большинства приложений.
Вы можете указать принадлежность вашего устройства к классу HID-уст-
ройств, задав в дескрипторе интерфейса соответствующий код класса (Табл. 4.15).
Таблица 4,15. Дескриптор интерфейса HID-устройства
Смещение Значение Описание
0 09h Размер дескриптора
1 04h Тип дескриптора
2 00 Количество интерфейсов
3 00 Дополнительные установки
4 01 Количество конечных точек
5 03 Код класса
6 00 Код подкласса
7 00 Код протокола
8 00 Индекс строки
Когда компьютер обнаруживает HID-устройство, он начинает запрашивать
остальные дескрипторы, называемые дескрипторами сообщений (report
descriptor). Дескрипторы сообщений описывают структуру данных, передаваемых
этим HID-устройством. Форум разработчиков USB поддерживает таблицы ис-
пользуемых HID-устройств, в которых указываются структуры данных для боль-
шого числа устройств. Однако можно определить собственную структуру, соот-
166 ветствующую вашим требованиям.
Полноскоростной интерфейс USB 2.0
Структура сообщения, приведенная в Табл. 4.16, описывает задаваемый про-
изводителем дескриптор сообщения, который конфигурирует драйвер HID для
передачи двух 8-битных чисел со знаком в ПК и двух 8-битных чисел со знаком из
ПК. Входящая передача должна выполняться по каналу с прерыванием, а исходя-
щая — по управляющему каналу или, если доступен исходящий канал прерыва-
ния, то по нему. Максимальная скорость передачи для HID-устройства будет, та-
ким образом, равна максимальной скорости обмена по каналу с прерыванием
(64 байта каждый кадр), или 64 Кбайт/с, что почти в пять раз больше скорости
последовательного порта.
Таблица 4,16. Содержимое дескриптора сообщения HID-устройства
Значение поля Тйп поля Описание
06h AOh FFh Страница применения (Определяется изготовителем)
09hA5h Применение (Определяется изготовителем)
AlhOlh Коллекция Приложение
09h 06h Применение (Определяется изготовителем)
Входной отчет
09hA7h Применение (Определяется изготовителем)
15h 80h Логический минимум (-128)
25 7F Логический максимум (127)
75 08 Размер поля отчета (8 бит)
95 02 Количество полей (2 поля)
8102 Вход (Переменная, абс. значение)
Выходной отчет
09hA7h Применение (Определяется изготовителем)
15h 80h Логический минимум (-128)
25 7F Логический максимум (127)
75 08 Размер поля отчета (8 бит)
95 02 Количество полей (2 поля)
9102 Выход (Переменная, абс. значение)
COh Конец коллекции
После того как процесс нумерации будет завершен, а наше USB-устройство
будет распознано как HID-устройство, мы сможем обращаться к нему из при-
кладной программы. Эти обращения осуществляются путем вызовов функций
WIN32 API, обеспечивающих доступ ко многим функциям операционной систе-
мы Windows (Табл. 4.17). Соответственно, для создания программы можно ис-
пользовать любые средства разработки, позволяющие вызывать функции API, та-
кие как Visual C++ или Visual Basic. Если вы используете Visual C++, вам потре-
буется комплект разработки драйверов (DDK) фирмы Microsoft, который ^67
Глава 4. Периферийные устройства общего назначения
распространяется бесплатно ($25 за доставку). В состав DDK входят файлы .lib и
.h, которые необходимы для доступа к API-функциям, требуемым для работы с
HID-драйвером.
Таблица 4.17. Основные функции Windows API для работы с HID-устройствами
Функция API DLL Назначение
HidDGetHidGuid hid.dll Получает GUID для HID-класса
SetupDiGetClassDevs setupapi.dll Возвращает информацию обо всех устройствах заданного класса
SetupDiEnumDevicelnterfaces setupapi.dll Возвращает информацию о конкретном устройстве
SetupDiDestroyDeviceInfoList setupapi.dll Освобождает ресурсы, выделенные при вызове функции SetupDiGetClassDevs
CreateFile kemel32.dll Создает канал обмена с устройством
HidDGetAttributes hid.dll Возвращает идентификатор изготовителя, иденти- фикатор изделия и номер версии
HidDGetPreparsedData hid.dll Возвращает указатель на буфер, содержащий инфор- мацию о возможностях устройства
HidDGetCaps hid.dll Возвращает структуру, описывающую возможности устройства
HidD FreePreparseData hid.dll Высвобождает ресурсы, выделенные при вызове функции HidD GetPreparsedData
WriteFile kernel32.dll Посылает исходящее сообщение (Output Report) в устройство
ReadFile kemel32.dll Принимает входящее сообщение (Input Report) от устройства
HidDSetFeature hid.dll Посылает сообщение Feature Report устройству
HidDGetFeature hid.dll Считывает сообщение Feature Report из устройства
CloseHandle kemel32.dll Высвобождает ресурсы, выделенные при вызове функции CreateFile
Очень подробно работа с HID-устройствами рассмотрена в книге «USB
complete» Яна Аксельсона (Jan Axelson), поэтому, если вы только начинаете рабо-
тать с шиной USB, я настоятельно рекомендую вам прочитать эту книгу. Если ко-
ротко, то программа должна определить количество активных HID-драйверов в
ОС, а затем поочередно запросить у всех драйверов идентификаторы изготовите-
ля и поставщика обслуживаемого ими устройства, чтобы обнаружить драйвер,
связанный с вашим устройством. Как только драйвер будет найден, мы можем уз-
нать его возможности, считывая структуру сообщений (report structure). После
этого мы сможем использовать функции чтения и записи в файл для обмена дан-
ными. Законченный пример клиентской программы поставляется вместе с отла-
дочной платой МСВ21240. В этом примере вызовы всех необходимых функций
API инкапсулированы в шесть Си-функций, которые вы можете легко использо-
468 вать в вашей программе.
Полноскоростной интерфейс USB 2.0
Вторым интересующим нас драйвером является драйвер класса устройств
массовой памяти. Принадлежность к этому классу позволяет USB-устройству
представляться как внешний диск, так что мы легко можем загружать и вы-
гружать с него файлы. В составе МСВ2140 имеется пример работы с устройс-
твом этого класса, которое хранит файлы на RAM-диске с файловой системой
FAT16 внутри внутреннего ОЗУ микроконтроллера LPC214x. Вам не требует-
ся вносить изменения в программное обеспечение для класса, его можно счи-
тать просто черным ящиком, однако для практического использования этого
примера вам потребуется написать функции работы (чтения и записи) с
RAM-диском.
В операционную систему ARTX
компании Keil
встроена поддержка
стека USB и файловой системы
для FLASH-памяти,
что сокращает сроки разработки
сложных продуктов
Модуль USB
Рис. 4.80. Использование операционной системы
ARTX
В полной версии операционной системы ARTX поддерживается стек
USB и файловая система для FLASH-памяти (Рис. 4.80). Если вам требуется
большой объем памяти, вы можете подключить к порту SPI микроконтрол-
лера карточку FLASH-памяти, что даст вам мегабайты FLASH-памяти для
хранения данных.
Итак, как вы видели, в состав моделей LPC214x входит модуль USB и связан-
ный с ним блок DMA, что позволяет создавать на основе этих микроконтролле-
ров высокопроизводительные USB-устройства. После изучения небольшого объ-
ема дополнительной информации и воспользовавшись примерами из комплекта
поставки платы МСВ2140, вы сможете в кратчайшие сроки разработать свое
USB-устройство. Не может не радовать тот факт, что в ОС ARTX уже встроена
поддержка стека USB и файловой системы, которые позволят вам создавать
изощренные USB-устройства без большого объема низкоуровневого программи-
рования. 169
Глава 4. Периферийные устройства общего назначения
Резюме
Написание этой главы было похоже на стрельбу по движущейся цели! Се-
мейство LPC2000 развивается очень быстро, а новые модели микроконтроллеров
появляются регулярно. Поищите на компакт-диске, поставляемом с книгой, до-
полнения к данной главе в виде файлов формата PDF или загляните в Интернет
по адресу http://www.hitex.co.uk/arm/lpcbook.
Если вы как следует проработали эту и предыдущие главы, то должны пре-
красно разбираться в семействе микроконтроллеров LPC2000, процессорном яд-
ре ARM7 и соответствующих средствах разработки. В Приложении приведены
список литературы для дальнейшего изучения, а также ресурсы сети, посвящен-
ные процессору ARM7 и микроконтроллерам LPC2000, в частности.
УЧЕБНОЕ ПОСОБИЕ
ПО СРЕДСТВАМ РАЗРАБОТКИ
КОМПАНИИ KEIL
В этой главе приведены рабочие листы для выполнения практических упраж-
нений, представленных на прилагаемом компакт-диске. Вообще говоря, имеется
два набора упражнений: один для компилятора Keil, а другой для компилятора
GNU. Данная глава писалась в расчете на компилятор Keil. Если же вы хотите ис-
пользовать компилятор GNU, вам нужно сначала изучить главу 6, в которой под-
робно описываются расширения стандарта ANSI С, используемые в компиляторе
GNU. Кроме того, в главе 6 приводятся рабочие листы для первых шести упраж-
нений, относящихся непосредственно к пакету программ GNU. После шестого
упражнения вы можете вернуться к данной главе и далее уже использовать любой
из наборов упражнений (Keil или GNU).
Установка
Все программное обеспечение, необходимое для выполнения практических
упражнений, находится на компакт-диске, прилагающемся к книге. Если вы
вставите компакт-диск в привод вашего ПК, появится следующее окно (Рис. 5.1):
hitexHBMi
3
• Дополнительные
материалы к курсу
'Упражнения
hitftx.C6.Bk phi!ipi.tu dodeca.in Контакты
PHILIPS
Инструывнтальны» средства
Операционная система СИХ
Добро пожаловать в мир встроенных решений Hitox
• Внутрисхемное
программирование (ISP)
• Рукояодстая и спраяониые
материалы
* Информация по плате
М СВ 2100
рКА
Устаноаить виизгомпилятор компании К«П
Установить среду разработки рУййон для ARM компании Keil
Рис. 5.1. Меню компакт-диска
171
Глава 5. Учебное пособие по средствам разработки компании Keil
Прежде всего, необходимо установить пакет программ Keil pVISION, при
этом также будет установлен компилятор Keil.
Если вы собираетесь использовать компилятор GNU, то его нужно будет уста-
новить отдельно, после установки пакета ^VISION.
Затем установите набор упражнений для того компилятора, который плани-
руете использовать.
И, наконец, установите утилиту для внутрисхемного программирования мик-
роконтроллеров.
После того как программное обеспечение будет установлено, вы можете при-
ступать к выполнению упражнений.
Использование ИСР pVISION
компании Keil
В данном разделе мы рассмотрим инструментальные средства разработки, ис-
пользуемые при разработке программ для микроконтроллеров семейства
LPC2000. Все примеры в книге написаны в расчете на набор инструментальных
средств Keil ARM. Этот набор включает в себя интегрированную среду разработ-
ки pVISION, содержащую редактор и менеджер проектов, компилятор и компо-
новщик для процессора ARM7, а также программный симулятор микроконтрол-
лера. Симулятор полностью моделирует работу ядра ARM7 и периферийных мо-
дулей микроконтроллеров LPC2000. То есть, используя один только симулятор,
можно наблюдать за работой всего микроконтроллера. Демонстрационную вер-
сию этого пакета программ можно скачать с сайта компании Keil (www.keil.com),
она также имеется на компакт-диске, прилагающемся к книге. Кроме того, мож-
но приобрести стартовый набор разработчика, в который входит оценочная плата
с микроконтроллером и JTAG-отладчик. Этот набор позволит вам отлаживать
свои программы на реальном устройстве.
Компилятор ARM компании Keil позволяет писать программы на языке Си и
компилировать код, выполняющийся на микроконтроллерах семейства LPC2000.
Для соответствия архитектуре микроконтроллеров в компиляторе используется ряд
нестандартных расширений (не соответствующих стандарту ANSI С), с помощью
которых обеспечивается поддержка различных функций микроконтроллера, таких
как прерывания, взаимодействие наборов команд ARM/THUMB и доступ к встро-
енным периферийным устройствам. Прежде чем приступить к выполнению упраж-
нений, не помешает еще раз взглянуть на упрощенную карту памяти микроконтрол-
леров LPC2000 (Рис. 5.2), чтобы иметь представление о компоновке проекта.
Поскольку вектор сброса и таблица векторов исключительных ситуаций раз-
мещаются начиная с нулевого адреса, встроенная FLASH-память занимает
адреса от 0 до 256 Кбайт. Встроенное ОЗУ занимает область адресов объемом до
64 Кбайт, начиная с адреса 0x40000000, а встроенные периферийные устройства
отображены на область с адреса ОхЕООООООО до верхней границы адресного про-
странства.
Прежде чем приступать к детальному изучению компилятора, давайте выпол-
ним упражнение, в котором поэтапно разберем, как в среде pVISION создать
172 проект, скомпилировать программу и запустить отладчик. Разумеется, мы не кос-
Использование ИСР yVISION компании Keil
Периферия
Статическое
ОЗУ
OxFFFF FFFF
ОхЕООО 0000
0x4000 FFFF
0x4000 0000
Память микроконтроллеров
семейства LPC2000
представляет собой
линейное адресное
пространство размером 4 Гбайт,
в котором выделены области
для внутренних FLASH-памяти,
статического ОЗУ
и периферийных устройств
FLASH-память
0x00001 FFFF
0
Рис. 5.2. Карта памяти микроконтроллеров LPC2000
немея всех возможностей ИСР ^VISION, но, по крайней мере, вы получите ос-
новные сведения по используемой среде разработки. Впоследствии вы сможете
исследовать ее самостоятельно. Если вы скопировали файлы упражнений с ком-
пакт-диска на жесткий диск компьютера, то файлы, необходимые для выполне-
ния следующего упражнения, находятся в папке «C:\work\EXl-First Program».
Итак, давайте приступим к созданию нашего первого проекта.
Упражнение 1. Использование пакета программ
компании Keil
В этом упражнении используются файлы с исходными текстами, располагаю-
щиеся в папке «C:\work\EXl-First Program».
При выполнении нашего первого упражнения мы создадим проект, скомпи-
лируем программу и загрузим ее в симулятор для отладки. После этого мы рас-
смотрим основные функции отладки, предоставляемые симулятором Keil.
Для запуска ИСР дважды щелкните на иконке программы ^VISION
У-
.По-
явится окно программы (Рис. 5.3).
ИСР pVISION компании Keil (далее будем просто писать pVISION) под-
держивает несколько различных компиляторов: компилятор GNU С, компиля-
тор из пакета разработки компании ARM и собственный компилятор Keil. Перед
компиляцией убедитесь, что выбран компилятор Keil. Для этого активируйте ок-
но рабочей области проекта Project Workspace (вкладка Files), щелкните в нем
правой кнопкой мыши и в появившемся контекстном меню выберите пункт
Manage Components. В появившемся окне диалога перейдите к вкладке
Folders/Extensions (Рис. 5.4) и убедитесь, что отмечен флажок Use Keil ARM Tools.
Затем перейдите к вкладке Books (Рис. 5.5).
Выделите в правом списке элемент User Manual и нажмите кнопку Change
Book. Появится окно Add/Change Book Item (Рис. 5.6).
173
Глава 5. Учебное пособие по средствам разработки компании Keil
174
t/ iap pVision3 [C:\WorkURM\Philipsexdniples\IAP\api.c]
edit View Project Debug Flgsh Peripherals look §VC5 'tfndow fctelp
Charnel j Source ' | Name | Type'Й'аёфа'Г"
0 Watchdog WDINT IRQ OOOOOOOOH 0 0
4 Timer 0 IRQ OOOOOOOOH 0 0 ®
5 Timer 1 IRQ OOOOOOOOH 0 0
6 UARTO IRQ OOOOOOOOH 0 0
7 UART1 IRQ OOOOOOOOH 0 0
8 PWM IRQ OOOOOOOOH 0 0
9 I2C IRQ OOOOOOOOH 0 0
10 SP10 IRQ OOOOOOOOH 0 0
11 SPI1 IRQ OOOOOOOOH 0 0
12 PLLLock PLOCK IRQ OOOOOOOOH 0 1
13 RTC IRQ OOOOOOOOH 0 0
14 External Interrupt 0 EINTO IRQ OOOOOOOOH О О Д:
Selected Interrupt Watchdog
Г IntEnatte Г IntSetect IRQ Slot. VICDefVectAddr |бх00б00000 :
Г Softlnt Г Rawlrt * !
L: VICVectAddr: juxOOOOOOOO VICIntSelect:{ОхОООООбоО VICRawIntt: §0x00001000
VICSofBnt:§(моо66обо~“ VICIntEnable.(бхббббббЙГ* VICIRQStatus-§МОЙЙЙГ“
i VlCSoftlntClear: jOxOOOOOOOO VIDnlEnClr: (бхбббоОООО VICFIQStatus: |’&Л000а300 '
iOxOOOOOOOO: 18 FO 9F
§0x00000003: E5 18 FO
§0x00000006: 9F E5 18
§0x00000009: FO 9F E5
§0x0000000C: 18 FO 9F
IOxOOOOOOOF: E5 18 FO
§0x00000012: 9F E5 00
§0x00000015: 00 AO El
0x00000018: FO FF IF
0x0000001В : E5 18 FO *1
A Memory #2 A »*
Mwf..Г
Рис. 5.3. Окно программы ц VI SION
Components, Environment and Books
Use Keil ARM Tools
Г
U e GNU Tools
Cygnus Folder: |777
Keil Root Folder:
ReafView Folder:
Keil Root Folder: '•7-
Use ARM Tools
| OK
эт Re-
Puc. 5.4. Вкладка Folders/Extensions
|x|
C Source:
C++ Source:
Asm Source:
Object:
Library:
Document:
Справка
Использование ИСР pVISION компании Keil
Рис, 5,5. Вкладка Books
Add ! Change Book Item [X~|
Book Title:
I User Manual
Book Path:
|C:\Work\ARM\Philips bourse lmage\UM_LPC21X><_LPC22
OK | Cancel
Puc, 5.6. Окно Add/Change Book Item
Измените путь к руководству пользователя по микроконтроллерам LPC2000,
которое находится на компакт-диске. С помощью этой вкладки вы можете добав-
лять любую другую необходимую вам документацию.
После того как проект будет полностью сконфигурирован, доступ ко всей
электронной документации можно будет получить через вкладку Book окна
Project Workspace (Рис. 5.7).
После добавления необходимой документации нажмите кнопку ОК, чтобы
вернуться к конфигурированию проекта.
Выберите в меню Project пункт New Project... (Рис. 5.8).
В окне диалога (Рис. 5.9) укажите папку, в которой будет сохранен новый про-
ект. В строке File name введите имя проекта «first.uv2» и нажмите кнопку Сохра-
нить.
175
Глава 5. Учебное пособие по средствам разработки компании Keil
£2 |jVision3
{ Project Workspace »• х |
Tools User's Guide i
Release Notes j
i * Complete User's Guide Selection i
GNU C Compiler i
GNU C Run-Time Libraries
GNU C Utilities t
j В tt Device Data Books
I User Manual
Puc. 5.7. Окно Project Workspace
. File Edit View [Project [Debug Flash Peripherals loots SVCS Window Help
-g у iJ " '-7Г\
Import pi Vis ion 1 Project...
4- >
> j Open Project
j Project Workspace
Puc, 5,8, Выбор New Project
Puc, 5,9. Ввод имени проекта
h . з йэ— Г*тт
После этого появится окно выбора нового устройства (Рис. 5.10). Просмотри-
те базу данных поддерживаемых устройств, выберите в папке «Philips» микрокон-
троллер LPC2129 и нажмите кнопку ОК.
В браузере проекта выделите корневой узел «Target 1» и вызовите контекстное
меню, нажав правую кнопку мыши (Рис. 5.11). В этом меню выберите пункт
Options for Target.
На вкладке Target (Рис. 5.12) задайте частоту симуляции, равную 12.000 МГц.
Л 76 Убедитесь, что отмечены флажки Use On-chip ROM и Use On-chip RAM.
Использование ИСР pVISION компании Keil
Select Device for Target 'Target T
[x|
CPU |
Vendor: Philips
Device: LPC2129
Toolset ARM
Data base
_____
□ LPC2114
□ LPC2119
> fl LPC2124
Description:
LPC2129
i fl LPC2131
; О LPC2132
□ LPC2138
-а LPC2194
i--fl LPC2210
□ LPC2212
□ LPC2214
= LPC2290
ARM7TDMI-S based high-performance 32-bit RISC Microcontroller with Tl
256KB on-chip Flash ROM with In-System Programming (ISP) and In-Applk
16KB RAM, Vectored Interrupt Controller,
Two UARTs, I2C serial interface, 2 SPI serial interfaces
T wo timers (7 capture/compare channels),
PWM unit with up to 6 PWM outputs,
4-channels 10bit ADC, 2 CAN channels.
Real Time Clock, Watchdog Timer, General purpose I/O pins.
CPU clock up to 60 MHz, On-chip crystal oscillator and On-chip PLL
OK I Отмена Справка
Рис. 5.10. Окно выбора устройства
Ю а; ы др «з
Рис. 5.11. Контекстное меню, вызванное в браузере проекта
177
Глава 5. Учебное пособие по средствам разработки компании Keil
Рис. 5.12. Вкладка Target
Убедитесь, что отмечен флажок Use Memory Layout from Target Dialog на вклад-
ке LA Locate (Рис. 5.13).
Puc. 5.13. Вкладка LA Locate
На вкладке Debug (Рис. 5.14) удостоверьтесь, что включен переключатель Use
178 Simulator, а также отмечены флажки Load Application at Startup и Go till mainQ.
Использование ИСР yVISION компании Keil
Options for Target ‘Target Г
Device | Target | Output | Listing I CC | Assembler | Linker Debug I Utilities |
Use Simulator Settings ||
P Load Application at Startup P Go till main()
Initialization File:
- Restore Debug Session Settings
P Breakpoints P Toolbox
P Watchpoints & PA
p Memory Display
CPU DLL: Parameter:
IsARhTDLL FcLPCZIOO
Use: |ULINK ARM Debugger 3
P Load Application at Startup Г* Go till main()
Initialization File:
। ।
Restore Debug Session Settings - ...........- -
P Breakpoints P Toolbox
! Г" Watchpoints
\ P Memory Display
Driver DLL: Parameter:
Didog DLL: Parameter:
|dARMPD’lL~” |:pLpc2“ix9
Dialog DLL: Parameter:
[tARMpTlL |-pLPC21x9
OK I Отмена I Defaults
Puc, 5.14, Вкладка Debug
Чтобы завершить установку параметров проекта, нажмите кнопку ОК.
В браузере проекта разверните узел «Target 1» (Рис. 5.15), появится папка
«Source Group 1».
Рис. 5,15, Папка «Source Group 1»
Выделите эту папку, нажатием правой кнопки мыши вызовите контекстное
меню и выберите пункт Add Files to Group ‘Source Group 1’ (Рис. 5.16). 179
Глава 5. Учебное пособие по средствам разработки компании Keil
В диалоговом окне (Рис. 5.17) добавьте файлы «blinky.c» и «seriate».
Рис. 5.17. Добавление файлов
Смените фильтр Files of type на «ASM Source file» и добавьте файл «startup.s».
Это все исходные файлы, необходимые для проекта, так что нажмите кнопку
Close.
Замечания:
1. Исходный код, содержащийся в файле, можно просмотреть, сделав двойной
щелчок на имени файла в браузере проекта.
2. На вкладке Project Components окна диалога, вызываемого при выборе пункта
Manage Components, можно добавить в проект дополнительные группы исход-
ных файлов, а также задать различные опции сборки проекта (создавать код
для отладки из ОЗУ или для размещения в FLASH-памяти, отлаживать про-
грамму в симуляторе или по интерфейсу JTAG).
Скомпилируйте программу, выбрав в меню Project пункт Build Target или на-
жав на клавиатуре клавишу F7. Соответствующая кнопка есть и на панели инс-
трументов (Рис. 5.18).
Запуск отладчика Сборка проекта
\ 0le ©ft W Project jjebug Flash Peripherals Tools gVC5 Window цЫр f f
........31^ [g® «r s wtr
?preset worksp». x s
Рис. 5.18. Панель инструментов
При выполнении остальных упражнений мы будем пользоваться уже соз-
данными проектами, в исходных файлах которых отсутствует некоторая часть ко-
да. Законченные версии упражнений можно найти в соответствующих
папках «Solution». Исполняемые файлы для всех упражнений находятся на ком-
пакт-диске.
180
Использование программы отладки
Использование
программы отладки
Запустите отладчик, выбрав в меню Debug пункт Start/Stop Debug Session или
нажав соответствующую кнопку на панели инструментов (Рис. 5.19).
Панель
Окно
Командная строка Регистры ЦПУ содержимого
Окно просмотра
памяти
переменных
Рис. 5.19. Окно ИСР цVISION
Код программы загрузится в симулятор и будет выполнена его часть от векто-
ра сброса до функции main().
В окне Project Window активной станет вкладка Regs, на которой можно про-
смотреть содержимое всех регистров ЦПУ. Здесь вы можете:
• Просмотреть регистры для любого из режимов работы ЦПУ
• Открыть регистры CPSR и SPSR, чтобы узнать значения флагов 184
Глава 5. Учебное пособие по средствам разработки компании Keil
• Увидеть внутренние параметры симулятора, такие как потраченное количество
тактов и текущее время выполнения
• Изменить содержимое регистра, сделав тройной щелчок на его значении и
введя новое
После входа в функцию main() для управления выполнением программы
можно использовать следующие клавиши:
Fl 1 — выполнение одной строки программы
F10 — выполнение блока или функции
F5 — запуск программы на полной скорости
Esc — останов программы
Замечание. Чтобы команды пошагового выполнения были доступны, окно ис-
ходного текста программы должно быть активным.
Задание точки останова
Поставьте курсор на строку программы, нажатием правой клавиши мыши вы-
зовите контекстное меню (Рис. 5.20) и выберите пункт Insert/Remove Breakpoint.
Теперь нажмите F5, чтобы выполнить программу до этой строки.
Undo
Сору
Paste
Select All
Show Disassembly at 0xl2C
Set Program Counter
Run to Cursor line
Go To Line
Insert/Remove Breakpoint
Enable/Disable Breakpoint
Clear complete Code Coverage Info
Execution Profiling
Outlining
Advanced
Puc. 5.20. Задание точки останова с помощью контекстного меню
Выполнение до определенного места программы
Это самый быстрый способ перехода к произвольному месту программы.
Поставьте курсор на строку программы, вызовите контекстное меню и выбе-
рите в нем пункт Run to Cursor line. После этого программа будет выполняться до
тех пор, пока не достигнет указанной строки. Также вы можете выбрать пункт Set
Program Counter. С его помощью можно установить счетчик команд в любое место
182 программы, не выполняя ее.
Использование программы отладки
Выберите в меню View пункт Disassembly Window (Рис. 5.21), чтобы увидеть ко-
нечный ассемблерный код.
Disassembly
Uln|[x|
46
47
48
49
50
51
52
‘0x00000174
int
main(void)
K0x00000176
K-0x00000178
Hl0x0000017A
54
L 55
»0х0000017С
F 56
K0x0000017E
0x00000180
K0x00000182
«0x00000184
0x00000186
«0x00000188
57
»0x0000018A
gOxOOOOOlSC
K0x0000018E
«0x00000190
L 58
0x00000192
«0x00000194
K0x00000196
for ( ,)
LB500 PUSH
counter = 0,
2100 MOV
480A LDR
6001 STR
for (i = 0, i
{
2400 MOV
{LR}
Rl,#0x00
R0,[PC,#0x0028]
RI,[R0,#0x00]
<= 20, i++)
R4,#0x00
1' I
counter++
4D0A LDR
1C28 ADD
3004 ADD
6801 LDR
3101 ADD
6001 STR
fiboCount
6868 LDR
F7FF BL
FFC8 BL
6028 STR
}
3401 ADD
2C14 CMP
DDF2 BLE
R5,[PC,#0x0028]
R0,R5,#0
R0,#0x04
RI,[R0,#0x00]
Rl,#0x01
RI,[R0,#0x00]
Fibonacci(counter)
R0,[R5,#0x04]
Fibonacci(0x00000120) - Part #1
Fibonacci(0x00000120) - Part #2
R0,[R5,#0x00]
R4,#0x01
R4,#0xl4
0x0000017E
Puc. 5.21. Окно дизассемблера
Просмотр значений переменных
В окне исходного текста установите курсор на переменную «counter». Вызови-
те контекстное меню и выберите в пункте Add “counter” to Watch Window... под-
пункт#! (Рис. 5.22).
Select All
Show Disassembly at 0xl7E
Set Program Counter
Run to Cursor line
Go To Line
Insert/Remove Breakpoint
Clear complete Code Coverage Info
.or (,,) Execution Profiling
counter :
for (i - Outlining
< Advanced
соип^егттг................—---------
fiboCount = Fibonacci(counter)
Puc. 5.22
183
Глава 5. Учебное пособие по средствам разработки компании Keil
Чтобы увидеть значение переменной, в окне просмотра Watches перейдите к
вкладке Watch #1 (Рис. 5.23).
4 I >1 » h Locals Awatch#! Д Watch #2 Д Call Stack /
mi №. ! i sn jui
Puc. 5.23. Вкладка Watch #1
Просмотр содержимого ячеек памяти
Выбрав в меню View пункт Memory Window, откройте окно просмотра памяти
(Рис. 5.24).
Задайте стартовый адрес, равный 0x40000060 (адрес переменной «counter»).
Ч Address: |3х40000060"
0x40000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 0 0 00 00
0x40000072: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x40000084: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x40000096: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x400000A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x400000BA: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x400000CC: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x400000DE: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x400000F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x40000102: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x40000114: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
К j 41 >| IHj\Memory #1 Д Memory #2 Д Memory #3 Д Memory #4 /
а
Рис. 5.24. Окно просмотра памяти
Просмотр встроенных периферийных устройств
Откройте несколько окон из меню Peripherals (Рис. 5.25).
Vectored Interrupt Controller (Ж| ; - X
tsh peripher | Tools SVCS Window Help
, Reset CPU
0 Watchdog WDINT IRQ
4 Timer 0 IRQ
5 Timer 1 IRQ
6 UARTO IRQ
7 UART1 IRQ
8 PWM IRQ
9 I2C IRQ
10 SPIO IRQ
11 SPI1 IRQ
12 PLLLock PLOCK IRQ
13 RTC IRQ
14 External Interrupt 0 EIN TO IRQ
~ Selected Interrupt: Watchdog -....-...
OOOOOOOOH
00000000H
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
j Г IntEnable Г IntSelect (RQ S|ot Г'“~] VICDefVectAddr: [Ьхоббоббоо
| Г Softlnt г Rawlnt ’ —J ’
VICVectAddr: [бхбббббббо” VICIntSelect: [бхбобббббб VICRawIntr: [OxOOOOIOOO
VlCSoftlnt: [б7ообббоОсГ“ VICIntEnable: [бхбобобобб“ VICIRQStatus: |бхбобббО(Ю
VlCSofUntClear: [смббббоббб VICIntEndr |0x00000000 VICFIQStatus: |0x00000000
184
Puc. 5.25. Меню Peripherals
Использование аппаратного JTAG-отладчика ULINK
В отладчике есть много других функций. Тем не менее, рассмотренных выше
функций будет достаточно для выполнения практических упражнений. Заменив
симулятор JTAG-отладчиком, можно будет использовать тот же самый интерфейс
для отладки реального устройства.
Использование аппаратного
JTAG-отладчика ULINK
Аппаратным JTAG-отладчиком, входящим в состав стартового набора разра-
ботчика, является отладчик ULINK производства компании Keil. Он подключа-
ется к разъему порта JTAG платы МСВ2100 (Р5) и, через порт USB, к персональ-
ному компьютеру. Для перехода от симулятора к отладчику ULINK следует вы-
полнить следующие действия.
Установка отладчика ULINK
Подключите отладчик к плате MVB2100, как показано на Рис. 5.26, и вставьте
кабель USB в соответствующий разъем ПК. Не забудьте подключить к плате пи-
тание (+6.5 В).
Рис. 5.26. Подключение отладчика к плате
Конфигурирование ^VISION для использования отладчика ULINK
Сначала откройте окно задания опций для конечного устройства (меню
Project, пункт Options for Target...) и перейдите к вкладке Utilities (Рис. 5.27).
Включите переключатель Use Target Driver for Flash Programming и выберите из
ниспадающего списка строку «ULINK ARM7 Debugger». Не забудьте также отме-
тить флажок Update Target before Debugging.
185
Глава 5. Учебное пособие по средствам разработки компании Keil
Options for Target "Target Г | X |
Device | Target | Output) Listing) C ) Asm ) LAMisc) LA Locate) Debug Utilities |
OK | Отмена I Defaufts I Справка
Puc. 5.27. Вкладка Utilities
Конфигурирование алгоритма записи в FLASH-память
Нажмите кнопку Settings. Задайте стартовый адрес ОЗУ (поле Start), равный
0x40000000, а размер (поле Size) — 0x400 (Рис. 5.28). Нажмите кнопку Add и выбе-
рите алгоритм, соответствующий используемому устройству. Для закрытия окна
диалога нажмите кнопку ОК.
186
Рис. 5.28. Задание стартового адреса и размера ОЗУ
Использование аппаратного JTAG-отладчика ULINK
Переключение с симулятора на JTAG-отладчик
Снова откройте окно задания опций для конечного устройства и перейдите к
вкладке Debug (Рис. 5.29). В правой части окна выберите из ниспадающего спис-
ка строку «ULINK ARM7 Debugger» и отметьте переключатель Use.
Options for Target 'Target Г
Device | Target | Output | Listing | C | Asm | LAMiscj LA Locate Debug I Utilities |
C Use Simulator Settings
P Load Application at Startup P Go tiBmainQ
Initialization File:
| ' " ... | Edit...
~ Restore Debug Session Settings------------------------------
p Breakpoints p Toolbox
P Watchpoints & PA
P Memory Display
Use: [uLINK ARMI Debugger j] Settings |
p Load Application at Startup P Go till mainO
Initialization File:
I । EdiL'.l
~ Restore Debug Session Settings--------------------------
P Breakpoints P Toolbox
Г Watchpoints
P Memory Display
CPU DLL Parameter:
|SARM DLL |
Dialog DLL: Parameter:
[DARiTPDLl pLp(:2292
Driver DLL: Parameter:
|SARM DLL |
Dialog DLL: Parameter:
pTARMRDLL ^£2292
OK | Отмена | Defaults [ Справка
Puc. 5.29. Вкладка Debug
Теперь pVISION готова для использования JTAG-отладчика ULINK вместо
симулятора.
Если в данный момент вы работаете с JTAG-отладчиком или симулятором, то
прежде чем перекомпилировать или закрыть проект, остановите выполнение лю-
бых отлаживаемых программ и выйдите из отладчика.
Важное замечание, касающееся следующих упражнений. Проекты для всех пос-
ледующих упражнений могут быть собраны либо для отладки в симуляторе
pVISION, либо для загрузки на плату МСВ2100и отладки через JTAG-отладчик
ULINK. При работе с версией для симулятора корневая папка в браузере проек-
та будет называться «Simulator», а при работе с версией для отладчика —
«Ulink». Единственное, чем отличаются обе версии проекта, — параметрами
опции Debug. Для переключения между этими вариантами перейдите к вкладке
Files окна Project Workspace и в контекстном меню выберите пункт Manage
Components.
На вкладке Project Components (Рис. 5.30) выберите требуемую цель проекта
(«Simulator» или «Ulink») и нажмите на кнопку Set as Current Target.
В реальных проектах эта функция pVISION позволяет задать несколько раз-
личных сборок проекта или разместить в проекте несколько различных про-
грамм, являющихся составными частями одного большого приложения. 487
Глава 5. Учебное пособие по средствам разработки компании Keil
Рис. 5.30. Вкладка Project Components
Упражнение 2. Стартовый код
В этом упражнении мы с вами будем конфигурировать стартовый модуль ком-
пилятора, чтобы задать конфигурацию стеков всех рабочих режимов ЦПУ ARM7.
Откройте проект, расположенный в папке «C:\work\EX2-StartupCode».
Откройте файл «Startup.s» и, используя графический редактор, задайте следу-
ющую конфигурацию стеков (Рис. 5.31) для различных режимов работы ЦПУ:
Mstack Configuration (Stack Sizes in Bytes)
5 Undefined Mode 0x0000 0080
j Supervisor Mode 0x0000 0080
: Abort Mode 0x0000 0080
Fast Interrupt Mode 0x0000 0080
Interrupt Mode 0x0000 0080
User/System Mode 0x0000 0400
(+! VPSDIV Setup Г
Щ PLL Setup F
[+r MAM Setup F
Щ - >Г Ис' r,t г 4 .EMC- Г
Рис. 5.31. Задание конфигураций стеков
Скомпилируйте программу.
Запустите симулятор и, когда PC дойдет до функции main(), просмотрите со-
держимое каждого регистра R13 (Рис. 5.32).
188
Использование аппаратного JTAG-отладчика ULINK
~ h'SI ! иЭ* » < э U и и -V Cti*
i Project Workspace v х |
Register_________ | Value________________________|
s Л Current j
? Л User/System 5
i й Fast Interrupt I
• * Interrupt I
-i Supervisor____________________________________|
Размер каждого стека,
кроме стека режима User,
равен 0x80 байт.
Стек режима User
имеет размер 0x400 байт,
поэтому пользовательские
данные будут размещаться,
начиная с адреса
(0x40003680 - 0x400)
R13 (SPJ 0x4000040c
R14(LR) 0x00000000
+ SPSR 0x00000000
+ Abort
+' Undefined
t Internal
[=1F g„. | IQe; <^T
Рис. 5.32. Окно регистров
Проверьте флаги регистра CPSR, чтобы определить текущий режим работы и
используемый набор команд.
Последний элемент в окне регистров называется «Internal» и предоставляет
вам дополнительную информацию, в том числе о временных параметрах (если вы
работаете с симулятором).
Упражнение 3. Использование кода THUMB
В этом упражнении мы создадим простейшую программу, в которой из основ-
ной функции, скомпилированной с использованием 32-битных команд ARM,
вызывается 16-битная функция, после чего продолжают использоваться команды
ARM.
Откройте проект, расположенный в папке «C:\work\EX3-Thumb Code».
Добавьте в файл «main.c» следующие объявления для функции main() и
16-битной функции:
void main(void) _arm
void thumb_function(void) thumb // Два символа подчеркивания
В браузере проекта выделите корневую папку (Ulink) и выберите в контекст-
ном меню пункт Options for Target 6Ulink’. На вкладке С появившегося диалого-
вого окна (Рис. 5.33) можно задать набор команд, используемый по умолчанию,
снимая или устанавливая флажок Use Thumb Mode. Также можно определить на-
бор команд, используемый при компиляции конкретного модуля, снимая или ус-
танавливая этот же флажок в локальных настройках модуля.
Скомпилируйте программу и загрузите ее в отладчик.
Откройте окно дизассемблера и начните выполнять программу в пошаговом
режиме, используя клавишу Fl 1.
Проследите за переключением с 32-битного кода на 16-битный (Рис. 5.34) и
обратите внимание на флаг THUMB регистра CPSR. 189
Глава 5. Учебное пособие по средствам разработки компании Keil
Options for Target ’Simulation’
Device | Target) Output) Listing С |Asm | LA Misc | LA Locate) Debug) Utilities)
- Preprocessor Symbols
Define: |
Undefine: |
X|
Code Optimization -...-
Level: Loop stren^
Warnings: | Warninglevel 2
; Emphasis:
|Favor execution speed
P Use Thumb Mode
P treat plain char as 'unsigned char'
P Alias checking on pointer accesses
Include
Paths
Misc
Controls
Compiler
control
string
THUMB OPTIMIZE (7,SPEED) BROWSE DEBUG TABS (4)
| OK | Отмена | Defaults |
Справка
Puc. 5.33. Вкладка C
32-битный код ARM
l-IIJlOrj
R14 (LR)
UX4UUUUJIC
OxOOOOOOeS
S CPSR
N
Z
. C
0x40000010
0
? M
E SPSR
0
0
0
0
0
0x10
0x00000000
0x0000011^400000000 DD
0x00000114 >^000000 DD
t huiftb_ f unc 11 on
E59FC000 LDR
E12FFF1C BX
00000125 DD
(i = 0x00001000,1
10x00000118
OxOOOOOllC
0x00000120
46 for
47 {
48
^0x00000124
49 for
50 -f
51 ,
>0x00000126
52 }
2100
4806
(delay
MOV
0x00000000
0x00000000
R12,[PC]
R12
0x00000125
' 0x01000000
RO,[PC,#0x0018]
LDR _
0,delays 0x010000 delay++)
Rl,#0x00
'z s
F
16-битный код THUMB
Puc. 5.34. Переключение с 32-битного кода на 16-битный
Сначала процессор работает в 32-битном режиме ARM, флаг Т сброшен, а
размер слова команды равен 4 байтам. Затем вызывается THUMB-функция, в ре-
зультате чего выполняется команда ВХ, переключающая процессор в 16-битный
режим THUMB.
190
Использование аппаратного JTAG-отладчика ULtNK
Упражнение 4. Использование библиотек STDIO
В этом упражнении мы доработаем функцию printf(), чтобы она смогла рабо-
тать с модулем UART микроконтроллеров LPC2100. В дальнейшем мы рассмот-
рим регистры модуля UART более подробно.
Откройте проект, расположенный в папке «C:\work\EX4-STDIO».
В файл «main.c» добавьте строки, выполняющие вывод сообщения с исполь-
зованием функции printf():
while(1)
{
printf("Здесь Ваше сообшение \п"); // Вызываем функцию printf()
}
Добавьте файл «serial.c» в рабочую папку проекта (Рис. 5.35).
г; Si Simulation
Я ЕЗ С source code
Я Щ main.c
Q Ipc21xx.h
Q stdiOih
ft Ю serial.c
Я E3 Assembler startup code
И Startup.s
-j Documentation
Q abstract.txt
Puc. 5.35. Добавление файла «serial.c»
В файле «serial.c» допишите функцию putchar(), чтобы она выводила одиноч-
ный символ в последовательный порт,
int putchar (int ch)
{
if (ch == '\n')
{
while (!(UOLSR & 0x20));
UOTHR = CR;
}
while (!(UOLSR & 0x20));
return (UOTHR = ch);
}
Скомпилируйте программу и загрузите ее в отладочную плату или в симулятор.
Подключите разъем СОМО платы к последовательному порту СОМ1 ПК и за-
пустите программу «HyperTerminal» с файлом конфигурации, расположенном в
рабочей папке упражнения.
Если вы используете симулятор, выберите в меню View пункт Serial Window #1.
В результате в симуляторе откроется окно терминала, отображающее данные с
выхода модуля UART0. 191
Глава 5. Учебное пособие по средствам разработки компании Keil
Запустите программу и удостоверьтесь, что в окне терминала (Рис. 5.36) по-
явилось сообщение.
К printf - pVision3 - [Serial #1]
; File Edit View Project Debug Flash Peripherals Tools SVCS Window Help
® й u a * 4s e _ <•*
Й? i»H@ ft oMF !! Osifti
! Project Workspace________ „ ’ x
i Register | Value __________________|
13 Current______________________________________j
RO 0x00000026
R1 0x00000000
R2 0x00000020
R3 0x000001 dd
Hello World, well its traditional |
R4 0x00000000
R5 0x00000000
R6 0x00000000
R7 0x00000000
R8 0x00000000
: R9 0x00000000
R10 0x00000000
R11 0x00000000
R12 0x00000000
R13(SP) 0x400003fc
Э SPSR 0x00000000
® Us er/Sy stem
ф Fast Interrupt
ffli Interrupt
ffl Supervisor
ffi Abort
ffl Undefined
S Internal
PC $ 0x000001 DC
Mode User
States 2483556
Sec 0 04139513
E)F *{}F ’<^T |
I=1 mainc d=] serial c [=| Startups Serial Й1 [
*** Restricted Version with 16384 Byte Code Size Limit
*** Currently used 1866 Bytes (11X)
ASSIGN BreakDisable BreakEnable BreakKill BreakList BreakSet BreakAccess COVERAGE
Puc. 5.36. Окно терминала
Упражнение 5. Простое прерывание
В этом упражнении мы сконфигурируем простейшее прерывание FIQ и по-
смотрим, как оно обрабатывается.
^92 Откройте проект, расположенный в папке «C:\work\EX5-Interrupt».
Использование аппаратного JTAG-отладчика ULINK
В файле «main.c» допишите объявление функции FIQ_Handler(), чтобы она
была объявлена как подпрограмма обработки прерывания FIQ:
void FIQ_Handler (void) _fiq;
В файле «startup.s» допишите таблицу констант векторов прерываний, чтобы
функция FIQ_Handler() вызывалась в качестве подпрограммы обработки преры-
вания FIQ.
startup PROC PC, Reset_Addr
Vectors: LDR PC, =Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
Вектор прерывания FIQ. NOP /* Зарезервированный вектор */
Команда загружает адрес LDR PC, [PC, #—OxOFFO]
Си-подпрограммы в РС * LDR PC, FIQ_Addr
Reset_Addr: DD Reset_Handler
Undef_Addr: DD Undef_Handler
SWI_Addr: DD SWI_Handler
PAbt_Addr: DD PAbt_Handler
DAbt_Addr: DD DAbt_Handler
DD 0 /* Зарезервированный адрес */
В таблице констант I RQ_Addr: DD IRQ_Handler
хранится адрес > FlQ_Addr: DD FIQ_Handler?A
Си-подпрограммы
обработки прерывания FIQ
Скомпилируйте программу и загрузите ее в микроконтроллер на отладочной
плате.
Выполните программу в пошаговом режиме до цикла while().
Установите точку останова на функцию FIQ_Handler().
Нажмите F5 для запуска программы.
Нажмите кнопку INT1 на плате МСВ2100, чтобы сгенерировать прерывание.
Если вы хотите посмотреть механизмы входа в режим обработки исключи-
тельной ситуации и выхода из него, лучше всего использовать симулятор и вы-
полнять программу по шагам в окне дизассемблера. В этом случае вы сможете по-
наблюдать за ходом выполнения программы и изменением регистров ЦПУ. Что-
бы управлять прерыванием в симуляторе, откройте окно управления нулевым
портом ввода/вывода (меню Peripherals, пункт GPIO/Port 0). Если вы будете про-
должать выполнение программы, не отметив ячейку, соответствующую выводу
Р0.14, будет сгенерировано прерывание. Для прекращения генерации прерыва-
ния ячейку необходимо отметить (Рис. 5.37).
В качестве альтернативы, в инструментарии имеется специальная кнопка
Generate EINT 1 (Рис. 5.38 и Рис. 5.39). Нажатие на эту кнопку симулирует появ-
ление импульса на выводе прерывания.
В pVISION есть свой развитой язык сценариев, использование которого поз-
волит вам симулировать внешние события. Этот язык основан на синтаксисе 193
Глава 5. Учебное пособие по средствам разработки компании Keil
Эти ячейки управляют логическим уровнем на выводах
симулируемого микроконтроллера LPC2000
Рис. 5.37. Окно управления нулевым портом ввода/вывода
Toolbox |Х|
Update Windows
Generate El NT 1
Рис. 5.38. Кнопка
инструментария
Puc. 5.39. Панель инструментария с кнопками,
которые вызывают сценарии, конфигурируемые
пользователем
языка Си, а программы на нем хранятся в виде текстовых файлов. Сценарий, ис-
пользуемый для симуляции одиночного импульса, приведен ниже.
signal void Toggle(void)
{
PORTO = (PORTO A 0x4000);
twatch (200);
PORTO = (PORTO A 0x4000);
}
KILL BUTTON *
DEFINE BUTTON "Generate EINT 1","Toggle()"
Этот сценарий находится в файле «signal.ini», который добавляется в проект
на вкладке Debug окна задания опций для конечного устройства. Подробнее о
языке сценариев можно узнать из документации pVISION.
Упражнение 6. Программное прерывание
В этом упражнении мы объявим функцию обработки программного прерыва-
ния и посмотрим, как компилятор обработает вызов данной функции.
Откройте проект, расположенный в папке «C:\work\EX6-SWI».
Добавьте файл «SWI_VEC.S» в проект.
В файле «main.c» объявите две функции в качестве функций обработки про-
194 граммного прерывания:
Использование аппаратного JTAG-отладчика ULINK
void SWI_Calll(int pattern) _____swi(8)
{
}
void SWI_Call2(void) ______swi(9)
{
}
Скомпилируйте и загрузите код в отладчик.
Выполняйте программу в пошаговом режиме и наблюдайте за обработкой
программного прерывания.
В окне дизассемблера можно посмотреть вызов первой функции. При этом
передается параметр и вызывается команда SWI, в теле которой закодировано
число 8. В окне регистров регистр CPSR показывает, что мы находимся в режиме
User (Рис. 5.40).
:• iR14 (LR) 0x000000f5 |
В CPSR 0x40000030
г N 0
; Z 1
г С 0
? V 0
: I 0
: F 0
: Т 1
М -0x10
S SPSR / 0x00000000
U жег/System /
0x00000198 4905 LDR
0х0000019А 4807 LDR
0х0000019С 6001 STR
50: SVI_Calll(pattern);
51
0x0000019E 4807 LDR
OxOOOOOlAO DF08 SWI
RI,[PC,#0x0014]
R0,[PC,#0x001C]
RI,[R0,#0x00]
R0,[PC,#0x001C]
0x08
Режим User
Рис. 5.40
52. SWI_Call2(),
Г 53
54.
55 while(l)
56- {
57 ,
0x000001A2 DF09
58: >
n,.nnnnni M Г7ГГ
0x09
Команда перехода к функции
заменена командой SWI
После того как программное прерывание будет сгенерировано, процессор пе-
реключит режим работы, выполнит некоторый код из файла «vectors.s», а затем
войдет в нашу функцию SWI с номером 8 (Рис. 5.41).
include <LPC21xx.H>
s
й
R13 (SP) 0x40000400
R14 (LR) 0x000001 fc
М
Е SPSR
User/System
Р IrJarri irJ
30 void SWI_Calll(int pattern) ____swi(8)
3ig<
’•,32"
E33 IOCLR1 = OxOOFFOOOO;
34,. IOSET1 = pattern;
35 }
$ void SWI_Call2 (void) ______swi(9)
3®<
39 ( IOCLR1 = OxOOFFOOOO;
40 I IOSET1 = OxOOAAOOOO;
Режим Supervisor
Puc. 5.41
195
Глава 5. Учебное пособие по средствам разработки компании Keil
Упражнение 7. Модуль МАМ
Это упражнение демонстрирует важность использования модуля МАМ. Изна-
чально схема ФАПЧ работает на частоте 60 МГц, а модуль МАМ выключен. В про-
грамме реализовано поочередное мигание светодиодов отладочной платы. Это ре-
шение помогает визуально оценить производительность ЦПУ ARM7 при считы-
вании команд непосредственно из встроенной FLASH-памяти. При изменении
сопротивления переменного резистора модуль МАМ включается и программа на-
чинает выполняться быстрее, что можно заметить по увеличению частоты мига-
ния светодиодов. Это увеличение производительности вызвано исключительно
использованием блока МАМ. Именно поэтому он так важен в однокристальных
микроконтроллерах такого рода. В этом упражнении для записи кода программы в
FLASH-память мы вместо JTAG будем использовать загрузчик.
Откройте проект, расположенный в папке «C:\work\EX7-MAM».
Допишите код в файле «main.c» для разрешения работы модуля МАМ.
В окне задания опций для конечного устройства на вкладке Output установите
флажок Create HEX File.
Скомпилируйте программу.
Подключите последовательный порт ПК к разъему СОМО на отладочной плате.
Подайте питание на плату.
Запустите утилиту внутрисхемного программирования. Появится окно, пока-
занное на Рис. 5.42.
Рис. 5.42. Окно утилиты внутрисхемного программирования
Убедитесь, что флажок Use DTR/RTS установлен.
Нажмите кнопку Read Device ID. Если плата подключена правильно, будут
отображены идентификатор устройства и версия загрузчика.
Запомните эти значения, т.к. они нам потребуются при выполнении следую-
щего упражнения.
Затем откройте файл «MAM.hex» из рабочей папки проекта и нажмите кнопку
Upload to Flash. При этом будет выполнено программирование микроконтроллера
196 отладочной платы.
Использование аппаратного JTAG-отладчика ULINK
Можете также воспользоваться кнопкой Compare Flash, чтобы убедиться, что
программирование прошло нормально.
Если же вы выберете опцию Buffer (Рис 5.43), то, помимо выполнения этих
операций, можно будет вычислить сигнатуру программы и воспользоваться неко-
торыми рудиментарными возможностями отладки.
LPC2OOO Flash Utility Flash Buffer
ы и
LH0000 осой 18 F0 9F Е5 18 F0 9F Е5 18 F0 9F Е5 18 F0 9F Е5 .руе.руе «руе.руе
£НО000 0(110 13 ГО ЗГ Е5 00 00 ц0 Е1 ГО ГГ 1Г Г5 18 F0 9F Е5 .руе.. бря.е.руе
&НОООО 0020 40 00 00 00 С8 02 00 00 С4 02 00 00 СО 02 00 00 И...И...Д...Й«..
LH 0000 00 30 ВС 02 00 00 00 00 00 00 В8 02 00 00 В4 02 00 00
2Н0П00 3040 А8 00 9F Е5 02 10 АО ЕЗ 00 10 80 Е5 АО 00 9F Е5 Г.уе». 1 ..Ъе .уе
<<Н 0000 0050 АД 10 АО ЕЗ 55 20 АО ЕЗ 24 30 АО ЕЗ 04 30 80 Е5 С. гВ г$0 f .ВБе
Ы(Ю00 0060 01 30 АО ЕЗ 00 30 80 Е5 ОС 10 80 Е5 ОС 20 6’0 Е5 . й I . 0Ъе .. Бе. Ье
6Н0000 9070 08 30 90 Е5 01 38 19 Е2 рг FF FF (1А 03 30 АО ЕЗ . 0tje.; .вьяя. „О i
;^ноооо 0060 00 зп 80 Е5 ОС 10 80 Е5 ОС 20 80 Е5 64 00 9F Е5 .0Ье..Ъе. bed.уе
?<Н0о0и 0090 DB F0 21 ЕЗ 00 ио АО Е1 04 00 40 Е2 D7 ГО 21 ЕЗ Ыр?г .Р б..(?в’1р!г
он оооо подо 00 D0 АО Е1 04 00 40 Е2 D1 F0 21 ЕЗ 00 D0 АО Е1 .Р б ..йвСрТг »Р б
СНОСКИ зове 04 00 40 Е2 D2 F0 21 ЕЗ 00 D0 АО Е1 80 00 40 Е2 ..РвТр!г.Р бБ.Рв
ОН 0000 оосо 03 F0 21 ЕЗ 00 D0 АО Е1 04 00 40 Е2 10 F0 21 ЕЗ МрТг.Р б..Йв.р?г
^нооооооно 00 DO АО Е1 20 00 9F Е5 01 00 10 ЕЗ 1С Е0 9F 05 .Р 6 .уе.. .1 .ау.
АН 0000 00Е0 1С Е0 9F 15 10 FF 2F Е1 FE FF FF ЕА FE Е7 СО 46 «ау..я/бмяякюзйЕ
3H0000 00F0 по С1 1F F0 АО СО 1F Е0 94 П4 00 40 48 01 00 по .Ь.аБй.а".«ЫН...
йН 0000 0100 Е8 00 00 00 ED 00 00 00 00 00 00 40 04 00 00 40 и.. -н..... .й.. .й
АН0000 0110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ЕНОООО 0120 00 30 АО Е1 03 Ю АО Е1 01 20 Е0 Е1 ОС 00 9F Е5 . й б.. б. аб..ур
АЧОООО 0130 00 20 80 Е5 ну 00 9F Е5 00 10 80 Е5 1Е FF 2F Е1 . Ъе«.уе.»Ъе.я/б
1.Н0006 0140 1С 80 02 Е0 14 80 02 Е0 42 OF АО ЕЗ 06 00 ВО Е8 »Б«а»1».аВ« г.« и
АН 0000 0150 01 30 АО Е1 02 30 93 Е1 05 00 00 0А 00 30 АО ЕЗ .0 6.0" б 0 1
АНООООСПЕО 00 30 С1 Е5 01 10 81 Е2 02 00 51 EI FB FF FF 1А . Щ>е . .f'e. .0быяя.
АН0000 0170 F5 FF FF ЕА 46 OF АО ЕЗ 03 00 80 ЕЗ 03 30 АО ЕЗ хяякЕ . г.. Ьв.О г
LHOOOG 0160 03 00 СО Е1 06 00 во Е8 01 30 АО С1 02 30 93 Е1 ..06..°И.0 6.0" 6
ЯНОООО 0190 06 00 00 0А 00 30 D0 Е5 01 00 80 Е2 00 30 С1 Е5 0Рр. .Бв. 0Бр
&H0000 01А0 01 10 81 Е2 02 00 51 Е1 F9 FF FF 1А F1 FF FF ЕА .«Гв..рбцяя.сяяк
АН0000 01 к и 00 40 2D Е9 01 38 АО ЕЗ FF 18 Ай ЕЗ D0 00 ЗЕ- Е5 .й-й.В гя. гР.уе
LH0000 01 СО 00 10 80 Е5 02 10 АО ЕЗ С8 00 9F Е5 00 10 СО Е5 ..Ъе.. гИ.уе..йе
AHOOOU 0100 С4 10 9F Е5 С4 00 9F Е5 00 10 80 Е5 ВС 00 9F Е5 Д.уеД.уе. .Бе] .уе
6Н0000СПЕи 00 10 90 Е5 0I 14 81 ЕЗ по 10 80 Е5 ВО 00 9F Е5 .Бе°.уе
ОНОПОО 01F0 00 10 90 Е5 01 01 АО ЕЗ 00 10 80 Е5 01 01 АО ЕЗ г..Бе«. г
Load Hex File Vector Calc Upload to Flash Download Flash Save Hex File Fill Buffer
Code Execution — — - - - Run from Address 1^00000000 — Г Thumb & |ABM| <• Address Range - — — — | Selected Range Start: | AH00000000 | Г Entire Buffer End: |&H000002DF Fill Value: Jff“
LPC2000 Flash Utility
HEX File Loading Succeeded
Puc. 5.43. Окно Buffer
После того как программирование микроконтроллера будет завершено, он ав-
томатически перезагрузится и начнет выполнять вашу программу.
Установите движок переменного резистора в крайнее правое положение.
Сбросьте микроконтроллер, и светодиоды начнут поочередно мигать.
Если вы повернете движок переменного резистора против часовой стрелки,
модуль МАМ включится, и вы сможете заметить «ускорение» работы микроконт-
роллера.
В программе внутрисхемного программирования при использовании буфера
вы можете посмотреть шестнадцатеричный дамп вашей программы. Там же отоб-
ражается вычисленная сигнатура. 197
Глава 5. Учебное пособие по средствам разработки компании Keil
Если вы снова подключите JTAG-отладчик и запустите его без перезагрузки
программы, то сможете проверить содержимое таблицы векторов. Поскольку мы
программировали микроконтроллер с помощью утилиты внутрисхемного про-
граммирования компании Philips, по адресу 0x00000014 вместо кода команды
NOP будет находиться значение сигнатуры программы.
Упражнение 8. Внутрипрограммное программирование
В этом упражнении демонстрируется вызов функций загрузчика из приклад-
ной программы. А именно, из программы вызываются функции «Прочитать ID
устройства» и «Прочитать версию загрузчика». Используемый в упражнении про-
ект имеет только одну версию — для работы с оценочной платой МСВ2100.
Откройте проект, расположенный в папке «C:\work\EX8-IAP».
Добавьте в файл «main.c» следующие строки:
command[0] = 0x36;
iap_byfunction(command,result,0x7FFFFFF0);
command[0] = 0x37;
iap_byfunction(command,result,0x7FFFFFF0);
Допишите код функции iap_byfunction():
__asm { mov rl5,r2; }
После этого удостоверьтесь, что функция main() будет компилироваться с ис-
пользованием команд ARM, а функция iap_byfunction() — с использованием ко-
манд THUMB.
Скомпилируйте программу и запустите отладчик.
Выполните код программы до первого вызова функции iap_byfunction().
Установите точку останова на следующую после вызова этой функции строку
программы.
Войдите в функцию iap_byfunction().
Обратите внимание на содержимое регистров R0...R2. В этих регистрах долж-
ны находиться адрес таблицы параметров команды, таблицы результата и адрес
входа в функцию загрузчика. Кроме того, в регистре R14 должен находиться адрес
возврата в основную функцию.
Выполняйте по шагам ассемблерный код, пока не перейдете к адресу
0x7FFFFFFF. Это точка входа в программу загрузчика.
Теперь запустите программу в нормальном режиме, она выполнит вызванную
функцию загрузчика и вернется по адресу, записанному в регистре R14 (следую-
щая строка в файле «main.c»).
Когда программа попадет на точку останова, посмотрите состояние регистра
CPSR, чтобы определить используемый набор команд.
Взгляните на таблицу результатов команды и найдите значение идентифика-
тора устройства. Сравните его со значением, считанным при выполнении преды-
дущего упражнения.
Выполните вызов следующей функции загрузчика и удостоверьтесь, что она
возвращает корректный номер версии загрузчика.
198
Использование аппаратного JTAG-отладчика ULINK
Упражнение 9. Интерфейс внешней шины
В этом упражнении мы разберем, как следует конфигурировать проект, чтобы
в нем использовалась внешняя шина. Необходимо так скомпоновать код про-
граммы, чтобы он размещался во внешней микросхеме FLASH-памяти, а также
сконфигурировать все используемые банки внешней памяти. Так как на оценоч-
ной плате МСВ2100 отсутствуют внешние микросхемы памяти, то для демонстра-
ции работы интерфейса внешней шины будет использоваться симулятор. Проект
собирается таким образом, что часть кода программы размещается в FLASH-па-
мяти, начиная с адреса 0x80000000 (линия CS0), а часть — в ОЗУ, начиная с адреса
0x81000000 (линия CS1). В реальном устройстве способ загрузки определяется со-
стоянием двух выводов управления загрузкой. Для задания корректных состоя-
ний этих выводов в симуляторе мы воспользуемся файлом сценария. Тем не ме-
нее, мы рассмотрим также и конфигурирование интерфейса JTAG для програм-
мирования внешней FLASH-памяти, так что это упражнение можно будет
выполнить на реальном устройстве.
Откройте проект, расположенный в папке «C:\work\EX9-EBI».
В окне задания опций для конечного устройства на вкладке Device выберите
микроконтроллер LPC2294.
Перейдя затем к вкладке Target, снимите флажок Use On-chip ROM и занесите
значения в поля блока External Memory, как показано на Рис. 5.44.
Рис. 5.44. Вкладка Target
Затем выделите в браузере проекта файл «Startup.s», вызовите контекстное ме-
ню, выберите в нем пункт Options for File ‘Startup.s’ и перейдите в появившемся
окне к вкладке Asm. 199
Глава 5. Учебное пособие по средствам разработки компании Keil
Введите в строку задания директив определение «EXTERNAL_MODE», как
показано на Рис. 5.45.
Рис, 5,45, Вкладка Asm
Этим гарантируется, что код стартового модуля будет скомпилирован для за-
грузки из внешней памяти.
Затем в редакторе конфигурации стартового модуля задайте параметры, опре-
деляющие конфигурацию банков внешней памяти (Рис. 5.46).
Э Stack Configuration (Stack Sizes in Bytes)
S PLL Setup P
Щ MAM Setup p
□ External Memory Controller (EMC) p
S Bank Configuration O(BCFGO) P
IDCY: Idle Cycles 3
WST1: Wait States 1 7
WST2: Wait States 2 7
RBLE: Read Byte Lane Enable П
WP: Write Protect Г
: BM: Burst ROM Г
MW: Memory Width 32-bit
В Bank Configuration 1 (BCFG1) P
IDCY: Idle Cycles 3
WST1: Wait States 1 7
WST2: Wait States 2 7
j RBLE: Read Byte Lane Enable p
; WP: Write Protect Г
BM: Burst ROM Г
MW: Memory Width 32-bit
’+ 4 » H • ? " “FC Г~
В Configuration J (ЮСЗ) Г
Puc, 5,46, Редактор конфигурации
стартового модуля
200
Использование аппаратного JTAG-отладчика ULINK
Скомпилируйте программу и запустите симулятор.
В окне дизассемблера (Рис. 5.47) видно, что счетчик команд установлен на ад-
рес 0x00000000 и в этой области памяти отсутствует осмысленный код.
Откройте окно управления распределением памяти (меню Peripherals, пункт
System Control Block, подпункт Memory Mapping Control), Рис. 5.48.
0x00000000
0x00000004
0x00000008
ОхОООООООС
0x00000010
0x00000014
0x00000018
0x0000001c
0x00000020
0x00000024
0x00000028
0x0000002C
0x00000030
0x00000034
0x00000038
ОхООООООЗС
0x00000040
0x00000044
nvnnnnnndfi
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
nnnnnnnn
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
йЫПРП
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
RO,RO,RO
RO,RO,RO
RO,RO,RO
RO,RO,RO
РП РП РП
Memory Mapping Control |X|
>?
г Memory Mapping Control-------
I MEMMAP: jOxOl
| MAP:
Puc, 5,47. Окно дизассемблера
Рис, 5,48. Окно управления
распределением памяти
Выберите в ниспадающем списке значение «User Ext. Mem. Mode».
В результате первые 64 байта памяти, подключенной к 0-му банку, будут отоб-
ражены на область памяти, начиная с адреса 0x00000000. Это наша таблица пре-
рываний (Рис. 5.49), размещенная во внешней FLASH-памяти.
10x00000000
0x00000004
0x00000008
ОхОООООООС
0x00000010
0x00000014
0x00000018
0x0000001с
0x00000020
0x00000024
0x00000028
0х0000002С
0x00000030
0x00000034
0x00000038
^ОхООООООЗС
«0x00000040
Й0х00000044
^0x00000048
E59FF018
E59FF018
E59FF018
E59FF018
E59FF018
Е1А00000
E51FFFF0
E59FF018
80000040
80000320
8000031С
80000318
80000314
00000000
80000310
8000030С
00000000
00000000
00000000
LDR
LDR
LDR
LDR
LDR
NOP
LDR
LDR
DD
DD
DD
DD
DD
DD
DD
DD
ANDEQ
ANDEQ
ANDEQ
PC,[PC,#0x0018] A,j
PC,[PC,#0x0018]
PC,[PC,#0x0018]
PC,[PC,#0x0018]
PC,[PC,#0x0018]
PC,[PC,#-0x0FF0]
PC,[PC,#0x0018]
0x80000040
0x80000320
0x8000031C
0x80000318
0x80000314
0x00000000
0x80000310
0x8000030C
R0,R0,R0
R0,R0,R0
R0,R0,R0 v:
> "
Puc, 5.49. Окно дизассемблера:
таблица прерываний, размещенная во внешней FLASH-памяти
Если вы выполните один шаг программы, то произойдет переход по адресу
0x80000040 и начнет выполняться код из внешней микросхемы FLASH-памяти.
Аппаратный отладчик ULINK тоже можно сконфигурировать для програм-
мирования внешних микросхем FLASH-памяти. Для этого необходимо выпол-
нить следующие действия.
Откройте окно задания опций для конечного устройства и на вкладке Utilities
укажите файл «Flash.ini», как показано на Рис. 5.50.
201
Глава 5. Учебное пособие по средствам разработки компании Keil
Рис. 5.50. Вкладка Utilities
Это файл сценария, который используется отладчиком ULINK для задания кон-
фигурации необходимых банков внешней памяти, разрешающей занесение кода
программы во внешнюю FLASH-память. По существу, эта конфигурация должна
соответствовать значениям, указанным при конфигурировании стартового кода.
Затем нажмите кнопку Settings и в появившемся окне добавьте алгоритм про-
граммирования для используемой микросхемы (Рис. 5.51).
|Х|
Flash Download Setup
Рис. 5.51. Добавление алгоритма программирования
После этого программу отладки можно будет легко использовать с аппарат-
202 ным JTAG-отладчиком и внешней микросхемой FLASH-памяти.
Использование аппаратного JTAG-отладчика ULINK
Упражнение 10. Схема ФАПЧ
В этом упражнении мы сконфигурируем схему ФАПЧ таким образом, чтобы
достичь максимально возможной скорости работы ядра ARM7 при использова-
нии резонатора на частоту 12 МГц. Кроме того, мы зададим такую конфигурацию
шины VPB, при которой она будет работать в два раза медленнее ядра ARM7.
Вычислите значение константы М по формуле CCLK = М х Fosc, учитывая,
что Fqsc = 12 МГц, а ССьк = 60 МГц.
Вычислите подходящее значение константы Р, используя формулу
Fcco = Cclk х 2 х Р и учитывая, что 156 МГц < FCCo < 320 МГц.
Используя полученные значения М и Р, вычислите значение, записываемое в
регистр PLLCFG.
(Ответ: М = 5, Р = 2.)
Вычислите значение, записываемое в регистр VPBDIV, при котором частота
Pclk будет в два раза меньше частоты CCLK.
Откройте проект, расположенный в папке «C:\work\EX10-PLL».
Допишите код подпрограммы init_PLL() в файле «main.c» следующим образом.
Сконфигурируйте умножитель и делитель схемы ФАПЧ для достижения час-
тоты 60.00 МГц:
PLLCFG = 0x00000024;
Разрешите работу схемы ФАПЧ, используя регистр PLLC ON:
PLLCON = 0x00000001;
Обновите внутренние регистры схемы ФАПЧ, записав управляющую после-
довательность:
PLLFEED = ОхООООООАА;
PLLFEED = 0x00000055;
Проконтролируйте установку бита LOCK регистра PLLSTAT:
while (!(PLLSTAT & 0x00000400)) ;
Подключите выход схемы ФАПЧ в качестве основного источника тактовых
сигналов:
PLLCON = 0x00000003;
Снова обновите внутренние регистры схемы ФАПЧ:
PLLFEED = ОхООООООАА;
PLLFEED = 0x00000055;
Задайте частоту шины VPB равной 30.00 МГц:
VPBDIV = 0x00000002;
Скомпилируйте программу и загрузите ее в микроконтроллер отладочной
платы.
Выполните подпрограмму init_PLL() и посмотрите результат ее выполнения в
окне регистров схемы ФАПЧ (меню Peripherals, пункт System Control Block, под-
пункт Phase Locked Loop). В этом окне (Рис. 5.52) будет отображено действитель-
ное значение тактовой частоты системной шины. 203
Глава 5. Учебное пособие по средствам разработки компании Keil
Phase Locked Loop (PLL) fx|
r Control Register —------—----------------—— ---------i
I PLLCON: f6xO3 p PLLE p PLLC |
r Configuration Register-----——---------------------—
| PLLCFG: |0x24... MSEL:[Fj| PSEL;P”~z]
r Status Register - •————.................... —..
PLLSTAT: 10x0724 ~ MS EL: |S PSEL:
P PLLE P PLLC p PLOCK
r Feed Register —-------—------------------------------i
| PLLFEED: Гох55~ I
г Crystal Oscillator & Processor Clock-------------—i
i XT AL: | 12666000 MHz Crystal Oscillator (Fosc) j
I CLOCK: J SCLOOOOOO MHz Processor Clock (CCLK) I
Option _ I Value
+: Stack Configuration (Stack Sizes in Bytes)
:+] VPBDIV Setup p
PLL Setup
MSEL: PLL Multiplier Selection 5
PSEL: PLL Divider Selection 2
/+• MAM Setup P
v- .nr Г
Puc. 5.52. Окно регистров схемы ФАПЧ
Puc. 5.53. Установки стартового кода
Конфигурирование схемы ФАПЧ можно выполнить и в стартовом модуле,
однако в данном упражнении эта возможность не используется. Аналогичные ус-
тановки стартового кода показаны на Рис. 5.53.
Упражнение 11. Быстрое прерывание
В этом упражнении мы сконфигурируем внешнее прерывание так, чтобы
оно обрабатывалось как быстрое прерывание (FIQ). Этот же код использовался
в 5-м упражнении для демонстрации поддержки прерываний компилятором.
В этот раз мы посмотрим, как следует конфигурировать микроконтроллер для
поддержки прерывания FIQ.
Откройте проект, расположенный в папке «C:\work\EXll-InterruptFIQ».
Сконфигурируйте внешнее прерывание в качестве прерывания FIQ, записы-
вая следующее значение в регистр VICIntSelect:
VICIntSelect = 0x00008000;
Скомпилируйте программу, запустите отладчик и удостоверьтесь, что преры-
вание обрабатывается, как показано в 5-м упражнении.
Имя подпрограммы обработки прерывания должно соответствовать указан-
ному в таблице констант векторов в файле «startup.s». По умолчанию это
FIQHandler.
При использовании симулятора генерацию прерывания можно вызвать сбро-
сом вывода Р0.14 в окне GPIO 0 или с помощью кнопки инструментария Generate
EINT1.
Упражнение 12. Векторное прерывание
В этом упражнении мы сконфигурируем источник прерывания так, чтобы он
обрабатывался контроллером VIС как векторное прерывание. Мы будем исполь-
зовать то же самое внешнее прерывание, что и в упражнении 11, однако на этот
раз напишем свой собственный обработчик для быстрого обслуживания запроса.
204
Использование аппаратного JTAG-отладчика ULINK
Откройте проект, расположенный в папке «C:\work\EX12-InterruptVectored».
Сконфигурируйте 0-й слот векторного контроллера прерываний для обслу-
живания внешнего прерывания EINT1:
VICVectCntIO = 0x0000002F;
Поместите адрес подпрограммы обработки внешнего прерывания в соответ-
ствующий регистр адреса вектора:
VICVectAddrO = (unsigned)EXTINTVectoredlRQ;
Допишите код подпрограммы EXTINTVectoredlRQ для корректного заверше-
ния обработки прерывания:
EXTINT = 0x00000002;
VICVectAddr = 0x00000000;
Скомпилируйте программу и запустите ее в отладчике.
Запустите программу на выполнение и убедитесь, что вход в обработчик пре-
рывания выполняется корректно и что при каждом нажатии на кнопку, подклю-
ченную к выводу РО. 14, он вызывается только один раз.
Если вы используете симулятор, откройте окно управления 0-м портом вво-
да/вывода. Прерывание можно будет сгенерировать сбросом вывода Р0.14 или
нажатием на кнопку инструментария Generate EINT1.
Откройте в отладчике окно управления модулем VIC (Рис. 5.54) и ознакомь-
тесь с его структурой и конфигурацией модуля.
Vectored Interrupt Controller (VIC) fx]
Channel | Source | Name | Type
5 Timer 1 IRQ
6 UARTO IRQ
7 UART1 IRQ
8 PWM IRQ
9 I2C IRQ
10 SPIO IRQ
11 SPI1 IRQ
12 PLLLock PLOCK IRQ
13 RTC IRQ
14 External Interrupt 0 EINTO IRQ
16 External Interrupt 2 EINT2 IRQ
Vector | IntEnable | Rawlnt I *
OOOOOOOOH 0 0
OOOOOOOOH 0 0
OOOOOOOOH 0 0
OOOOOOOOH о 0
OOOOOOOOH о 0
OOOOOOOOH о 0
OOOOOOOOH о 0
OOOOOOOOH 0 1
OOOOOOOOH о 0
OOOOOOOOH о 0
OOOOOOOOH о 0
Все слоты модуля VIC
г Selected Interrupt: External Interrupt 1
P IntEnable F“ IntSelect
Г Softlnt F Rawlnt
IRQ Slot: | o/3
VICVectAddrO: [OxOOOOOW
VICVectAddr: [6^00000130 VICIntSelect: f&^OOOOOOO” VICRawIntr: [OxOOOOSCOO ?
VlCScfllnt:(bxbbbddood VICIntEnaWe: [&66Ьо8б6о““ VICIRQStatus: [(ЪюбббЙЬб j
VlCSoWntClear: [ЬхбббоЬооЬ VIClntEnClr [ЬхОООООООО VICFIQStatus: |6х66Ьо66Ьо j
Подробная информация
о выделенном слоте
Содержимое глобальных регистров
контроллера
Рис. 5.54. Окно управления модулем VIC
При работе с симулятором воспользуйтесь счетчиком тактов, чтобы опреде-
лить, сколько времени требуется микроконтроллеру для перехода к первой
строке подпрограммы обработки прерывания. Этот счетчик находится в окне
регистров.
205
Глава 5. Учебное пособие по средствам разработки компании Keil
Упражнение 13. Невекторное прерывание
В этом упражнении мы будем использовать векторный контроллер для полу-
чения самой медленной реакции на прерывание — обработки запроса как невек-
торного прерывания. Для генерации прерывания мы будем использовать внеш-
нее прерывание EINT1. При возникновении этого события модуль VIC будет вы-
зывать переход процессора к подпрограмме обработки прерывания общего
назначения. После входа в эту подпрограмму необходимо определить источник
прерывания, выполнить необходимые действия, а затем корректно выйти из нее
и возобновить нормальное выполнение программы.
Откройте проект, расположенный в папке «C:\work\EX13-InterruptNonVectored».
В файле «Startup.s» добавьте соответствующий код для вектора прерывания IRQ:
LDR PC,[PC, #-0x0FF0]
В файле «main.c» сконфигурируйте блок управления выводами, чтобы разре-
шить использование вывода РО. 14 в качестве входа внешнего прерывания:
PINSEL0 = 0x20000000;
Поместите адрес подпрограммы NonVectoredIRQO в регистр адреса вектора
по умолчанию. Напоминаю, что на языке Си это делается следующим образом:
VICDefVectAddr = (unsigned)<имя подпрограммы-обработчикам
Разрешите в модуле VIC канал внешнего прерывания:
VICIntEnable = 0x8000;
В подпрограмме обработки прерывания проконтролируйте регистр состояния
IRQ для определения источника прерывания:
if(VICIRQStatus&0x0000801000)
В конце подпрограммы обработки прерывания сбросьте флаг в регистре
EINT0 и выполните фиктивную запись в требуемый регистр модуля VIC для
сброса источника прерывания:
IOSET1 = OxOOFFOOOO;
EXTINT = 0x00000002;
Скомпилируйте программу и запустите отладчик.
Выполняя программу, удостоверьтесь, что вход в обработчик прерывания осу-
ществляется корректно и что он вызывается только один раз при каждом нажатии
на кнопку EINT1.
Если вы используете симулятор, откройте окно управления 0-м портом вво-
да/вывода. Прерывание можно будет сгенерировать сбросом вывода Р0.14. Или
же откройте окно инструментария и воспользуйтесь кнопкой Generate EINT1.
При работе с симулятором воспользуйтесь счетчиком тактов, чтобы опреде-
лить, сколько времени требуется микроконтроллеру для перехода к первой строке
206 подпрограммы обработки прерывания.
Использование аппаратного JTAG-отладчика ULINK
Упражнение 14. Вложенные прерывания
В этом упражнении мы будем работать с двумя источниками прерываний —
таймером 0 и внешним прерыванием. На время выполнения каждого из преры-
ваний на определенные выводы микроконтроллера выдается напряжение
НИЗКОГО уровня. При нормальной работе оба прерывания во время своего
выполнения блокировали бы друг друга. Однако, вставив в подпрограмму об-
работки внешнего прерывания соответствующие макросы, мы можем сделать
так, чтобы прерывание от таймера прерывало обработку внешнего прерыва-
ния, т.е. гарантированно генерировалось каждые 10 мс. Это можно наблюдать
визуально на светодиодах платы МСВ2100 или в окне логического анализатора
симулятора.
Откройте проект, расположенный в папке «C:\work\EX14-Nested Interrupt».
В файле «Intrpt.c» допишите два макроса IENABLE и IDISABLE:
#define IENABLE и Вход во вложенное прерывание
asm { MRS LR, SPSR } // Копируем SPSR_irq в LR
asm { STMFD SP! , {LR} } и Сохраняем SPSR_irq
asm { MSR CPSR. _C, #0xlF } и Разрешаем IRQ (режим System)
asm { STMFD SP! , {LR} } и Сохраняем LR
#define IDISABLE // Выход из вложенного прерывания
asm { LDMFD SP! , {LR} } и Восстанавливаем LR
asm { MSR CPSR. _c, #0x92 } и Запрещаем IRQ (режим IRQ)
asm { LDMFD SP! , {LR} } и Восстанавливаем SPSR_irq в LR
asm { MSR SPSR. _cxsf, LR } II Копируем LR в SPSR_irq
Добавьте оба макроса в подпрограмму обработки внешнего прерывания:
void eintl_srv (void) __irq
int i;
EXTINT = 2; IENABLE; // Сбросим флаг прерывания EINT1 // Разрешаем вложенные прерывания
delay (); // Ждем
++intrp_count; // Инкрементируем счетчик
IDISABLE; // Запрещаем вложение прерываний
VICVectAddr = 0; // Подтверждаем прерывание
Скомпилируйте программу и загрузите ее в отладчик.
Если вы используете плату МСВ2100, запустите программу на выполнение в
реальном времени. Периодически мигающий светодиод управляется прерывани-
ем от таймера. Если вы нажмете кнопку INT1, включится второй светодиод, ко-
торый управляется внешним прерыванием. Тем не менее, светодиод таймера про-
должит мигать, поскольку прерывание не заблокировано.
Если вы используете симулятор, то это же поведение вы можете наблюдать в
окне логического анализатора.
Удалите макросы IDISABLE и IENABLE из обработчика и посмотрите, как в
этом случае будет вести себя программа.
207
Глава 5. Учебное пособие по средствам разработки компании Keil
Упражнение 15. Порты ввода/вывода общего назначения
В этом упражнении мы будем использовать выводы портов ввода/вывода об-
щего назначения. Ряд выводов будут сконфигурированы как выходы, после чего
на них последовательно будут выдаваться импульсы ВЫСОКОГО уровня.
Откройте проект, расположенный в папке «C:\work\EX15-GPIO».
Добавьте в файл «main.c» включаемый файл с определениями РСФ микро-
контроллеров LPC21xx:
#include <LPC21xx.H>
Занесите требуемое значение в регистр направления передачи данных, чтобы
выводы Р1.16...Р1.23 функционировали как выходы:
IODIR1 = OxOOFFOOOO;
Допишите подпрограмму ChangeGPIOPinState(), чтобы она сбрасывала и ус-
танавливала соответствующие выводы:
IOCLR1 = -state;
IOSET1 = state;
Скомпилируйте программу и загрузите ее в отладчик.
Если вы запустите программу на плате МСВ2100, то увидите бегущий огонек,
формируемый линейкой светодиодов.
Если вы используете симулятор, выполняйте программу в пошаговом режиме
и наблюдайте за ее работой, отслеживая состояние контактов ввода/вывода с по-
мощью окна GPIO 1.
Упражнение 16. Функция захвата (capture)
В этом упражнении мы будем использовать таймер 0 для измерения времени
между запуском таймера и появлением нарастающего фронта сигнала на выводе
Р0.2. Поскольку на плате МСВ2100 нет кнопки на входе канала захвата, которая
позволила бы нам сгенерировать импульс, будем использовать симулятор. Версия
для аппаратного отладчика тоже имеется, однако для ее корректной работы вам
потребуется доработать плату. В этом случае работу программы можно будет кон-
тролировать с помощью осциллографа по выходным сигналам:
Pclk = 30 МГц,
Pciocktick “ 0.033 МГц.
Откройте проект, расположенный в папке «C:\work\EX16-TimerCapture».
Внесите в файл «main.c» следующие изменения.
Разрешите работу вывода Р0.2 в качестве входа 0-го канала захвата:
PINSEL0 = 0x00000020;
Загрузите в предделитель значение, необходимое для получения микросе-
кундных интервалов:
TOPR = OxOOOOOOlE;
Сбросьте счетный регистр и предделитель таймера:
208 T0TCR = 0x00000002;
Использование аппаратного JTAG-отладчика ULINK
Сконфигурируйте 0-й канал захвата для захвата по нарастающему фронту:
T0CCR = 0x00000005;
Разрешите работу таймера:
T0TCR = 0x00000001;
В подпрограмме обработки прерывания скопируйте захваченное значение во
временную переменную:
value = T0CR0;
Скомпилируйте программу и загрузите ее в отладчик.
Проконтролируйте работу прерывания по захвату, устанавливая точку остано-
ва на обработчик прерывания и выполняя программу.
В версии проекта для симулятора в инструментарий был добавлен сценарий, гене-
рирующий импульс на выводе Р0.2. При использовании платы МСВ2100 необходимо
подтянуть вывод порта к линии Vcc, подключив резистор сопротивлением 10 кОм.
В симуляторе убедитесь, что изменение состояния таймера происходит с тре-
буемой частотой. Для этого выполняйте программу в пошаговом режиме до изме-
нения состояния таймера и измерьте временной интервал с помощью счетчика в
окне регистров (Рис. 5.55).
Счетный регистр таймера
Значение таймера
при захвате —
Рис, 5.55. Окно регистров таймера
Упражнение 17. Функция совпадения (match)
В этом упражнении мы сконфигурируем таймер для генерации ШИМ-сигна-
ла, управляемого по одному фронту, с использованием двух каналов совпадения.
Нулевой канал будет использоваться для формирования общего периода ШИМ-
сигнала. При событии совпадения он будет сбрасывать таймер и генерировать
прерывание. Первый канал будет использоваться для управления скважностью
сигнала. При совпадении он будет сбрасывать выход 1-го канала совпадения. Ус-
танавливаться этот вывод будет в начале периода (при прерывании). 209
Глава 5. Учебное пособие по средствам разработки компании Keil
Откройте проект, расположенный в папке «C:\work\ EX17-TimerMatch».
Внесите в файл «main.c» следующие изменения.
Разрешите работу вывода Р0.5 в качестве выхода 1-го канала совпадения:
PINSELO |= 0x00000800;
Сконфигурируйте нулевой канал так, чтобы он сбрасывал таймер и генериро-
вал прерывание:
T0MCR = 0x00000003;
Задайте период ШИМ-сигнала равным 16 мс:
T0MR0 = 0x00000010;
Задайте коэффициент заполнения сигнала равным 50%:
T0MR1 = 0x00000008;
Задайте сброс выхода 1-го канала при совпадении (ВЫСОКИЙ уровень также
устанавливается при генерации первого периода сигнала):
T0EMR = 0x00000042;
В подпрограмме обработки прерывания установите выход 1-го канала:
T0EMR |= 0x00000002;
Скомпилируйте программу и загрузите ее в отладчик.
Запустите программу и посмотрите с помощью осциллографа сигнал на выво-
де Р0.5.
И снова мы можем посмотреть конфигурацию таймера в окне периферийного
устройства (Рис. 5.56).
Timer 0 [х]
г Prescaler —:------
PR :jOxOOOOOO1E
РС:|0х00000009
Г Timer~- ; —*j р Interrupt Register —-------------------------
tcr: |oxoooooooi рьиы. | |Я:|0>000:(Ю01
ТС|ОхОООООООО г Reset
Совпадение
при 0x10 ..»
Генерировать . »
прерывание и сброс
[Match Channels
MCR: |0х00000003
MR0: |bxOOOOOO10
P Interrupt on MR0
p Reset on MR0
Г StoponMRO
EMCO: | Nothing ’rj
Г External Match 0
p MRO Interrupt
EMR: [6x00000042“
MR1:10x00000008
F Interrupt on MR 1
F Reset on MR1
F StoponMRI
EMC1: [clear 3
p ExternalMatchl
Г MR1 Interrupt
MR2:10x00000000
Г Interrupt on MR2
F Reset on MR2
Г StoponMRZ
EMC2: | Nothing 7[
Г External Match 2
Г MR2 Interrupt
MRa-|oxoooo66oo
F Interrupt on MR3
Г Reset on MR3
Г StoponMR3
EMCl | Nothing 3
F External Match 3
F MR3 Interrupt
Совпадение
— при 0x08
Capture Channels -——— > —..................................................
OCR: fOxOOOOOOOO
CR0: [OxOOOOOOOO №1:(6>Йо6о6оГ“ CR2: |0x00000000 CR3: [OxOOOOOOOO
Г Rising Edge 0 | Rising Edge 1
F Faffing Edge 0 F FaingEdgel
Г Interrupt on Event 0 F Interrupt on Event 1
F CRO Interrupt Г CR1 Interrupt
F RisingEdge2 F Rising Edge 3
Г FaingEdge2 F Falling Edge 3
F Interrupt on Event 2 F Interrupt on Event 3
F САРП. 2 F CAPQ3
F CR2 Interrupt F CR3 Interrupt
Puc. 5.56. Окно периферийного устройства, таймер
В составе симулятора также имеется логический анализатор, в окне которого
можно в виде графика наблюдать изменение состояния выводов с течением време-
ни. Для использования логического анализатора необходимо сделать следующее.
210
Использование аппаратного JTAG-отладчика ULINK
Откройте окно логического анализатора, выбрав в меню View пункт Logic
Analyzer. Нажмите кнопку Setup в левом верхнем углу.
Добавьте новый сигнал (назовем его PORTO), установите значение маски (по-
ле Mask) равным 0x00000020 и способ отображения (поле Display Type) — Bit
(Рис. 5.57).
I Cunent Logic Analyzer Signals:
Setup Logic Analyzer
PORTO
Рис. 5.57. Добавление нового сигнала
Удалите имеющийся сигн<
Добавьте новый сигнал
После запуска программы любое изменение состояния вывода МАТ0.1 будет
отображено в окне логического анализатора (Рис. 5.58).
Рис. 5.58. Окно логического анализатора
211
Глава 5. Учебное пособие по средствам разработки компании Keil
Упражнение 18. Генерация симметричного ШИМ-сигнала
В этом упражнении мы воспользуемся модулем ШИМ для создания однока-
нального генератора симметрично модулированного ШИМ-сигнала. При этом
канал МАТО будет формировать общий период сигнала, а также осуществлять
сброс счетного регистра таймера. Канал МАТ1 будет определять момент форми-
рования нарастающего фронта сигнала, а канал МАТ2 — момент формирования
спадающего фронта сигнала. После запуска программы коэффициент заполне-
ния сигнала можно будет менять, нажимая клавиши «+» и «—» в окне терминала
Serial Window #2.
Откройте проект, расположенный в папке «C:\work\ EX18-PWMModule».
Внесите в файл «main.c» следующие изменения.
Разрешите работу вывода Р0.7 в качестве выхода 2-го канала ШИМ (PWM2):
PINSELO 1= 0x00028000;
Сконфигурируйте 2-й канал ШИМ для управления по двум фронтам, разре-
шите формирование выходного сигнала:
PWMPCR = 0x0000404;
Сконфигурируйте 0-й канал для сброса счетного регистра:
PWMMCR = 0x00000003;
Задайте начальные значения 1-го и 2-го каналов для формирования началь-
ного «импульса», который будет затем постепенно расширяться в основном цик-
ле программы:
PWMMR0 = OxOOOOOOFF;
PWMMR1 = 0x00000080;
PWMMR2 = 0x00000080;
Разрешите теневые регистры-защелки для каналов 0...2:
PWMLER = 0x00000007;
Сбросьте счетчик, предделитель и разрешите режим ШИМ:
PWMTCR = 0x00000002;
Разрешите работу счетчика и ШИМ:
PWMTCR = 0x00000009;
В главном цикле разрешите обновление регистров модуля из теневых защелок
при появлении новых значений ШИМ:
PWMLER = 0x00000006;
Скомпилируйте программу и загрузите ее в отладчик.
Запустите программу и с помощью симулятора убедитесь, что она работает
правильно.
Для просмотра конфигурации модуля ШИМ можно использовать окно пери-
212 ферийного устройства (меню Peripheral, пункт Pulse Width Modulator), Рис. 5.59.
Использование аппаратного JTAG-отладчика ULINK
Pulse Width Modulator (PWM)
1*1
PR: |0x00000001
PC: |0x00d00660
TCR: 10x00000003 P Counter Enable
________________ Г Reset
TC: jOxOOOOOOEB p PWM Enabie
IR: jOxOOOOOOOO
Match Channels ———————— --;--——— -----——~~—————
x I MRx | Interrupt[Reset | S top | EMC | E xt M atch I MRxInt [ Latch | р^дд
1 00000036H ооо
2 000000C9H 000
3 OOOOOOOOH 000
4 OOOOOOOOH ООО
5 OOOOOOOOH ООО
6 OOOOOOOOH ООО
Set О 0 10
Set 0 0 10
Nothing О ООО
Nothing О ООО
Nothing О ООО
Nothing О ООО
r Selected Channel—
MR0: |OxOOOOOOFF
p Match 0 Latch
Г” MR0 Interrupt
p Interrupt on MR0
p Reset on MR0
П StoponMRO
EMCO: [Nothing ▼“[
Г~ External Match 0
MCR: |Ox6o6oOOO3 EMR; [dxOOOOoSo LER: [OxOOOOOOO? PCR: [6x06000404~
Puc. 5.59. Окно периферийного устройства, ШИМ-модулятор
Для контроля сигнала на выводе PWM1 можно воспользоваться логическим
анализатором симулятора (Рис. 5.60). На этот раз значение маски должно быть
равно 0x000000080.
Рис. 5.60. Окно логического анализатора
213
Глава 5. Учебное пособие по средствам разработки компании Keil
Упражнение 19. Часы реального времени
В этом упражнении мы научимся использовать все основные возможности
модуля часов реального времени. Сначала мы сконфигурируем делитель опорной
частоты для получения тактового сигнала с частотой 32.768 кГц. После этого мы
можем сконфигурировать регистр управления прерыванием по инкременту для
формирования ежесекундного прерывания и регистры управления прерыванием
по сигналу для формирования прерывания на третьей секунде.
Частота внешнего генератора =12 МГц, CCLK = 60 МГц, PCLK = 30 МГц.
Вычислите значение регистра PREINT по формуле:
PREINT = (int)(PCLK/32 768) - 1.
(Ответ: 0x392.)
Вычислите значение регистра PREFRAC по формуле:
PREFRAC = Pclk - ((PREINT + 1) х 32 768).
(Ответ: 0x4380.)
Откройте проект, расположенный в папке «C:\work\ EX19-RTC».
Внесите в файл «main.c» следующие изменения.
Загрузите значения в регистры PREINT и PREFRAC:
PREINT = 0x00000392;
PREFRAC = 0x00004380;
Разрешите прерывание от счетчика секунд:
CIIR = 0x00000001;
Установите сигнальный регистр секунд на 3 с и разрешите формирование сиг-
нала от регистра секунд:
ALSEC = 0x00000003;
AMR = OxOOOOOOFE;
Запустите часы реального времени:
CCR = 0x00000001;
В подпрограмме обработки прерывания вставьте проверку регистра типа пре-
рывания, чтобы определить источник прерывания (инкремент или сигнал):
if(ILR & 0x00000001) // Инкремент
if(ILR & 0x00000002) // Сигнал
В обоих случаях необходимо перед выходом из прерывания сбросить флаг
прерывания:
ILR = 0x00000001; // Инкремент
ILR = 0x00000002; // Сигнал
Убедиться в корректности работы программы можно как при помощи платы
МСВ2100, так и с помощью симулятора. Помните, что симулятор работает не в
режиме реального времени, так что для получения действительной информации о
течении времени необходимо использовать счетчик Internal.Sec, который нахо-
214 дится в окне регистров.
Использование аппаратного JTAG-отладчика ULINK
Упражнение 20. UART
В этом упражнении мы сконфигурируем модуль UART1 для работы на скоро-
сти 9600 бод с данными следующего формата: 8 битов, 1 стоп-бит, контроль чет-
ности отсутствует. Для проверки работы модуля мы будем передавать символы,
полученные им из терминального окна симулятора.
Откройте проект, расположенный в папке «C:\work\ EX20-UART».
Сконфигурируйте модуль UART1 для передачи данных формата 8/N/1 со ско-
ростью 9600 бод, учитывая, что PCLK = 30 МГц (реальная скорость передачи будет
равна 9664):
U1LCR = 0x00000083;
U1DLL = 0х000000С2;
U1LCR = 0x00000003;
В функции getchar() и putchar() добавьте строки, в которых осуществляется
контроль регистра состояния линии:
а) для putchar()
while (!(U1LSR & 0x20));
б) для getchar()
while (!(U1LSR & 0x01));
Скомпилируйте программу и загрузите ее в отладчик.
Если вы работаете с платой МСВ2100, подключите разъем UART1 к последо-
вательному порту ПК и запустите программу «HyperTerminal». После запуска
программы вводите в окне HyperTerminal символы и убедитесь, что они отобража-
ются на экране.
Если вы используете симулятор, воспользуйтесь встроенным терминалом (ок-
но Serial Window #2).
Упражнение 21. Интерфейс I2C
В этом упражнении демонстрируется использование интерфейса I2C для за-
писи и чтения микросхем EEPROM с последовательным интерфейсом (полную
документацию на интерфейс I2C можно найти на компакт-диске). Поскольку на
отладочной плате МСВ2100 такая микросхема не установлена, для эмуляции ра-
боты EEPROM используется сценарий pVISION. Так что мы сможем протестиро-
вать наши подпрограммы обмена и подготовить их к использованию в реальном
устройстве.
Откройте проект, расположенный в папке «C:\work\ ЕХ21-12С».
Сценарий находится в файле «I2C.ini», так что добавьте его к проекту на
вкладке Debug окна задания опций для конечного устройства.
Скомпилируйте программу и запустите симулятор.
Откройте окно модуля I2C (меню Peripherals, пункт I2C Interface).
На вкладке I2C Hardware отображается конфигурация модуля, а на вкладке
I2C Communication отображаются все транзакции, осуществляемые на шине.
В нашей программе функция I2CtransferByte() инициирует транзакцию
на шине I2C, дальнейшая обработка которой осуществляется в прерывании. 2И5
Глава 5. Учебное пособие по средствам разработки компании Keil
Подпрограмма обработки прерывания представляет собой конечный автомат, ре-
ализованный с помощью оператора switch(). Поставив точку останова на этот
оператор, мы можем отслеживать активность на шине во время работы програм-
мы (Рис. 5.61).
092 L
093 void I2CISR (void) _____irq
оИЗ<
099
®09S switch (I2STAT)
097 {
098 // St .art and Send byte cond.
Puc. 5.61. Установка точки останова
на оператор switchQ
Транзакции, выполняемые на шине во время работы программы, будут иметь
следующий вид (Рис. 5.62):
Рис. 5.62. Вкладка I2C Communication
Память эмулируемой микросхемы EEPROM отображена на неиспользуемый
диапазон адресов процессора, а именно 0x00030000...ОхОООЗООЕЕ После запуска
программы можно посмотреть данные, записываемые в память и считываемые из
нее (Рис. 5.63).
[0x00030000: 01 02 03 04 90 00 00 00
[0x00030008: 00 00 00 00 00 00 00 00
[ОхОООЗООЮ: 00 00 00 00 00 00 00 00
[0x00030018: 00 00 00 00 00 00 00 00
|0х00030020: 00 00 00 00 00 00 00 00
[0x00030028: 00 00 00 00 00 00 00 00
[ОхОООЗООЗО: 00 00 00 00 00 00 00 00
I >[0x00030038: 00 00 00 00 00 00 00 00 . ;
I 1 п л п - n п ,пл clq □□□ ас аа аа—пл,,, -XJ i
Ii и| I klHhMemory»! Д Memory#2 A Memory#3 Д Memory#4 , 3
216
Рис. 5.63. Содержимое памяти
Использование аппаратного JTAG-отладчика ULINK
Упражнение 22. Интерфейс SPI
Интерфейс SPI в этом упражнении, как и интерфейс I2C в предыдущем, ис-
пользуется для связи с последовательной микросхемой EEPROM. В упражнении
демонстрируется выполнение операций чтения и записи с устройствами такого
типа. Поскольку на отладочной плате МСВ2100 такой микросхемы нет, для эму-
ляции работы EEPROM используется сценарий pVISION.
Откройте проект, расположенный в папке «C:\work\ EX22-SPI».
Сценарий находится в файле «SPI.ini», так что добавьте его к проекту на
вкладке Debug окна задания опций для конечного устройства. С помощью сцена-
рия память эмулируемой микросхемы EEPROM отображается на диапазон адре-
сов процессора 0x00700000.. .0x007000FF.
Допишите программу, находящуюся в файле «main.c».
Задайте режим работы и скорость передачи:
SOSPCCR = OxOOOOOOFF;
S0SPCR = ОхООООООАО;
Инициируйте обмен по шине SPI:
SPI_write(output_buffer,8);
Допишите код конечного автомата в подпрограмме обработки прерывания:
case (0x01): // Посылка команды записи
S0SPDR = 0x00000002;
status = 0x02; // Переходим к следующему состоянию
break;
Скомпилируйте программу и запустите симулятор.
Поставьте точку останова на оператор switch() в подпрограмме обработки пре-
рывания.
Запустите программу и наблюдайте состояние виртуальной микросхемы
EEPROM и отладочные сообщения в окне Output Window.
Упражнение 23. Аналого-цифровой преобразователь
В этом упражнении мы сконфигурируем модуль АЦП для выполнения в аппа-
ратном режиме 8-битного преобразования по 0-му каналу. Результат преобразова-
ния будет использоваться для управления группой светодиодов.
Откройте проект, расположенный в папке «C:\work\ EX23-AtoD».
Сконфигурируйте АЦП для работы в аппаратном режиме по 0-му каналу с
разрешением 8 бит. Задайте тактовую частоту модуля АЦП, учитывая, что
Pclk = 30 МГц:
ADCR = 0x00270601;
Добавьте проверку бита DONE регистра ADDR для обнаружения завершения
преобразования:
while ((val & 0x80000000) == 0);
Скомпилируйте программу и загрузите ее в отладчик.
217
Глава 5. Учебное пособие по средствам разработки компании Keil
Если вы работаете с демонстрационной платой, то при повороте движка пере-
менного резистора будет изменяться напряжение на входе 0-го аналогового канала.
Если же вы работаете с симулятором, то изменение внешнего напряжения
можно эмулировать с помощью окна управления периферийным устройством
(меню Peripherals, пункт A/D Converter), Рис. 5.64.
A/D Converter [X|
f A/D Control—-----------------------------------------
| ADCR: |0хЪТ27060Г SEC [ЬхбГ H)N
----------------------- .—.— p BURST
CLKS: |8clk/7bit _*j CLKDIV:|0x06 Г EDGE
I START: 3 Clock: [4285714’ ”
A/D Data.....----
ADDR: |0x00004C00
V3A: [З 3000'
CHN:[OxOO~
V/V3A: j ОхоТзО ~
Г DONE )
Г OVERUN j
Analog Inputs •
j AINO:|l 0000 AIN1:[OOOOO AIN2:(OOOOO’ AIN3:|o0000 i
Puc. 5.64. Окно периферийного устройства, АЦП
Кроме того, в проект включен файл сценария, позволяющий изменять напря-
жение на входе АЦП с помощью кнопок панели инструментария.
Упражнение 24. Цифро-аналоговый преобразователь
В этом упражнении модуль АЦП будет использоваться для оцифровки вход-
ного сигнала. Результат преобразования будет передаваться в модуль цифро-ана-
логового преобразователя. Если у вас есть генератор сигналов и осциллограф, то
можно будет сравнить входной и выходной сигналы. При работе с симулятором
для сравнения можно использовать логический анализатор.
Откройте проект, расположенный в папке «C:\work\ EX24-DtoA».
Вставьте в программу операцию пересылки результата АЦП в ЦАП.
Скомпилируйте программу и запустите отладчик.
Если вы работаете с платой МСВ2100, то подключите генератор сигналов к
входу АЦП, а осциллограф — к выходу ЦАП.
Запустите программу и сравните оба сигнала. Изменяя частоту входного сиг-
нала, определите частоту, начиная с которой сигналы станут различаться.
При использовании симулятора генерация входного сигнала обеспечивается
файлом сценария, а сравнение входного и выходного сигнала можно выполнить с
помощью логического анализатора.
Упражнение 25. Передача данных по интерфейсу CAN
В двух последних упражнениях мы рассмотрим работу с интерфейсом CAN.
Для образования работающей сети CAN нам требуется по меньшей мере два узла.
К счастью, микроконтроллер LPC2194 имеет два независимых контроллера CAN,
которые на демонстрационной плате подключены к разъемам типа D-SUB. Для
выполнения упражнений мы соединим эти два канала и будем пересылать дан-
21 8 ные из одного контроллера в другой.
Использование аппаратного JTAG-отладчика ULINK
Подключите к демонстрационной плате JTAG-отладчик и соедините 2-й
(CAN L) и 7-й (CAN H) контакты разъема РЗ с соответствующими контактами
разъема Р4.
Откройте проект, расположенный в папке «C:\work\ EX25-CANTX».
Вычислите параметры тактовой синхронизации для скорости передачи
125 Мбит/с при PCLK = 60 МГц.
Допишите программу в файле «main.c» следующим образом.
Сконфигурируйте регистр тактовой синхронизации:
C2BTR = OxOOlCOOlD;
Задайте код длины данных, равный 4-м байтам:
C2TFI1 = 0x00040000;
Разрешите передачу стандартных идентификаторов и установите значение
идентификатора передаваемого сообщения, равное 2:
C2TID1 = 0x00000002;
Скопируйте результат АЦП в первый байт буфера передачи:
C2TDA1 = val;
Поставьте сообщение в очередь передачи:
C2CMR = 0x00000021;
Теперь скомпилируйте программу и запустите отладчик.
Во время работы программы результат аналого-цифрового преобразования
будет передаваться модулем CAN2 и приниматься модулем CAN1. Получаемые
данные затем выводятся в порт для управления светодиодами.
При использовании симулятора виртуальное соединение двух контроллеров
осуществляется с помощью сценария, а процесс обмена данными по шине CAN
можно наблюдать в окне, вызываемом из меню Peripherals (пункт CAN, подпункт
Communication).
Упражнение 26. Прием данных по интерфейсу CAN
В этом упражнении используется та же программа, что и в предыдущем, одна-
ко на этот раз мы будем исследовать работу приемника.
Откройте проект, расположенный в папке «C:\work\ EX26-CANRX».
Добавьте в файл «main.c» строки, в которых выполняется конфигурирование
фильтра приема.
Объявите массив в памяти данных:
unsigned int StandardFilter[2] _at_ 0xE0038000;
Сконфигурируйте таблицу фильтра стандартных сообщений:
AFMR = 0x00000001;
StandardFilter[0] = 0x20012002;
StandardFilter[1] = 0x20032004;
SFF_sa = 0x00000000;
SFF_GRP_sa = 0x00000010;
219
Глава 5. Учебное пособие по средствам разработки компании Keil
Очистите буфер приема перед выходом из обработчика прерывания:
C1CMR = 0x00000004;
Скомпилируйте программу и запустите отладчик.
Выполняйте программу до окончания процесса инициализации контроллера
CAN. ; 5
Проверьте содержимое памяти фильтра сообщений (меню Peripherals, пункт
CAN, подпункт Acceptance Filter). В этом окне показано, какие сообщения могут
приниматься модулем CAN.
Запустите программу на выполнение и примите сообщение.
Убедитесь, что идентификатор сообщения соответствует заданному в фильтре.
Глава 6________________________
УЧЕБНОЕ ПОСОБИЕ
ПО СРЕДСТВАМ РАЗРАБОТКИ GNU
Основные положения
В этой главе рассматривается настройка проектов ^VISION для использова-
ния компилятора GNU. Разбираются упражнения в которых демонстриру-
ется использование нестандартных расширений языка Си, реализованных в ком-
пиляторе GNU. После выполнения этих упражнений вы можете вернуться к уп-
ражнениям основного учебного пособия, используя, однако, проекты-заготовки
из папки «GCC».
Стартовый код GCC
Стартовый код, используемый в проектах GNU, отличается от стартового ко-
да Keil, поскольку в ассемблерах разных пакетов используются различные дирек-
тивы и соглашения о присваивании имен. Тем не менее, он выполняет те же са-
мые операции. Таблицу векторов прерываний, как и прежде, должен редактиро-
вать программист. Конфигурирование стеков процессора и системных
периферийных устройств можно выполнить, как и в случае компилятора Keil, в
графическом виде с помощью специального редактора.
Взаимодействие кода ARM/THUMB
Компилятор GCC тоже поддерживает соглашение ARM о вызове подпро-
грамм и обеспечивает взаимодействие между наборами команд ARM и THUMB.
Однако, в отличие от компилятора Keil, в нем нельзя объявлять отдельные ARM-
или THUMB-функции. В компиляторе GCC функции, использующие набор ко-
манд ARM, и функции, использующие набор команд THUMB, должны быть
описаны в отдельных модулях. Эти модули компилируются при помощи соот-
ветствующих наборов команд, а затем объединяются вместе. Данный процесс
описывается в третьем упражнении настоящей главы.
221
Глава 6. Учебное пособие по средствам разработки GNU
Организация доступа
к периферийным устройствам
Оба компилятора используют одни и те же заголовочные файлы для обраще-
ния к регистрам специальных функций встроенных периферийных устройств.
Подпрограммы обработки
прерываний
Компилятор GCC поддерживает несколько нестандартных расширений язы-
ка Си, позволяющих объявлять функции в качестве подпрограмм обработки пре-
рываний. Общая форма такого объявления показана ниже.
void IRQ_Routine (void) _attribute_ ((interrupt{"IRQ")));
Для определения конкретного источника исключительной ситуации исполь-
зуются следующие ключевые слова:
FIQ, IRQ, SWI, UNDEF
Такая форма записи необходима только при объявлении прототипа функции
и не должна использоваться в основном теле функции. Подпрограмма обработки
прерывания рассматривается в 5-м упражнении.
Программное прерывание
Реальная поддержка программных прерываний в компиляторе GCC отсут-
ствует. Для генерации программного прерывания необходимо использовать
встроенный ассемблер:
#define Softwarelnterruppt2 asm ("swi #02")
При использовании этого макроопределения в код программы помещается ко-
манда SWI, в битах которой закодировано число 2. Далее, можно объявить указа-
тель на регистр ЦПУ с использованием очередного нестандартного расширения:
register unsigned *link_ptr asm ("rl4");
Такое объявление позволит прочитать содержимое регистра связи в подпро-
грамме обработки прерывания. При выполнении команды SWI ЦПУ переклю-
чится в режим Supervisor и перейдет по вектору SWI. В регистре связи будет со-
хранен адрес команды SWI, увеличенный на единицу. При входе в подпрограмму
обработки прерывания выполняется следующий оператор:
temp = *(link_ptr - 1) & OxOOFFFFFF;
Значение, сохраненное в регистре связи, «откатывается» назад на одну коман-
ду (на 4 байта, т.к. используется указатель на 32-битное целое), чтобы указать на
адрес команды SWI, сгенерировавшей исключительную ситуацию. Старшие 8 би-
222 тов ко да команды маскируются, и значения битов 0... 2 3 копируются в переменную
Встраиваемые функции
temp. В данном случае в переменную temp будет загружено число 2. Теперь можно
использовать оператор switch() для перехода к требуемому участку кода. Этот спо-
соб обработки программных прерываний демонстрируется в 6-м упражнении.
Встраиваемые функции
Встраиваемые функции в компиляторе GNU объявляются следующим образом;
inline int fast_function (char paraml);
Упражнение 1. Использование инструментальных средств
компании Keil совместно с компилятором GNU
Этот пример основан на программе, исходный текст которой можно найти в
папке «EXl-First Program\Work».
В нашем первом упражнении мы создадим свой первый проект, скомпилиру-
ем программу и загрузим ее в симулятор для отладки. После этого мы рассмотрим
основные функции отладки, предоставляемые симулятором Keil.
ИСР pVISION компании Keil поддерживает несколько различных компиля-
торов: компилятор GNU С, компилятор из пакета разработки компании ARM и
собственный компилятор Keil. Перед компиляцией убедитесь, что выбран ком-
пилятор GNU. Для этого активируйте окно рабочей области проекта Project
Workspace (вкладка Files), щелкните в нем правой кнопкой мыши и в появившем-
ся контекстном меню выберите пункт Manage Components. В появившемся окне
диалога перейдите к вкладке Folders/Extensions (Рис. 6.1) и убедитесь, что отмечен
флажок Use GNU Tools.
Рис. 6.1. Вкладка Folders/Extensions
223
Глава 6. Учебное пособие по средствам разработки GNU
iW|
Для запуска ИСР дважды щелкните на иконке программы pVISION ДИ .
Появится окно программы (Рис. 6.2).
Ц)ав £* View Project Qebug Flgsh Peripherals Tools £VCS Window Help
2 ы & «i и “73 м Я1 ®
& ДС ft
Project Workspace
g] Startup s
.......Bl «define _api_
02
03 «include vLPC210x.H^
04 «include "-ipi n"
05
06 void clock(void)
07 I
: JMSB' PLLCFG - 0x00000024;
H{)9 PLLCON ’ 0x00000001;
Г1В
! |Bl1 PLLFEED - OxOOOOOOAA.
i а|т2".PLLFEED = OxOOOOOOSS;
F13
i |Ц14 Vhile Г 1 (PLLSTAT s 0x00000400)1
Гл5 <
i И16 PLLFEED = OxOOOOOOAA;
Г 17 PLLFEED = Oxi'.li Ю0055;
ь
l9 1
20 PLLCON = 0x00000005;
21
Й22’ PLLFEED * OxOOOOOOAA,
; 23 PLLFEED = UMJUJLU05!:,
24
X'25 VPBDIV - O' iriijcorc;
.26 !
27
"3
0* fV 5)
rttfotetf CwUelfeHWft . 'Xi
Channel i Source
Watchdog
TvnerO
UARTO
UART1
PWM
I2C
SPIO
SPI1
"1 Name , j Type' ~[ Vector j IntEnablef Rawlritj
WDINT — ----------
RTC
External Interrupt О E
Selected Interrupt: Watchdog
Г HEnable Г IntSelect
Г Softlnt Г~ Rawlnt
13
PLOCK
EINTO
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
OOOOOOOOH
: VICVectAddr: [(£66666665 VldntSalectfSrOOOOOOOO"''' VICRawIntr: {5x6666io6o
VICSoWntJft565o66o6“" ViawEnable:{6x66o6aioo” VlDRQStatus: jOxOOOOOOOO”
< VlCSoftWCleac <0x00000000 VICIntEnCk: joxooobooob VICFIQStatus: |6xo6666o66
,ap
Address: f
0x00000000:
0x00000003:
0x00000006:
0x00000009:
OxOOOOOOOC:
OxOOOOOOOF:
0x00000012:
0x00000015:
0x00000018:
OxOOOOOOlB:
WMch# l A Watch #2 Д Cal Stack /
L:14G1 i MM i < iR/W
Puc. 6.2. Окно программы pVISION
Выберите в меню Project пункт New Project... (Рис. 6.3).
pVision3
File Edit View | Project | Debug Flash Peripherals Tools 5VC5 Window Help
'й aS Ы SL..........................................Z_..„..............................
Import pVision 1 Project...
Open Project
: Project Workspace
Рис. 6.3. Меню Project
В окне диалога (Рис. 6.4) укажите папку, в которой будет сохранен новый про-
ект. В строке File name введите имя проекта «first.uv2» и нажмите кнопку
Сохранить.
После этого появится окно выбора нового устройства (Рис. 6.5). Просмотрите
базу данных поддерживаемых устройств, выберите в папке «Philips» микроконт-
роллер LPC2129 и нажмите кнопку ОК.
224
Встраиваемые функции
Рис. 6.4. Ввод имени нового проекта
Select Device for Target 'Target Г
CPU |
Vendor: Philips
Device: LPC2129
Toolset: ARM
Description:
Database
□ LPC2114
О LPC2119
О LPC2124
□
Cl LPC2131
□ LPC2132
; □ LPC2138
: □ LPC2194
= £2 LPC2210
£3 LPC2212
: а LPC2214
: £3 LPC2290
ARM7TDMI-S based high-performance 32-bit RISC Microcontroller with TF
256KB on-chip Flash ROM with In-System Programming (ISP) and In-Appfir
16KB RAM, Vectored Interrupt Controller,
Two UARTs, I2C serial interface, 2 SPI serial interfaces
Two timers (7 capture/compare channels),
PWM unit with up to 6 PWM outputs,
4-channels 10bit ADC, 2 CAN channels.
Real Time Clock, Watchdog Timer, General purpose I/O pins.
CPU clock up to 60 MHz, On-chip crystal oscillator and On-chip PLL
OK I Отмена I Справка
Puc. 6.5. Окно выбора нового устройства
В браузере проекта выделите корневой узел «Target 1» и вызовите контекстное
меню, нажав правую кнопку мыши. В этом меню выберите пункт Options for
Target (Рис. 6.6).
На вкладке Target задайте частоту симуляции, равную 12.000 МГц (Рис. 6.7).
На вкладке Linker (Рис. 6.8) в поле Linker Script File выберите файл «Flash.ld» и
установите флажки Enable Garbage Collection и Do not use Standard System Startup
Files. 225
Глава 6. Учебное пособие по средствам разработки GNU
Рис. 6.6. Контекстное меню корневого узла «Target 1»
Замечание. Если вы хотите, чтобы ваша программа запускалась из встроенно
го ОЗУ микроконтроллера, используйте файл компоновщика «RAM.Id» и скон
фигурируйте поле Text Start.
226
Встраиваемые функции
Options for Target ’Target Г
Device| Target] Output) Listing| CC | Assembler Linker | Debug] Utilities |
Text Start: |
P Enable Garbage Collection ---------------------------
P Do not use Standard System Startup Files Data Start. ___________________________
Г~ Do not use Standard System Libraries BSS Start: |
Г Use Math Libraries
OK | Отмена J Defaults | Справка
Puc. 6.8. Вкладка Linker
На вкладке Debug (Рис. 6.9) удостоверьтесь, что включен переключатель Use
Simulator, а также установлены флажки Load Application at Startup и Go till main().
Options for Target-Target Г |X|
Device] Target| Output| Listing] CC
<• Use Simulator
P Load Application at Startup P Go till mainQ
Initialization File:
| Assembler | Linker Debug | Utilities |
Settings I
~ Restore Debug Session Settings...--
P Breakpoints P Toolbox
P Watchpoints & PA
P Memory Display
CPU DLL: Parameter:
|sARm7dLL |-сГрС21 00
r Use: | ULIN К ARM Debugger 3 Settin9s |
P Load Application at Startup Г" Go tillmainf}
Initialization File:
Restore Debug Session Settings---------------------
j P Breakpoints p Toolbox
Г“ Watchpoints
P Memory Display
Driver DLL: Parameter:
[SARM?DГ“|
Dialog DLL: Parameter:
jDARMRDLL ppLPC21x9
Dialog DLL: Parameter:
[tARMP'dLL I pLPC21x9
OK | Отмена I Defaults
Справка
Puc. 6.9. Вкладка Debug
227
Глава 6. Учебное пособие по средствам разработки GNU
Чтобы завершить установку параметров проекта, нажмите кнопку ОК.
В браузере проекта разверните узел «Target 1», появится папка «Source
Group 1» (Рис. 6.10).
4 LU л ^|largetl
Project Workspace x
d £3 Target 1_______
0
Source Group 1
Puc. 6.10. Папка «Source Group 1»
Выделите эту папку, нажатием правой кнопки мыши вызовите контекстное
меню и выберите пункт Add Files to Group ‘Source Group 1’ (Рис. 6.11).
Puc. 6.11. Контекстное меню папки «Source Group 1»
В диалоговом окне (Рис. 6.12) добавьте файлы «blinky.c» и «seriate».
Смените фильтр Files of type на «ASM Source file» и добавьте файл «startup.s».
Это все исходные файлы, необходимые для проекта, так что нажмите кнопку
Close.
Исходный код, содержащийся в файле, можно просмотреть, сделав двойной
щелчок на имени файла в браузере проекта.
228
Встраиваемые функции
Add Files to Group 'Source Group 1'
Папка: j^Work
00 Blinky.c
0 Serial.c
Имя Файла: |[
Tип Файлов: |c Source file Г~с)
Puc. 6.12. Добавление файлов «blinky.c» и «seriate»
После добавления в проект всех исходных файлов его можно собрать либо из
меню, либо нажав соответствующую кнопку на панели инструментов (Рис. 6.13).
Запуск отладчика
Сборка проекта
: ЕНе Щей &oject Qebug ГШ Peripherals tools §VCS window beip
3# * & • $ gg & г в ийи * t
Puc. 6.13. Панель инструментов
После того как программа будет скомпилирована, вы можете запустить симуля-
тор, нажав кнопку запуска отладчика. Использование симулятора и JTAG-отладчи-
ка подробно рассмотрено в предыдущей главе при разборе первого упражнения.
Упражнение 2. Стартовый код
В этом упражнении мы сконфигурируем стартовый модуль компилятора, а
именно, зададим конфигурацию стеков всех рабочих режимов ЦПУ ARM7. От-
кройте проект, расположенный в папке «EX2-StartupCode\Work».
Откройте файл «Startup.s» и, используя графический редактор, задайте следу-
ющую конфигурацию стеков для различных режимов работы ЦПУ (Рис. 6.14):
В Stack Conf iguration
Top of Stack Address
E Stack Sizes (in Bytes)
i Undefined Mode
j Supervisor Mode
: Abort Mode
: Fast Interrupt Mode
:••• Interrupt Mode
User/System Mode
[+] PLL Setup
0x4000 4000
0x0000 0080
0x0000 0080
0x0000 0080
0x0000 0080
0x0000 0080
0x0000 0400
F
Puc. 6.14. Задание конфигурации стеков
229
Глава 6. Учебное пособие по средствам разработки GNU
Скомпилируйте программу.
Запустите симулятор и, когда PC дойдет до функции main(), просмотрите со-
держимое каждого регистра R13 (Рис. 6.15).
Register
® Current
Jba-
□ User/System
R8 0x00000000
R9 0x00000000
: R10 0x40003980
< R11 0x00000000
i R12 0x00000000
' R13(SP) 0x40003d80
R14 (LR) 0x00000000
Fast Interrupt
:•••• R8 0x00000000
г R9 0x00000000
i R10 0x00000000
R11 0x00000000
5 R12 0x00000000
- R13(SP) 0x40003f00
г R14 (LR) 0x00000000
S SPSR 0x00000000
Interrupt
R13(SP) 0x40003e80
; R14(LR) 0x00000000
Й SPSR 0x00000000
Supervisor
R13(SP) 0x40003e00
R14(LR) 0x00000000
S SPSR 0x00000000
Abort
• R13(SP) 0x40003f80
R14(LR) 0x00000000
S SPSR 0x00000000
Undefined
: R13(SP) 0x40004000
: R14(LR) 0x00000000
В SPSR 0x00000000
Internal
= PC $ 0x0000018C
; Mode User
' States 133
Sec 000000435
Область стеков размещается, начиная
с верхней границы встроенной памяти.
Размер каждого стека,
кроме стека режима User, равен 0x80 байт.
Стек режима User имеет размер 0x400 байт,
поэтому пользовательские данные
будут размещаться, начиная с адреса
(0x40003680 - 0x400)
________________________________________у
Рис. 6.15
Упражнение 3. Использование кода THUMB
В этом упражнении мы создадим простейшую программу, в которой из основ-
ной функции, скомпилированной с использованием 32-битных команд ARM,
вызывается 16-битная THUMB-функция.
Откройте проект, расположенный в папке «\ЕХЗ-Thumb Code\Work».
В браузере проекта выделите файл «thumb.c» и выберите в контекстном меню,
вызываемом по щелчку правой кнопки мыши, пункт Options for File ‘thumb.c’
(Рис. 6.16).
На вкладке СС появившегося диалогового окна (Рис. 6.17) введите в поле
Misc Control ключ -mthumb или отметьте флажок Compile Thumb Mode, после чего
нажмите кнопку ОК.
Теперь выделите в браузере проекта корневую папку «FLASH» и в контекст-
ном меню выберите пункт Options for Target ‘Flash’.
На вкладке СС появившегося диалогового окна (Рис. 6.18) установите флаж-
230 ки Enable APCS и Support Calls Between ARM and THUMB.
Встраиваемые функции
j Ptojed Workspace____
| H Bal Flash
S g Source Group 1
® SSS23B
i S Щ main.c i
i в startup‘ E
23
24
25
#include <LPC21XX.H>
Options for File 'thumb.c'
A
Open thumb.c
Rebuild target
Build target F7
Translate C:\Work\ARM\Philips\GCC Examples\EX3-Thumb Code\Work\thumb.c
:lay++)
Manage Components
Remove File 'thumb.c'
[V] Include Dependencies
Puc. 6.16. Выбор пункта Options for File ‘thumb.c’ в контекстном меню
Options for File ‘thumb.c* |X|
Properties CC |
r~ Preprocessor Symbols
| Define: |
I Undefine: |
- Code Generation
'П
P Enable APCS (ARM Procedure Call Standard)
P Generate Stack Check Code j
P Support Calls between ARM and THUMB Instruction Set \
Optimization: |< default
Warnings: |< default
Г Strict ANSI C
P Compile Thumb Code
Include Г~ : “
Paths ’
Misc | ‘
Controls I
Compiler |.c -mcpu=arm7tdmi -mthumb-gdwarf 2 -MD -w -0 -mapcs-frame -mthumb-interwork
control -IC:\KeihARMMNC\Philips\ -o thumb.o
string I
Отмена | Defaults |
Справка
Puc. 6.17. Вкладка CC
231
Глава 6. Учебное пособие по средствам разработки GNU
Options for Target ’Flash’
Device} Target} Output} Listing CC } Assembler} Linker} Debug} Utilities}
r Preprocessor Symbols---------------------------------------
Define:
Undefine: |.... ...........................
r Code Generation-------——‘---------!---------;--------------
p Enable APCS (ARM Procedure Call Standard)
Г* Generate Stack Check Code
P Support Calls between ARM and THUMB Instruction Set
Optimization: [<defauit> 3
Warnings: |N^Warning^
Г Strict ANSI C
Г" Compile Thumb Code
Include Г
Paths ’
Misc Г
Controls '
1*1
Compiler l-c -mcpu=arm7tdmi -gdwarf-2 -MD -w 0 -mapcs-frame -mthumb-interwork -IC:\KeilSARM\INC\Philips\
control to ’.o
sbing |
OK | Отмена I Defaults I Справка
Puc. 6.18. Установка флажков на вкладке СС
Скомпилируйте программу и загрузите ее в отладчик.
Откройте окно дизассемблера и начните выполнять программу в пошаговом
режиме, используя клавишу Fl 1.
Проследите за переключением с 32-битного кода на 16-битный и обратите
внимание на флаг THUMB регистра CPSR (Рис. 6.19).
® SPSR 0x00000000
|0х00000194 Е584501С STR
36
10x00000198
|0х0000019С
lOxOOOOOlAO
|0х000001А4
10х000001А8
lOxOOOOOlAC
|0х000001В0
|0х000001В4
?0х000001В8
jOxOOOOOlBC
iOxOOOOOlCO
|0х000001С4
|0х000001С8
|0х000001СС
|0x000001D0
|Ox000001D4
thumb_f unction ()
_ _ -------- BL
В
LDR
BX
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
ANDEQ
EB000000
EAFFFFFC
E59FC000
E12FFF1C
00000139
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
R5,[R4,#0x001C]
OxOOOOOlAO
0x00000194
R12,[PC]
R12
R0,R0,R9,LSR R1
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0, R0,R0
R0,R0,R0
R0, R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
R0,R0,R0
Puc. 6.19
Сначала процессор работает в 32-битном режиме ARM, флаг Т сброшен, а
размер слова команды равен 4 байтам. Затем вызывается THUMB-функция, в ре-
зультате чего выполняется команда ВХ, переключающая процессор в 16-битный
режим THUMB. При этом устанавливается флаг THUMB, а при входе в THUMB-
232 функцию для сохранения регистров в стеке используется команда PUSH.
Встраиваемые функции
Упражнение 4. Использование библиотек GNU
В этом упражнении мы доработаем функцию printf(), чтобы она смогла рабо-
тать с модулем UART микроконтроллеров LPC2100. В дальнейшем мы рассмот-
рим регистры модуля UART более подробно.
Откройте проект, расположенный в папке «EX4-Printf\Work».
В файл «main.c» добавьте строки, выполняющие вывод сообщения с исполь-
зованием функции printf():
while(1)
{
printf("Здесь Ваше сообшение \п"); // Вызываем функцию printf()
}
Добавьте файл «syscalls.c» в рабочую папку проекта (Рис. 6.20).
-1 £3 Flash
Я Q Source Group 1
'+] Щ main.c
[+i- [S| serial.с
S| Startup.s
Я [£| Syscalls.c
Puc. 6.20
В файле «syscalls.c» допишите функцию write() следующим образом.
Допишите оператор for(), чтобы длина цикла была равна длине выводимой
строки (1еп).
Внутри цикла добавьте вызов функции putchar() для записи одиночного сим-
вола в канал stdio (putchar(*ptr*)).
Инкрементируйте указатель на строку символов (ptr++):
int write (int file, char * ptr, int len)
{
int i ;
for (i = 0; i < len; i++) putchar (*ptr++);
return len;
9
}
Скомпилируйте программу и загрузите ее в отладочную плату.
Запустите программу и посмотрите на результат ее работы в окне терминаль-
ной программы.
Если вы используете симулятор, выберите в меню View пункт Serial Window #1.
В результате в симуляторе откроется окно терминала, отображающее данные с
выхода модуля UART0.
Упражнение 5. Простое прерывание
В этом упражнении мы сконфигурируем простейшее прерывание FIQ и по-
смотрим, как оно обрабатывается.
Откройте проект, расположенный в папке «EX5-Interrupt\Work». 233
Глава 6. Учебное пособие по средствам разработки GNU
В файле «main.c» допишите объявление прототипа функции EXTintFIQO,
чтобы она была объявлена как подпрограмма обработки прерывания FIQ:
void EXTintFIQ (void) _attribute_ ((interrupt("FIQ")));
В файле «startup.s» допишите таблицу констант векторов прерываний, чтобы
функция EXTintFIQO вызывалась в качестве подпрограммы обработки прерыва-
ния FIQ:
-Startup: .global .global . func EXTintFIQ -Startup -Startup // Имя Си-подпрограммы объявляется как // глобальное
Vectors: LDR LDR LDR PC, Reset_Addr PC, Undef_Addr PC, SWI_Addr
Reset_Addr: Undef_Addr: LDR PC, PAbt_Addr // Таблица векторов LDR PC, DAbt.Addr .long 0xB8A06F58 LDR PC, [PC, #-0xFF0] LDR PC, FIQ.Addr .word Reset—Handler .word Undef_Handler
SWI_Addr: PAbt_Addr: DAbt_Addr: IRQ_Addr: FIQ_Addr: .word .word .word .word .word .word SWI_Handler PAbt_Handler DAbt_Handler 0 IRQ_Handler EXTintFIQ // Таблица констант
Добавьте имя подпрограммы обработки прерывания в таблицу констант.
Скомпилируйте программу и загрузите ее в микроконтроллер на отладочной
плате.
Выполняйте программу в пошаговом режиме до цикла while() и наблюдайте за
ее выполнением с помощью окна дизассемблера и окна регистров.
Установите точку останова на функцию EXTintFIQO.
Нажмите F5 для запуска программы.
Нажмите кнопку INT1 на плате МСВ2100, чтобы генерировать прерывание.
Если вы хотите посмотреть механизмы входа в режим обработки исклю-
чительной ситуации и выхода из него, лучше всего использовать симулятор и
выполнять программу по шагам в окне дизассемблера. В этом случае вы смо-
жете понаблюдать за ходом выполнения программы и изменением регистров
ЦПУ.
Чтобы управлять прерыванием в симуляторе, откройте окно управления ну-
левым портом ввода/вывода (меню Peripherals, пункт GPIO/Port 0). Вывод Р0.14
установлен стартовым сценарием в файле «map.ini». Если вы продолжите выпол-
нение программы, сняв отметку с ячейки, соответствующей выводу Р0.14, то
234
Встраиваемые функции
будет сгенерировано прерывание. Для прекращения генерации прерывания ячей-
ку необходимо отметить (Рис. 6.21).
General Purpose Input/Output О (GPIO 0) | X |
_______—............. 31 Bits 24 23 Bits 16 15 Bits 8 7 Bits 0
IOOIRO: [frxoooooooo ГТТТТТТГ ГТТТТГГГ ГТТТГГГГ ГТТТТТТГ
iosETa|oxoooooodo~ ГГГГГТТГ гтгттттг гггггггг гггггггг-
IOCLRO: [ОхОООООООС ггттгггг гтгггггг I......................Г" i.n..I.IT ГТТТТТТТ
IQPINO: [0x00004000~ ГТТТТТТТ ГТТТТТТТ ГТТТТТТГ гттттттт
Pins:|0x00004000 птг ГТ ГТТТТТТТ ГТТТТТТГ гттттттт
Рис, 6,21. Окно управления нулевым портом ввода/вывода
В качестве альтернативы в инструментарии (вызывается кнопкой, показан-
ной на Рис. 6.22) имеется специальная кнопка Generate EINT 1 (Рис. 6.23). Нажа-
тие на эту кнопку симулирует появление импульса на выводе прерывания.
Рис, 6.22. Кнопка
инструментария
Рис, 6,23, Панель инструментария с кнопками,
которые вызывают сценарии, конфигурируемые
пользователем
В pVISION есть свой развитой язык сценариев, использование которого поз-
волит вам симулировать внешние события. Этот язык основан на синтаксисе
языка Си, а программы на нем хранятся в виде текстовых файлов. Сценарий, ис-
пользуемый для симуляции одиночного импульса, приведен ниже.
signal void Toggle(void)
{
PORTO = (PORTO A 0x4000);
twatch (200);
PORTO = (PORTO A 0x4000);
KILL BUTTON *
DEFINE BUTTON "Generate EINT 1","Toggle()"
Этот сценарий находится в файле «signal.ini», который добавляется в проект
на вкладке Debug окна задания опций для конечного устройства. Подробнее о
языке сценариев можно узнать из документации на pVISION.
Упражнение 6. Программное прерывание
В этом упражнении мы определим встраиваемую ассемблерную функцию
для вызова программного прерывания и поместим в команду вызова число 0x02.
В подпрограмме обработки программного прерывания мы декодируем эту ко-
манду, чтобы определить номер вызванной функции программного прерыва-
Глава 6. Учебное пособие по средствам разработки GNU
ния, а затем используем оператор switch() для перехода к соответствующей сек-
ции обработчика.
Откройте проект, расположенный в папке «EX6-SWI\Work».
Допишите программу в файле «main.c» следующим образом.
Добавьте макроопределение, вызывающее ассемблерную команду SWI:
#define Softwarelnterrupt2 asm (" swi #02")
В подпрограмме обработки прерывания завершите определение регистра, ис-
пользуемое для обращения к регистру R14:
register unsigned * link_ptr asm ("rl4");
Допишите оператор присваивания порядкового номера прерывания перемен-
ной temp:
temp = *(link_ptr-l) & OxOOFFFFFF;
Скомпилируйте и загрузите код в отладчик.
Выполняйте программу в пошаговом режиме и наблюдайте за обработкой
программного прерывания.
В окне дизассемблера можно увидеть, что в теле первой команды SWI по адре-
су 0x0000015С было закодировано число 1:
42: SoftwareInterrupt 1;
0x00000150 EFOOOOOl SWI 0x00000001
При входе в подпрограмму обработки прерывания регистр связи режима
Supervisor содержит число 0x00000160:
R14(LR) 0x00000160
Значение переменной temp вычисляется из выражения temp = *(link_ptr-l) &
OxOOFFFFFF. Число в скобках будет равно 0x160-4 (не забывайте, используется
указатель на 4-байтное целое), или 0х15С. Это адрес команды, сгенерировавшей
прерывание. Замаскировав 8 старших битов кода этой команды, получим число 1,
которое затем используется в операторе switch() для выполнения соответствую-
щей части кода.
Приложение
Список литературы
ARM7 TDMI datasheet ARM
LPC2119/2129/2194/2292/2294 User Manual Philips
LPC214x User Manual Philips
ARM System on chip architecture Steve Furber
ARM Architecture Reference Manual David Seal
ARM System developers guide Andrew N. Sloss
Domonic Symes
Chris Wright
MicroC/OS-II Jean J. Labrosse
GCC The complete reference Arthur Griffith
USB Complete Jan Axelson
Universal Serial Bus system Architecture Don Anderson
Ссылки
http ://www. arm. com
http://www.philips.com
http://www.lpc2000.com
http: //www. usb.org
http: //www. Ivr. com
Инструментальные средства и ПО
http: //www. hi t ex. с о. uk
http: //www. ke il. с о. uk
http://www.ucos-ii.com
http: //www. ristancase. com
http://gcc.gnu.org/onlinedocs/gcc
http ://thesycon. de
Оценочные платы и модули
http://www.phytec.co.uk
http://www.embeddedartists.com
237
Материалы,
размещенные на компакт-диске
На прилагаемом к книге компакт-диске содержатся оригинальные материалы
на английском языке.
После запуска компакт-диска открывается окно главного меню, откуда мож-
но установить GNU-компилятор компании Keil, среду разработки pVision для
ARM компании Keil и программу Acrobat Reader, а также перейти в любой из сле-
дующих разделов:
• Дополнительные материалы к курсу
• Инструментальные средства
• Упражнения
• Внутрисхемное программирование (ISP)
• Информация по плате МСВ2100
• Руководства и справочные материалы
• Операционная система СМХ
В разделе Дополнительные материалы к курсу представлены блок-схемы мик-
роконтроллеров семейства LPC900 и LPC2xxx, а также описание двоичного ин-
терфейса (ABI) для архитектуры ARM. Раздел Инструментальные средства содер-
жит ИСР «Development Assistant for С», среду отладки HiTOP, информационные ма-
териалы по программному обеспечению Tessy «Автоматическое, динамическое
тестирование компонентов встраиваемого ПО» и руководство для первоначаль-
ного ознакомления с компилятором Keil. На компакт-диске имеется исходный
код для всех упражнений как в версии для компилятора Keil, так и в версии для
компилятора GCC. Тексты для всех упражнений курса находятся в папке
«exercise». Из раздела Внутрисхемное программирование (ISP) можно установить
утилиту для внутрисхемного программирования LPC2000. В разделе Информация
по плате МСВ2100 содержится документация по высокоскоростному CAN-тран-
сиверу (High speed CAN transceiver Data Sheet), сдвоенному трансиверу EIA/TIA-562
компании Maxim (MAXIM EIA/TIA-562 Dual Transceiver), LDO-стабилизаторам
положительного напряжения с фиксированными и регулируемыми выходами
(Low drop fixed and adjustable positive voltage regulators), а также руководство пользо-
вателя для платы МСВ2100 (МСВ2100 User's Guide) и принципиальная схема
МСВ2100. В разделе Руководства и справочные материалы имеются параметричес-
кие таблицы по микроконтроллерам Philips, справочное руководство по ядру
ARM7 TDMI (ARM7 TDMI Technical Reference Manual), описание наборов команд
ARM (ARMinstruction set) и Thumb (Thumb instruction set), спецификация шины I2C
(The I2C-BUS Specification V2.1), руководство по эксплуатации LPC2104/2105/2106
(LPC2104/2105/2106 Product Data), руководства пользователя и спецификации
(data sheet) по микроконтроллерам семейства LPC2000, справочное руководство
по векторному контроллеру прерываний VIC (PrimeCell Vectored Interrupt Control-
ler Technical Reference Manual), демонстрационные программы USB HID и USB
Memory для LPC2148, а также другие справочные материалы. Раздел Операцион-
ная система СМХ содержит руководство, файл помощи и демонстрационную про-
грамму для версии 5.3.
238
Мартин Тревор
Микроконтроллеры ARM7. Семейство LPC2000 компании Philips.
Вводный курс
Переводчик А. В. Евстифеев
Ответственный редактор Т. Е. Брод
Технический редактор В. И. Матвеева
График Л. Н. Клочков
Корректор А. К. Федорова
Подписано в печать 28.12.2005. Формат 70x100/16. Бумага офсетная.
Гарнитура «NevtonC». Печать офсетная.
Объем 15,0 п. л. Усл. печ. л. 19,5. Тираж 5000 экз. Изд. № 101. Заказ №1.
Издательский дом «Додэка-ХХ1»
ОКП 95 3000
105318 Москва, а/я 70
Тел./факс: (095) 366-24-29, 366-09-22
E-mail: books@dodeca.ru; red@dodeca.ru
Отпечатано с готовых диапозитивов в ОАО «Типография Новости».
105005 Москва, ул. Ф. Энгельса, 46
Издательский дом «Додэка-XXI»
выпускает техническую литературу с 1992 г. В пер-
вую очередь это книги по электронной и компьютер-
ной тематике. Кроме этого, мы осуществляем пере-
ОАЭКА вод и издание зарубежных книг, каталогов, справоч-
ников и журналов. Расширяя поле деятельности,
издательство «Додэка»
ПРИГЛАШАЕТ К СОТРУДНИЧЕСТВУ
авторов, переводчиков и редакторов, разбирающихся в радиоэлект-
ронной и компьютерной тематике. Возраст и пол значения не имеют. Ос-
новное условие — желание работать. Приглашаются все заинтересован-
ные лица: с готовой книгой, с наполовину готовой книгой, с голой идеей
или без таковой.
Возможны разные варианты сотрудничества: от постоянной работы
до выполнения разовых заданий редакции.
За дополнительной информацией обращайтесь:
• по тел. (495) 366-09-22, 366-81-45 к Халикееву Вадиму Маратовичу,
• по E-mail: vadim@dodeca.ru
red@dodeca.ru.
КНИГИ ИЗДАТЕЛЬСТВА МОЖНО ЗАКАЗАТЬ ИЛИ КУПИТЬ:
• в издательстве
по адресу: 105318, г. Москва, ул. Щербаковская, 53
по тел./факсу: (495) 366-81-45, 366-24-29, 366-09-22
• на сайте: www.dodeca.ru
• по E-mail: books@dodeca.ru
• по почте: 105318, Москва а/я 70
Мы предлагаем вам приобрести наши книги на эксклюзивных условиях:
• Самые низкие розничные цены
• Скидки:
от 500 до 1000 рублей — скидка 5%
от 1000 до 3000 рублей — скидка 10%
от 3000 до 5000 рублей — скидка 15%
более 5000 рублей — скидка 20 %
начисление скидок производится от розничного прайс-листа.
• Уцененные книги
ПОКУПАЯ КНИГИ У НАС, ВЫ МОЖЕТЕ СТАТЬ НАШИМИ ПОДПИСЧИКАМИ
Для подписчиков действуют накопительные скидки, при которых
суммы всех покупок складываются и скидка постоянно растет.
Кроме того, подписчики регулярно получают информацию о наших
новинках открытками или по электронной почте.
Чтобы стать подписчиком, вам надо сообщить фамилию, имя, отчест-
во, почтовый адрес и электронный адрес (если он у вас есть).
Если вы уже являетесь нашим подписчиком, то сразу получаете скид-
ку 10% независимо от суммы покупки.
Семейство LPC2000
Модель Память Интерфейсы АЦП (10b) Порты ввода/ вывода Корпус
Flash RAM UART PC SPI CAN USB # of ch
LPC2I04 I28K I6K 2 I I - - - 32 LQFP48
LPC2I05 I28k 32K 2 I I - - - 32 LQFP48
LPC2I06 I28K 64K 2 I I - - - 32 LQFP48
LPC2II4 I28K I6K 2 I 2 - - 4 46 LQFP64
LPC2II9 I28K I6K 2 I 2 2 - 4 46 HVQFN64 LQFP64
LPC2I24 256К I6K 2 I 2 - - 4 46 LQFP64
LPC2I29 256К I6K 2 I 2 2 - 4 46 LQFP64
LPC2I3I 32К 8K 2 2 2 - - 8 47 LQFP64
LPC2I32 64К I6K 2 2 2 - - 8 + DAC 47 HVQFN64 LQFP64
LPC2I34 I28K I6K 2 2 2 - - 8 + DAC 47 LQFP64
LPC2I36 256К 32K 2 2 2 - - 16 +DAC 47 LQFP64
LPC2I38 5I2K 32K 2 2 2 - - 16 +DAC 47 HVQFN64 LQFP64
LPC2I4I 32К 8K 2 2 2 - Y 8 46 LQFP64
LPC2I42 64К I6K 2 2 2 - Y 8 +DAC 46 LQFP64
LPC2I44 I28K I6K 2 2 2 - Y 8 + DAC 46 LQFP64
LPC2I46 256К 32K 2 2 2 - Y 16 + DAC 46 LQFP64
LPC2I48 5I2K 32K 2 2 2 - Y 16 + DAC 46 LQFP64
LPC2I94 256К I6K 2 I 2 4 - 4 46 LQFP64
LPC22I0 Ext. I6K 2 I 2 - - 8 76 LQFPI44
LPC22I2 I28K I6K 2 I 2 - - 8 112 LQFPI44
LPC22I4 256К I6K 2 I 2 - - 8 112 LQFPI44
LPC2220 Ext. 64K 2 I 2 - - 8 112 TFBGAI44 LQFP64
LPC2290 Ext. I6K 2 I 2 - - 8 112 TFBGAI44 LQFP64
LPC2292 256K I6K 2 I 2 2 - 8 112 LQFPI44
LPC2294 256K I6K 2 I 2 4 - 8 112 LQFPI44
©Koninklijke Philips N.V., 2005. Все права защищены.
Большие возможности
в маленьком корпусе
16/32-битные флэш-микроконтрол леры
Семейство флэш-микроконтроллеров Philips LPC2000 с 16/32-битным
ядром ARM7TDMI-S™ поможет реализовать Ваши решения:
Самая высокая скорость работы с встроенной флэш-памятью
- До 512 Кбайт флэш-памяти на кристалле
- Исполнение кода из Flash или RAM на 60 МГц,
без динамической загрузки
- JTAG-интерфейс, ISP- и IAP-программирование через
последовательные порты
Сверхнизкое потребление на тактовой частоте до 75 МГц
- Потребляемая мощность 1 мВт/МГц
USB 2.0 Full-speed device
- Возможность подключения до 32 устройств
- 2 буфера х 1 Кбайт
- Гибкость работы с DMA
Широкий диапазон встроенных периферийных устройств
USB, UART, l2C, CAN и SPI
PHILIPS
разумно и просто
Посетите сайт www.philips.com/LPC2000