Академический Документы
Профессиональный Документы
Культура Документы
Кочуров
ПРОГРАММИРОВАНИЕ ВСТРАИВАЕМЫХ
СИСТЕМ НА ОСНОВЕ МИКРОКОНТРОЛЛЕРОВ
LPC214X
Учебное пособие
Министерство образования и науки РФ
Учебное пособие
О. М. Кочуров
Владимир 2011
УДК 004.31
УДК 004.031.6
ББК 32.973–04
К75
3
Предисловие
Настоящее учебное пособие предназначено для изучения архитектуры
и основных приемов программирования встраиваемых однокристальных
микроконтроллеров серии LPC214x фирмы NXP. Материал изложен в трех
частях.
Первая часть преимущественно содержит материал справочного ха-
рактера — описание архитектуры и аппаратных средств микроконтроллера.
Предложенное описание, затрагивая важнейшие узлы LPC2148, не является
полным. Некоторые из аппаратных средств не рассмотрены. Изучив материал
настоящего учебного пособия читатель без труда дополнит свои знания с по-
мощью известных книг [1, 2] а также официальной документации компаний
ARM и NXP, ссылки на которые приведены в приложении.
Отметим, что первая часть не повторяет перевода официальной до-
кументации, а представляет собой авторское изложение материала. Каждый
раздел начинается с краткого описания основных возможностей одного из
узлов микроконтроллера, после чего следует основная справочная часть. В
конце разделов приводятся методические указания по настройке рассмотрен-
ных узлов и управлению ими.
Вторая часть посвящена программным и аппаратным средствам, кото-
рые необходимы для разработки программ. Здесь читатель найдет основы
представления числовой информации в памяти вычислительных устройств, а
также экскурс в программирование на языке Си. Привнести что-либо новое в
описание самого распространенного языка программирования трудно, кроме
краткости. Поэтому авторы касаются лишь наиболее важных вопросов, без
знания которых невозможна разработка ни одной программы. Авторы стре-
мились не обойти вниманием некоторые приемы программирования и кон-
струкции, которые часто возникают при программировании микроконтрол-
леров и редко в практике программирования для персональных ЭВМ. Для
углубленного изучения языка рекомендуем иметь под рукой один из извест-
ных учебников [3, 4]. Значительное внимание уделено описанию популярной
среды программирования Keil µVision 4. Авторы предложили методику от-
ладки программ.
Третья часть представляет собой методические указания по решению
практических задач. В каждом разделе дано описание алгоритмического ре-
шения очередной элементарной задачи. Аппаратной основой авторам послу-
жили учебные платы EA-EDU-001 и EA-EDU-011 фирмы Embedded Artists.
Схемотехнические узлы этих плат вполне могут считаться классическими и
легко заимствуются с помощью принципиальных схем, приведенных в при-
ложении. Тематика практических занятий охватывает весьма широкий круг
задач, возникающих в практике разработки микропроцессорных средств, та-
ких как ввод-вывод аналоговых и цифровых сигналов, опрос аналоговых,
дискретных и цифровых датчиков, индикация, обмен данными с другими
компонентами микропроцессорной системы и персональным компьютером.
4
Авторы стремились создать подборку наиболее типичных приемов
микропроцессорного управления, освоив которые читатель приобретет до-
статочные навыки для решения практических задач. Впрочем, следует заме-
тить, что основную трудность представляет собой продуманная организация
взаимодействия отдельных подпрограмм в рамках большой программы. Для
этого требуется представлять общий алгоритм программы на основе техни-
ческого задания. Такие навыки приобретаются с опытом.
Текст учебного пособия сопровождается наглядными схемами, диа-
граммами, а также осциллограммами реальных процессов, протекающих в
микропроцессорной системе, полученными с помощью цифрового осцилло-
графа.
Авторы рассчитывают, что настоящее учебное пособие послужит не
только студентам, изучающим микропроцессорную технику, и радиолюбите-
лям, но и инженерам со стажем.
5
Введение
Исторически первый четырехразрядный микропроцессор был разра-
ботан фирмой Intel в 1971 году для применения в настольных микрокальку-
ляторах. Микросхема i4004 выпускалась в корпусе PDIP16, выполняла
92,6 тысяч действий в секунду и адресовала всего 640 байт памяти. Система
команд первого процессора включала 46 инструкций. Давно известные прин-
ципы программного управления впервые были применены в интегральной
микросхеме. Это положило начало новому направлению микросхемотехники.
На протяжении сорока лет микропроцессорная техника может по пра-
ву считаться наиболее динамично развивающимся направлением микросхе-
мотехники. Постоянно повышаются тактовые частоты микропроцессоров,
увеличивается число полупроводниковых элементов на кристалле, усложня-
ются операционные узлы и система команд.
Универсальные микропроцессоры, предназначенные для решения ши-
рокого круга задач, связанных с обработкой цифровой информации, стали
основой для построения персональных компьютеров. Благодаря высокому
быстродействию, разрядности и объему адресуемой памяти такие микропро-
цессоры отличаются способностью выполнять громоздкие алгоритмы за при-
емлемое время.
Чрезвычайная гибкость микропроцессоров сделала их привлекатель-
ными для применения в составе разнообразных технических изделий от бы-
товых приборов до промышленных установок. По мере широкого распро-
странения микропроцессоров возникла необходимость в разработке эконо-
мичных, компактных и исключительно надежных микропроцессорных си-
стемы, причем, в кратчайшие сроки.
Высокопроизводительные универсальные микропроцессоры не удо-
влетворяют таким потребностям. Их ядро представляет собой набор взаимо-
действующих интегральных микросхем высокой степени интеграции с боль-
шим числом выводов. При этом требуется изготовление печатных плат высо-
кого класса плотности монтажа. Передача цифровых сигналов в микропро-
цессорных системах осуществляется в диапазоне высоких и ультравысоких
частот, что также выдвигает жесткие требования к технологии изготовления
аппаратуры. Кроме того, универсальные микропроцессоры не приспособле-
ны для непосредственного взаимодействия со средой, требуя еще и сложных
средств сопряжения.
Разрешить возникшие противоречия позволило создание микро-
контроллеров. Эти устройства представляют собой совмещение всех элемен-
тов микропроцессорной системы на одном кристалле.
Микроконтроллеры предназначены для решения задач управления
объектом в реальном времени. Помимо микропроцессорного ядра содержат
встроенные память для программы и данных, а также периферийные устрой-
ства для сопряжения с объектом. Как правило, микроконтроллеры обладают
меньшим быстродействием, разрядностью и объемом памяти, чем универ-
6
сальные микропроцессоры, но выделяются развитыми средствами для ввода
и вывода дискретных и аналоговых сигналов.
Первый микроконтроллер i8051 также был разработан фирмой Intel в
1980 году. Это был 8-разрядный микроконтроллер, выполненный в виде мик-
росхемы в корпусе PDIP40. Архитектура 8051 (или ее развитие 8052), реали-
зованная во множестве модификаций микроконтроллеров, чрезвычайно по-
пулярна до настоящего времени и будет оставаться популярной еще, по
меньшей мере, десять лет.
Число семейств микроконтроллеров, разработанных за тридцатилет-
нюю историю, по всей видимости, исчисляется сотнями, а в каждом семей-
стве насчитывается до нескольких десятков микросхем. Разнообразие дей-
ствительно огромно: от очень простых микросхем всего с шестью выводами
до сложных однокристальных систем ввода, вывода и обработки сигналов.
Сегодня микроконтроллеры чрезвычайно распространены, составляя
основу для построения так называемых встраиваемым систем, то есть микро-
процессорных систем, встроенных в какое либо изделие и управляющее им
или его узлами. С использованием микроконтроллеров конструируется со-
временное промышленное оборудование, контрольно-измерительные прибо-
ры, бортовые устройства транспортных средств, медицинские и бытовые
приборы. Знание архитектур распространенных микропроцессоров и микро-
контроллеров, владение приемами их программирования и отладки программ
необходимы инженеру, работающему в этих областях техники.
7
Часть 1. Архитектура и аппаратные средства
микроконтроллера LPC214x
9
г) Переход в режим Undefined производится в случае попытки вы-
полнения неопределенной команды (исключительная ситуация Undefined).
д) IRQ — режим прерывания, классифицированного как IRQ.
е) FIQ — режим прерывания, классифицированного как FIQ (быстрое
прерывание).
Все режимы кроме User называются привилегированными. В этих ре-
жимах доступны некоторые функции управления ядром, которые не доступ-
ны в режиме User.
1.2.2 Система регистров
Арифметико-логическое устройство МК взаимодействует с 16 реги-
страми общего назначения, обозначаемыми R0–R15 (рисунок 1.2.1). Реги-
стры R0–R12 доступны для размещения данных. Регистр R13 (SP) служит
указателем стека; в нем хранится адрес вершины стека, организованного в
памяти данных. R14 (LR) — регистр связи, предназначенный для хранения
адреса возврата при вызове прерываний и подпрограмм. R15 (PC) — счетчик
команд, содержащий адрес следующей команды.
В каждом привилегированном (то есть кроме User/System) режиме
имеется своя пара регистров R13, R14. На схеме (рисунок 1.2.1) они обозна-
чены R13_xxx, R14_xxx, где xxx — идентификатор режима. При смене ре-
жима используются эти копии, а оригинальное содержимое R13, R14 основ-
ного режима User/System сохраняется неизменным. Это необходимо для пол-
ного восстановления состояния ядра при возврате в режим User/System.
Вполне очевидно, что счетчик команд R15 не должен ни сохраняться, ни вос-
станавливаться при смене режима, поэтому он не имеет копий. Для режима
быстрого прерывания FIQ предусмотрен второй набор регистров R8–R12.
Эти «дублеры» R8–R12 можно использовать в процедуре обработки быстро-
го прерывания, не затрачивая времени на сохранение в стек оригинальных
регистров режима User/System и на последующее их восстановление.
Регистр состояния программы CPSR содержит флаги результатов
арифметических операций и биты управления режимом ядра (раздел 1.2.3).
Изменение регистра CPSR программным путем возможно только в привиле-
гированных режимах. Для сохранения слова состояния программы имеются
регистры SPSR_xxx, где xxx — идентификатор режима.
1.2.3 Слово состояния программы
Схема флагов и управляющих битов слова состояния программы
CPSR показана на рисунке 1.2.1 (внизу).
Флаги результата арифметических операций, устанавливаются авто-
матически при обработке данных в АЛУ инструкциями, вызванными с моди-
фикатором {S} (раздел 1.4 и таблица 1.4.2). В таблице 1.2.1 даны примеры
влияния на флаги операции сложения. Рассмотрим назначение флагов слова
состояния программы CPSR.
● Бит 31 (N) — флаг устанавливается в единицу, если результат вы-
числений в АЛУ отрицательный, то есть если старший (31-ый) разряд ре-
зультата равен единице.
10
User/System FIQ Supervisor Abort IRQ Undefined 0xFFFFFFFF
Режимы: Выполнение Быстрое Программное Ошибка Прерывание Неопределен- Устройства AHB
0xF0000000
программы прерывание прерывание адреса ная команда 0xEFFFFFFF
R0 R0 Устройства VPB
R0 R0 R0 R0 0xE0000000
R1 R1 R1 R1 R1 R1
R2 R2 R2 R2 R2 R2 Загрузчик 0x7FFFFFFF
R3 R3 R3 R3 R3 R3 12 кбайт 0x7FFFD000
R4 R4 R4 R4 R4 R4
R5 R5 R5 R5 R5 R5 Буфер USB 0x7FD01FFF
Регистры
общего R6 R6 R6 R6 R6 R6 8 кбайт 0x7FD00000
назначения R7 R7 R7 R7 R7 R7
0x40007FFF
R8 R8_fiq R8 R8 R8 R8 Память данных
R9 R9_fiq R9 R9 R9 R9 ОЗУ
32 кбайта 0x40000000
R10 R10_fiq R10 R10 R10 R10
Порты 0x3FFFFFFF
R11 R11_fiq R11 R11 R11 R11
ввода-вывода 0x3FFF8000
R12 R12_fiq R12 R12 R12 R12
Указатель стека R13 (SP) R13_fiq R13_svc R13_abt R13_irq R13_und
0x0007FFFF
Адрес возврата R14 (LR) R14_fiq R14_svc R14_abt R14_irq R14_und Память программ
Счетчик команд R15 (PC) R15 R15 R15 R15 R15 Flash-ПЗУ
512 кбайт 0x00000040
Регистр состояния CPSR CPSR CPSR CPSR CPSR CPSR 0x0000003F
Резерв
11
Таблица 1.2.1 – Примеры влияния операции сложения на флаги результата
Операция Результат C V N Z
1 0 0 0
0 1 0 0
0 0 1 0
1 1 0 0
1 0 0 1
0 1 1 0
1 0 1 0
● Бит 30 (Z) — флаг устанавливается в единицу, если результат вы-
числений в АЛУ равен нулю.
● Бит 29 (С) — флаг переноса, инверсный влаг заема. При сложении
беззнаковых чисел флаг устанавливается в единицу, если произошел перенос
из 31-го разряда, то есть если результат вычислений в АЛУ больше .
При вычитании беззнаковых чисел флаг сбрасывается в ноль, если произо-
шел заем из несуществующего 32-го разряда, то есть если результат вычис-
лений в АЛУ меньше нуля.
● Бит 28 (V) — флаг арифметического переполнения. При сложении и
вычитании чисел со знаком флаг устанавливается в единицу, если результат
вычислений в АЛУ больше или меньше . Такой результат приво-
дит к потере знака. Иными словами, флаг устанавливается в единицу, если
знаковый (31-ый) разряд обоих операндов одинаков и отличается от знаково-
го разряда результата.
● Бит 7 (I) — бит запрета прерываний IRQ. Устанавливается аппарат-
но в единицу в исключительных ситуациях Reset, SWI, IRQ, FIQ. Равенство
единице запрещает прерывания IRQ при сбросе и в одноименных режимах.
● Бит 6 (F) — бит запрета прерываний FIQ. Устанавливается в едини-
цу аппаратно в исключительных ситуациях Reset, FIQ. Равенство единицы
запрещает прерывания FIQ при сбросе и в режиме FIQ.
● Бит 5 (T) — бит перевода ядра в 16-разрядный режим Thumb ( ).
В режиме Thumb меняется программистская модель и система команд мик-
роконтроллера. Производительность в режиме Thumb снижается, но благода-
ря коротким 16-разрядным командам сокращается расход памяти программ.
Режим Thumb в настоящем учебном пособии не рассматривается.
Таблица 1.2.2 – Управление режимом работы ядра через регистр CPSR
Режим Mode (двоичные и шестнадцатеричные значения)
User 10000 (0x10)
FIQ 10001 (0x11)
Привилегир.
Исключ.
12
● Биты 0–4 (Mode) — код управления режимом работы микро-
контроллера (раздел 1.2.1) в соответствии с таблицей 1.2.2.
1.2.4 Организация памяти
В состав системы памяти входит память программ, память данных и
массив управляющих регистров.
Ядро ARM7 основано на фон-неймановской архитектуре. Это значит,
что одна и та же шина используется для передачи команд и данных. Имеется
единое адресное пространство для памяти программ, данных и управляющих
регистров; обращение к этим областям памяти выполняется одними и теми
же командами (в основном LDR и STR). Шина адреса имеет разрядность
32 бита, соответственно объем адресного пространства составляет 4 Гбайта.
Единое адресное пространство и возможность размещения частей
программы в памяти данных делают неточными термины «память программ»
и «память данных». Поэтому далее будем чаще называть их ПЗУ и ОЗУ.
Схема распределения памяти показана на рисунке 1.2.1. На схеме вы-
делены области памяти данных, памяти программ, а также области портов
ввода-вывода и устройств AHB и APB.
Память программ предназначена для постоянного хранения про-
граммы и используемых ей констант. Память программ представляет собой
электрически перепрограммируемое ПЗУ (FLASH) объемом 512 кбайт. К
этой области относятся адреса 0x00000000–0x3FFF7FFF и 0x7FFFD000–
0x7FFFFFFF (загрузчик).
Адреса 0x00000000–0x0000003F в начальной области памяти (отделе-
ны пунктирной линией) принадлежат векторам исключительных ситуаций и
прерываний. В LPC2148 из них используются первые восемь 32-разрядных
ячеек с адресами 0x00000000–0x0000001С. При возникновении исключи-
тельной ситуации или прерывания управление передается команде, располо-
женной по одному из этих адресов. Подробнее вопросы обработки исключе-
ний рассматриваются в разделах 1.6 и 1.11. Здесь коснемся лишь ячейки с ад-
ресом 0x00000014 (Checksum). Ячейка предназначена для хранения
32-разрядной контрольной суммы остальных семи ячеек. Контрольная сумма
используется процедурой начальной загрузки (раздел 1.5).
Основное назначение памяти данных — хранение переменных, со-
здаваемых программой. Встроенная память данных является статическим
ОЗУ объемом 40 кбайт, из которых 8 кбайт служат буфером для приемопере-
датчика USB, хотя могут использоваться и для общих целей. ОЗУ занимает
адреса выше 0x40000000.
Управляющие регистры предназначенных для взаимодействия ядра
с периферийными устройствами микроконтроллера и системой прерываний.
Обмен данными с управляющими регистрами осуществляется через две
внутренние шины: шину высокого быстродействия (AHB — Advanced High-
performance Bus) и шину периферийных устройств (APB — ARM Peripheral
Bus). Через шину AHB ведется управление системой прерываний; остальные
регистры подключены к шине APB. Управляющим регистрам отведены адре-
13
са выше 0xE0000000. Отдельная область памяти 0x3FFF8000–0x3FFFFFFF
предназначена для регистров управления портами в быстром режиме.
Организация памяти в ARM7 байтовая. Это значит, что каждый адрес
указывает на ячейку размером 1 байт. В то же время хранимые в памяти дан-
ные выравниваются соответственно их разрядности. Поэтому при обращении
к 16-разрядному слову адрес должен быть четным; для 32-разрядного слова
адрес должен быть кратным четырем (закачиваться на шестнадцатеричные
цифры 0, 4, 8, С). Обращение в байтовом режиме возможно к любому адресу.
Данные, занимающие более одного байта, хранятся с обратным по-
рядком байт. Младший байт размещается по адресу с меньшим номером;
старший байт — по адресу с большим номером.
14
Перечень команд, сгруппированных по выполняемым функциям, при-
веден в таблице 1.3.2 (см. также о псевдокомандах в разделе 2.5). Кратко рас-
смотрим каждую из групп.
1.3.1 Команды арифметической и логической обработки
Команды этой группы предназначены для выполнения арифметиче-
ских действий (сложение, вычитание) с целыми числами, а также логических
операций (конъюнкция, дизъюнкция, исключающее «ИЛИ»). Команды явля-
ются трехадресными и все имеют общий синтаксис:
Операция{Усл}{S} , ,
При этом Операция, определяемая мнемоническим обозначением, выполня-
ется над операндами и . Результат операции помещается в .
Здесь , любые регистры общего назначения (R0–R15). ,
занимающий 12 разрядов в коде команды, может быть адресован непосред-
ственным или регистровым методом (раздел 1.4.1 и таблица 1.4.1).
Операнд может отсутствовать или совпадать с . Эти случаи ин-
терпретируются одинаково — служит и первым операндом, и приемником.
Имеется необязательный модификатор «S», который указывает на
необходимость обновления флагов состояния программы. Без этого модифи-
катора обновление не происходит. Независимо от результата выполнения
команды флаги результат остаются неизменными.
Примеры:
ADD R0, R1, R2 ; R0 = R1 + R2
AND R0, R1, #0x80 ; R0 = R1 & 0x80
ADD R0, R1 ; R0 += R1
ADDEQ R0, R1, R2 ; if (Z) R0 = R1 + R2
1.3.2 Команды умножения
Команды выполняют умножение 32-разрядных целых чисел. Операн-
дами и приемником результата могут служат регистры общего назначения.
Имеются команды для умножения с накоплением. Результат может
быть 32- или 64-разрадным. Команды с 32-разрядным результатом отбрасы-
вают старшую часть. 64-разрядный результат размещается в паре регистров
общего назначения.
Примеры:
MUL R0, R1, R2 ; R0 = (long)(R1 * R2)
MLA R0, R1, R2, R3 ; R0 = (long)(R1 * R2 + R3)
Влияние команд на флаги состояния включается модификатором «S».
1.3.3 Команды регистровой пересылки
Команды пересылки предназначены для загрузки регистра короткой
константой или для копирования содержимого одного регистра в другой.
Команды двухадресные; второй операнд может быть задан непосредственно
(константа) или адресован регистровым способом. При копировании воз-
можна инверсия (команда MVN) или сдвиг.
15
Таблица 1.3.2 – Система команд процессорного ядра ARM7
Мнемоническое обозначение Операция Краткое описание
Команды арифметической обработки
ADD{Усл}{S} , , Арифметическое сложение
ADC{Усл}{S} , , Арифметическое сложение с переносом
SUB{Усл}{S} , , Вычитание
SBC{Усл}{S} , , Вычитание с учетом заема
RSB{Усл}{S} , , Обратное вычитание
RSС{Усл}{S} , , Обратное вычитание с учетом заема
Команды логической обработки
AND{Усл}{S} , , Логическое умножение (И)
ORR{Усл}{S} , , Логическое сложение (ИЛИ)
EOR{Усл}{S} , , Исключающее ИЛИ (сложение по модулю 2)
BIC{Усл}{S} , , Сброс битов в ноль
Команды регистровой пересылки
MOV{Усл}{S} , Копирование регистра или загрузка константы
Копирование регистра или загрузка константы
MVN{Усл}{S} ,
с инверсией
Команды сравнения и тестирования
CMN{Усл} , Сравнение с отрицательным числом
CMP{Усл} , Сравнение с положительным числом
TEQ{Усл} , Проверка равенства
TST{Усл} , Тестирование
Команды умножения c 32-разрядным результатом
MUL{Усл}{S} , , Умножение (с учетом знаков)
MLA{Усл}{S} , , , Умножение с накоплением (с учетом знаков)
16
Таблица 1.3.2 – Продолжение
Мнемоническое обозначение Операция Краткое описание
Команды умножения с 64-разрядным результатом
SMULL{Усл}{S} , , , Умножение учетом знака
SMLAL{Усл}{S} , , , Умножение с накопл. (с учетом знака)
UMULL{Усл}{S} , , , Умножение положительных чисел
UMLAL{Усл}{S} , , , Умножение полож. чисел с накоплением
Команды загрузки регистров из памяти
LDR{Усл} , Загрузка регистра
LDR{Усл}B , ; Загрузка регистра байтом
Загрузка регистра байтом
LDR{Усл}BT , ;
c эмуляцией режима User
LDR{Усл}H , ; Загрузка регистра двухбайтным словом
; Загрузка регистра байтом
LDR{Усл}SB ,
c дополнением знака
Загрузка регистра двухбайтовым словом
LDR{Усл}SH ,
c дополнением знака
Загрузка регистра
LDR{Усл}T ,
c эмуляцией режима User
Команды сохранения регистров в память
STR{Усл} , Сохранение регистра в память
STR{Усл}B , Сохранение в память мл. байта регистра
Сохранение в память младшего байта
STR{Усл}BT ,
регистра с эмуляцией режима User
STR{Усл}H , Сохранение в память мл. слова регистра
Сохранение регистра в память с эмуля-
STR{Усл}T ,
цией режима User
17
Таблица 1.3.2 – Продолжение
Мнемоническое обозначение Операция Краткое описание
Команды перестановки регистров и ячеек памяти
SWP{Усл} , ,[ ] ; Обмен между регистрами и памятью
SWP{Усл}B , ,[ ] Обмен байтов между регистрами и памятью
Команды пакетной пересылки
LDM{Усл}IA {!},
Загрузить блок памяти Методы адресации:
LDM{Усл}IB {!},
с базовым адресом равным IA (FD) — постинкрементный;
LDM{Усл}DA {!},
в список Регистров IB (ED) — преинкрементный;
LDM{Усл}DB {!},
DA (FA) — постдекрементный;
STM{Усл}IA {!},
Сохранить список Регистров DB (EA) — предекрементный.
STM{Усл}IB {!},
в блок памяти, Список регистров задается в фигурных скобах через
STM{Усл}DA {!}, запятую или тире, например, {R0–R3, R5}
начиная с адреса в
STM{Усл}DB {!},
Команды передачи управления
B{Усл} Передача управления по непосредственному адресу
BL{Усл} ; Передача управления с сохранением адреса возврата
Передача управления по адресу в регистре
BX{Усл}
со сменой режима ARM/Thumb
SWI{Усл} Вызов прерывания Software Interrupt; перевод процессора в режим ARM Supervisor
Команды обращения к слову состояния программы
MRS{Усл}{S} , CPSR
Сохранение или в регистр
MRS{Усл}{S} , SPSR
MSR{Усл} CPSR_Поля, #
MSR{Усл} SPSR_Поля, # Запись константы или регистра в разряды флагов в или .
MSR{Усл} CPSR_Поля, Поля задают копируемые байты: c — 0, x — 1, s — 2, f — 3
MSR{Усл} SPSR_Поля,
18
Ограниченная разрядность поля операнда не позволяет загружать
произвольную 32-разрядную константу. Непосредственно в коде команды
могут размещаться только 8-разрядные константы с 4-разрядным смещением
(раздел 1.4.1). Для загрузки 32-разрядных констант используются команды
обмена с памятью. Влияние команд пересылки на флаги состояния разреша-
ется или запрещается модификатором «S». Формат команд:
MOV{Усл}{S} ,
MVN{Усл}{S} ,
Операнд12 копируется в регистр-приемник (R0–R15).
Примеры:
MOV R0, #0x80 ; R0 = 0x80
MVN R0, R1, LSR #2 ; R0 = ~(R1 << 2)
Для загрузки «полноценных» 32-разрядных констант служит псевдо-
команда
LDR{Усл} ,=
При этом константа размещается в отдельной ячейке памяти программ, адрес
которой задается 12-разрядным кодом, обычно в виде смещения по отноше-
нию к счетчику команд.
1.3.4 Команды загрузки и сохранения регистров
Эти команды предназначены для загрузки в регистры общего назна-
чения содержимого ячеек памяти и сохранения в память содержимого реги-
стров. Команды двухадресные, имею общий формат
Команда{Усл} , /
Поддерживается косвенная или индексная адресация (раздел 1.4.2). Имеется
несколько модификаций команд этой группы (таблица 1.3.2) для пересылки
байтов и двухбайтных слов. Как указывалось выше, при передаче 16-
разрядного слова адрес обязательно должен быть четным, а при передаче 32-
разрядного слова — кратным четырем. На флаги состояния программы ко-
манды эти команды не влияют.
Примеры:
STR R1, [R2] ; *R2 = R1
LDR R1, [PC, #0x58] ; R1 = *(PC + 0x58)
К этой же группе относится команды SWP одновременно загружаю-
щую и сохраняющую регистры. С помощью SWP можно «перестановить ме-
стами» содержимое регистра и ячейки памяти.
1.3.5 Команды пакетного обмена с памятью
Основное назначение таких команд — сохранение регистров в стек и
последующем их восстановлении. В адресной части команды указывается ре-
гистр, содержащий базовый адрес блока памяти, перечень регистров общего
назначения, содержимое которых требуется сохранить в блок памяти или за-
грузить этим блоком, а также метод адресации. Поддерживается автоинкре-
ментный и автодекрементный виды адресации.
19
Пример:
STMDB SP!, {R1-R2} ; *(SP-=4) = R1; *(SP-=4) = R2
LDMIA SP!, {R3} ; *SP = R3; SP += 4
1.3.6 Команды передачи управления
Команды служат для безусловных и условных переходов (ветвлений)
и вызова подпрограмм. Поскольку все команды ARM7 являются условными,
достаточно всего трех команд B (перехода по непосредственному адресу) BL
(переход с сохранением адреса возврата в LR) и BX (переход по адресу в ре-
гистре).
Адрес перехода, заданный непосредственно, кодируется как 24-
разрядное смещение (включая знак), которое умножается на 4 и прибавляется
к текущему значению счетчика команд. Фактически реализуется операция
20
этому длинные 32-разрядные адресе не могут размещаться в коде операции.
Ниже рассмотрены поддерживаемые методы адресации.
Важный материал далее представлен в форме таблиц (1.4.1–1.4.3). В
таблицах использованы следующие обозначения: текст, набранный шрифтом
Consolas, не допускает изменения, так как является мнемоническим обозна-
чением или элементами синтаксиса. Текст, оформленный наклонным шриф-
том Times, представляет собой операнды. Вместо него подставляются кон-
станты, адреса или имена регистров, содержащих обрабатываемые данные.
Элементы в фигурных скобках «{ }» не обязательны и могут быть опущены.
1.4.1 Непосредственная адресация
Непосредственная адресация наряду с регистровой применяется в ко-
мандах арифметической и логической обработки. Непосредственная адреса-
ция наиболее проста. Операндом является числовая константа располо-
женная непосредственно в коде операции.
Пример (третий операнд адресован непосредственно):
SUB R2, R0, #0x80000001 ; R2 = R0 - 0x80000001
Разрядность поля операнда ограничена 12 битами. Это поле состоит
из двух частей: восьмиразрядной , и четырехразрядной . Операнд фор-
мируется путем циклического сдвига вправо константы на разряда.
Допустимыми являются только числа, которые могут быть представлены та-
ким способом. Характерный пример — число 0x80000001 (шестнадцатерич-
ное), которое получается путем сдвига числа 6 (двоичная запись ) на два
разряда вправо. В то же время число , для записи которого в обычном
прямом двоичном коде требуется всего девять разрядов, недопустимо, так
как все эти разряды содержат единицы. Определить множество допустимых
чисел с помощью удобной математической формулы вряд ли возможно.
1.4.2 Регистровая адресация
Регистровая адресация (короткая прямая) — вторая разновидность ад-
ресации в арифметико-логических командах. При регистровой адресации
операнд расположен в одном из регистров .
Пример (все три операнда адресованы регистровым способом):
ORR R3, R3, R2 ; R3 = R3 | R2
Здесь примеры сопровождаются комментариями (через «;»), поясняющими
выполняемые командой действия. При этом использован синтаксис языка Си.
В коде команды номер регистра обозначается коротким 4-разрядным
полем. Это позволяет включить три адресных поля в сравнительно длинные
32-разрядные команды ARM7.
Кроме базового варианта поддерживается несколько видов сдвига ре-
гистрового операнда. Способ сдвига обозначается специальным ключевым
словом. Число разрядов сдвига обозначается непосредственно константой
или хранится в регистре общего назначения. Примеры:
ADD R0, R0, R1, LSR #4 ; R0 = R0 + R1 >> 4
ADD R0, R0, R1, LSR R2 ; R0 = R0 + R1 >> R2
21
Сдвиг применим только к последнему третьему операнду (в примере
это регистр R1). В таблице 1.4.1 приведены допустимые варианты регистро-
вой адресации со сдвигом.
Таблица 1.4.1 – Непосредств. и регистровая адресация (операнд типа )
Метод адресации Сдвиг операнда
Непосредственная # —
Регистровая —
, LSL # Логический влево на разрядов
Регистровая с , LSR # Логический вправо на разряд
непосредственным , ASL # Арифм. вправо на разряд
сдвигом , ROR # Циклич. вправо на разряд
, RRX Цикл. вправо через перенос на 1 разр.
, LSL Логический влево на разрядов
Регистровая с
, LSR Логический вправо на разрядов
регистровым
, ASL Арифм. вправо на разрядов
сдвигом
, ROR Циклический вправо на разрядов
1.4.3 Косвенная адресация
Косвенная адресация применяется только в командах обмена с памя-
тью. Предполагается, что 32-разрядный исполнительный адрес хранится в
одном из регистров общего назначения, в то время как в коде операции хра-
нится лишь короткая 4-разрядная ссылка на этот регистр, играющий роль
указателя. Пример:
LDR R0, [R1] ; R0 = *R1
Разумеется, регистр-указатель должен быть предварительно загружен нуж-
ным адресом.
1.4.4 Индексная адресация
Индексная адресация является развитием косвенной и так же как кос-
венная применяется в командах сохранения, загрузки и обмена с памятью.
При индексной адресации исполнительный адрес вычисляется как сумма или
разность базового адреса и смещения. Базовый адрес хранится в регистре
общего назначения ( ). Смещение может быть задано непо-
средственно числовой константой или тоже храниться в одном из регистров
общего назначения.
После выполнения операции исполнительный адрес может быть поте-
рян, либо сохранен. В последнем случае регистр, хранящий базовый адрес,
модифицируется, то есть увеличивается на величину смещения. Причем ба-
зовый адрес может модифицироваться на величину смещения до обращения
к памяти или после. По этому признаку различают преиндексную адресацию
и постиндексную.
Кроме того смещение, прибавляемое к базовому адресу или вычитае-
мое из него, может быть подвергнуто сдвигу. Поддерживается несколько ви-
дов сдвига (таблица 1.3.2).
22
Таблица 1.4.2 – Косвенная и индексная адресация (операнд типа )
Метод Исполн. Содержимое
Вид сдвига
адресации адрес после операции
Косвенная [ ] — — —
Непоср.
[ ], #± —
Постиндексная
смещ.
[ ], ± — —
Регистровое
со сдвигом
смещение
модификатора {!}
Rn не меняется без
смещ.
Преиндексная
[ ,± ]{!} — —
Регистровое
[ ,± , LSL # ]{!}
смещение
25
командой возврата в основную программу. При этом состояние программы
восстанавливается таким, каким оно было до возникновения исключения.
Исключения характеризуются разными приоритетами. Обработка ис-
ключения с меньшим приоритетом может быть приостановлена возникшим
исключением с более высоким приоритетом.
Исключительные ситуации, обработка которых предусмотрена аппа-
ратурой контроллера LPC2148, перечислены ниже (см. также раздел 2.4.1).
Reset — сброс. Исключение возникает в следующих случаях:
а) включение питания микроконтроллера или восстановление напря-
жения питания после провала до 1 В;
б) нарастающий перепад напряжения на контакте ;
в) сигнал сброса от сторожевого таймера;
г) сигнал от супервизора питания, свидетельствующий о снижении
напряжения до 2,6 В.
Undefined — неопределенная команда. Исключение возникает, если
на конвейер поступил код нераспознанной команды
Software interrupt (SWI) — программное прерывание. Вызывается
командой SWI.
Prefetch abort (PAbort) — ошибка адреса команды. Исключение возни-
кает при передаче управления по адресу памяти, не реализованному физически.
Data abort (DAbort) — ошибка адреса данных. Исключение возника-
ет при попытке обращения к ячейке памяти, не реализованной физически.
Interrupt request (IRQ) — прерывание. Поступил запрос прерывания,
разрешенного и классифицированного как zIRQ.
Fast interrupt request (FIQ) — быстрое прерывание. Поступил запрос
прерывания, разрешенного и классифицированного как FIQ.
В таблице 1.6.1 для каждого исключения указан приоритет, закреп-
ленный адрес памяти программ для передачи управления, режим, в который
будет переведен процессор на время обработки исключения, и инструкция,
завершающая обработку.
Общий порядок действий, выполняемых при возникновении исклю-
чения таков:
1. Cодержимое счетчика команд R15 (PC), указывающее на следую-
щую команду, сохраняется в регистр R14_xxx (LR), где xxx — идентификатор
Таблица 1.6.1 – Исключения, поддерживаемые ядром ARM7TDMI
Исключение Приор. Вектор I/F Режим Инструкция выхода
Reset 1 0x00000000 1/1 Supervisor —
Undefined 6 0x00000004 –/– Undefined MOVS PC, R14
SWI 6 0x00000008 1/– Supervisor MOVS PC, R14
PAbort 5 0x0000000C –/– Abort SUBS PC, R14, #4
SUBS PC, R14, #4
DAbort 2 0x00000010 –/– Abort
SUBS PC, R14, #8
IRQ 4 0x00000018 1/– IRQ SUBS PC, R14, #4
FIQ 3 0x0000001C 1/1 FIQ SUBS PC, R14, #4
26
режима, соответствующего возникшему исключению. Например, при воз-
никновении исключения Data Abort счетчик команд сохраняется в R14_abt.
Для Data Abort в R14_xxx помещается значение для остальных —
.
2. Содержимое слова состояния программы CPSR сохраняется в ре-
гистр SPSR_xxx режима, соответствующего исключению.
3. Изменяется режим работы процессора, а также устанавливаются
биты запрета прерываний (I и F) в слове состояния программы CPSR в соот-
ветствии с таблицей 1.6.1.
4. В счетчик команд R15 (PC) записывается адрес вектора исключения
в соответствии с таблицей 1.6.1, что приводит к немедленной передаче
управления команде, расположенной по этому адресу.
Общий порядок действий, производимых ядром ARM7 при возврате
из обработчика исключения:
1. Восстанавливается содержимое счетчика команд R15 (PC) путем
вычитания из R15_xxx смещения. Команды возврата приведены в таблице
1.6.1. Для Data Abort может использоваться возврат к команде, вызвавшей
исключение, а может к следующей ща ней команде (то есть с пропуском ко-
манды, приведшей к ошибке). Это достигается вычитанием смещения 8 или 4.
2. При выполнении команды возврата автоматически восстанавлива-
ется слово состояния программы CPSR из SPSR_xxx. При этом режим ядра
меняется на исходный, сбрасываются флаги запрета прерывания I и F, уста-
новленные в ходе обработки исключения.
Частный случай обработки прерываний IRQ и FIQ рассмотрен по-
дробней в разделе 1.11.2.
27
(МГц). (1.7.3)
Например, при частоте кварцевого резонатора МГц значения
, дают МГц и МГц. Такие параметры си-
стемы тактирования можно рекомендовать разработчикам.
Имеется второй умножитель, предназначенный для тактирования при-
емопередатчика USB. Его настройка осуществляется аналогичным образом с
поправкой — выходная частота должна быть равна 48 МГц.
Значения и для ФАПЧ 0 и 1 задаются через регистры PLL0CON
и PLL1CON соответственно. Для выполнения настройки необходимо обра-
щаться еще к нескольким регистрам.
В учебном пособии настройка ФАПЧ через регистры специальных
функций не рассматривается. В большинстве случаев настройка системы так-
тирования выполняется однократно, ее не приходится выполнять повторно
во время выполнения программы. Поэтому предлагается воспользоваться ин-
струментом Configuration Wizard, среды Keil µVision 4. Инструмент автома-
тически генерирует необходимые команды настройки и внедряет их в файл
инициализации Startup.s, являющийся частью разрабатываемого проекта.
Значение выбирается в поле PLL Multiplier Selection, значение —
в поле PLL Divider Selection (рисунок 1.7.1).
28
Особенно важно контролировать частоту при использовании
таймеров, поскольку именно этот сигнал поступает на их счетные входы.
Частота шины периферийных устройств APB, так же как и частота яд-
ра, связана с потребляемой микроконтроллером мощностью.
Делитель частоты периферийных устройств задается двумя младшими
разрядами регистра APBDIV (таблица 1.7.1).
Рассмотрим настройку делителя шины APB с помощью Configuration
Wizard (рисунок 1.7.1). По умолчанию флажок VPBDIV Setup снят и исполь-
зуется делитель 1:4. Установка флажка позволяет выбрать значение делителя
шины APB (опция VPBDIB: VPB Clock) согласно таблице 1.7.1.
Таблица 1.7.1 – Управление тактовой частотой шины APB
Двоичный код в регистре APBDIV Делителя частоты шины APB
00 (по умолчанию) 4 (по умолчанию)
01 2
10 1
11 зарезервировано
30
«порт 0» и «порт 1». В них не все разряды реализованы физически. Принято
порты обозначать «P0» и «P1», а номера линий порта указывать через точку,
например «P0.14» или «P1.23». Цифровые сигналы могут формироваться или
считываться с портов под управлением программы (раздел 1.10). Основные
электрические характеристики портовых линий приведены в таблице 1.9.2.
Таблица 1.9.1 – Назначение служебных контактов МК LPC2148
Обознач. Контакт Назначение
Vdd 23, 43, 51 Питание цифровой части (3,0–3,6 В)
Vdda 7 Питание аналоговой части (3,0–3,6 В)
Vss 6, 18, 25, 42, 50 Общая точка цифровой части
Vssa 59 Общая точка аналоговой части
Вход сброса. Низкий лог. уровень переводит
57 микроконтроллер в режим сброса. В рабочем
режиме должен быть подан высокий уровень
XTAL1 62 Контакты для подключения основного кварцево-
го резонатора. На контакт XTAL1 может быть
XTAL2 61 подан внешний тактовый сигнал
RTCX1 3 Контакты для подключения кварцевого резона-
RTCX2 5 тора для тактирования часов реального времени
D+ 10 Двунаправленная линия передачи данных ин-
D– 11 терфейса USB
Vref 63 Опорное напряжение АЦП и ЦАП (2,5–3,6 В)
Vbat 49 Питание часов реального времени (2,0–3,6 В)
Отметим, что реальные логические уровни, существенно отличаются
от предельных. Так в условиях, близких к нормальным, экспериментально
можно установить, что: В, В.
Таблица 1.9.2 – Электрические параметры цифровых портовых линий
Параметр Значение
Предельно допустимое напряжение в режиме входа, В
Выходной уровень логической единицы, В, не менее
Выходной уровень логического нуля, В, не более 0,4
Входной уровень логической единицы, В, не менее 2,0
Входной уровень логического нуля, В, не более 0,8
Ток в режиме входа, мкА, не более 3
Предельный выходной ток, мА 50
Предельный ток через каждый контакт Vdd и Vss, мА 100
1.9.3 Альтернативные функции линий ввода вывода
Портовые линии совмещают основную функцию (цифровой ввод-
вывод) с несколькими альтернативными функциями. Они служат входами
или выходами многочисленных периферийных устройств, встроенных в мик-
роконтроллер, таких как счетчики, АЦП и ЦАП.
31
PINSEL1 – настройка входов внешних прерыыаний
31 P0.30 27 24 23 20 19 16 15 12 11 P0.20 7 4 3 P0.16
0 1 1 1 0 1
EINT3 EINT3 EINT0
1 0 1 0 1 1 1 1 1 1 1 1
EINT2 EINT1 EINT2 EINT2 EINT1 EINT0
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
MAT1.1 MAT1.0 CAP1.1 CAP1.0 CAP0.2 MAT0.1 CAP0.1 MAT0.0 CAP0.0
0 1
PWM5
1 0 1 0 1 0 1 0 1 0
PWM6 PWM4 PWM2 PWM3 PWM1
32
PINSEL1 – настройка входов АЦП
31 P0.30 P0.29 P0.28 23 20 P0.25 16 15 P0.22 P0.21 8 7 4 3 0
0 1 0 1 0 1 0 1 0 1 1 0
AD0.3 AD0.2 AD0.1 AD0.4 AD1.7 AD1.6
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
AD1.5 AD1.4 AD1.3 AD1.2 AD1.1 AD1.0 AD0.7 AD0.6
1 0 1 0 1 0 1 0
SSEL1 MOSI1 MISO1 SCK1
0 1 0 1 0 1 0 1
SSEL0 MOSI0 MISO0 SCK0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
RI DCD DTR DSR CTS RTS RxD1 TxD1 RxD0 TxD0
1 1 1 1 0 1 0 1
SDA1 SCL1 SDA0 SCL0
33
Выбор основной или альтернативной функции линий порта 0 осу-
ществляется путем записи управляющего кода в регистры PINSEL0 и PIN-
SEL1. Имеется также регистр PINSEL2, предназначенный для переключения
линий порта 1 в отладочный режим, который здесь не рассматривается.
Управляющие коды и соответствующие им альтернативные функции
портовых линий приведены в таблицах 1.9.3, 1.9.4. На рисунках 1.9.1 и 1.9.2
показаны схемы регистров PINSEL0 и PINSEL1, сгруппированы по перифе-
рийным устройствам.
Прежде чем использовать какое-либо встроенное периферийное
устройство, требующее взаимодействия с внешней средой, необходимо с по-
мощью таблиц 1.9.3, 1.9.4 или рисунков 1.9.1, 1.9.2 определить, какие кон-
такты МК могут использоваться для обмена сигналами с данным устрой-
ством и внедрить в программу команды перевода выбранных линий в аль-
тернативный режим.
Таблица 1.9.3 – Управление функциями внешних выводов через PINSEL0
Биты Конт. Код Функция Описание
0–1 19 00 Port 0.0
01 TxD0 (UART0) Выход передатчика UART0
10 PWM1 Выход 1 ШИМ
11 —
2–3 21 00 Port 0.1
01 RxD0 (UART0) Вход приемника UART0
10 PWM3 Выход 3 ШИМ
11 EINT0 Вход 0 внешнего прерывания
4–5 22 00 Port 0.2
01 SCL0 (I2C0) Тактовый сигнал I2C0
10 CAP0.0 (Timer 0) Вход 0 устр. захвата таймера 0
11 —
6–7 26 00 Port 0.3
01 SDA0 (I2C0) Линия передачи данных I2C0
10 MAT0.0 (Timer 0) Выход 0 устр. сравнения таймера 0
11 EINT1 Вход 1 внешнего прерывания
8–9 27 00 Port 0.4
01 SCK0 (SPI0) Тактовый сигнал SPI0
10 CAP0.1 (Timer 0) Выход 1 устр. сравнения таймера 0
11 AD0.6 Вход 6 АЦП 0
10–11 29 00 Port 0.5
01 MISO0 (SPI0) Вход ведущего, выход ведомого SPI0
10 MAT0.1 (Timer 0) Выход 1 устр. сравнения таймера 0
11 AD0.7 Вход 7 АЦП 0
34
Таблица 1.9.3 – Продолжение
Биты Конт. Код Функция Описание
12–13 30 00 Port 0.6
01 MOSI0 (SPI0) Выход ведущего, вход ведомого SPI0
10 CAP0.2 (Timer 0) Выход 2 устр. сравнения таймера 0
11 AD1.0 Вход 0 АЦП 1
14–15 31 00 Port 0.7
01 SSEL0 (SPI0) Выбор режима ведущий/ведомый SPI0
10 PWM2 Выход 2 ШИМ
11 EINT2 Вход 2 внешнего прерывания
16–17 33 00 Port 0.8
01 TxD1 (UART1) Выход передатчика UART1
10 PWM4 Выход 4 ШИМ
11 AD1.1 Вход 1 АЦП 1
18–19 34 00 Port 0.9
01 RxD1 (UART1) Вход приемника UART1
10 PWM6 Выход 6 ШИМ
11 EINT3 Вход 3 внешнего прерывания
20–21 35 00 Port 0.10
01 RTS (UART1) Выход запроса передачу (UART1)
10 CAP1.0 (Timer 1) Вход 0 устр. сравнения таймера 1
11 AD1.2 Вход 2 АЦП 1
22–23 37 00 Port 0.11
01 CTS (UART1) Вход готовности к передаче UART1
10 CAP1.1 (Timer 1) Выход 1 устр. сравнения таймера 1
11 SCL1 (I2C1) Тактовый сигнал I2C1
24–25 38 00 Port 0.12
01 DSR (UART1) Вход готовности к обмену UART1
10 MAT1.0 (Timer 1) Выход 0 устр. сравнения таймера 1
11 AD1.3 Вход 3 АЦП 1
26–27 39 00 Port 0.13
01 DTR (UART1) Выход готовности к обмену UART1
10 MAT1.1 (Timer 1) Выход 1 устр. сравнения таймера 1
11 AD1.4 Вход 4 АЦП 1
28–29 41 00 Port 0.14
01 DCD (UART1) Вход «связь установлена» UART1
10 EINT1 Вход 1 внешнего прерывания
11 SDA1 (I2C1) Линия данных (I2C1)
30–31 45 00 Port 0.15
01 RI (UART1) Вход входящего вызова UART1
10 EINT2 Вход 2 внешнего прерывания
11 AD1.5 Вход 5 АЦП 1
35
Таблица 1.9.4 – Управление функциями внешних выводов через PINSEL1
Биты Конт. Код Функция Описание
0–1 46 00 Port 0.16
01 EINT0 Вход 0 внешнего прерывания
10 MAT0.2 (Timer 0) Выход 2 устр. совпадения таймера 0
11 CAP0.2 (Timer 0) Вход 2 устр. захвата таймера 0
2–3 47 00 Port 0.17
01 CAP1.2 (Timer 1) Вход 2 устр. захвата таймера 1
10 SCK1 (SSP) Тактовый синел интерфейса SSP
11 MAT1.2 (Timer 1) Выход 2 устр. совпадения таймера 1
4–5 53 00 Port 0.18
01 CAP1.3 (Timer 1) Вход 3 устр. захвата таймера 1
10 MISO1 (SSP) Вход ведущего, выход ведомого SSP
11 MAT1.3 Выход 2 устр. совпадения таймера 3
6–7 54 00 Port 0.19
01 MAT1.2 Выход 2 устр. совпадения таймера 1
10 MOSI1 (SSP) Выход ведущего, вход ведомого SSP
11 CAP1.2 (Timer 1) Вход 2 устр. захвата таймера 1
8–9 55 00 Port 0.20
01 MAT1.3 (Timer 1) Выход 2 устр. совпадения таймера 3
10 SSEL1 (SSP) Выбор режима ведущий/ведомый SSP
11 EINT3 Вход 3 внешнего прерывания
10–11 1 00 Port 0.21
01 PWM5 Выход 5 ШИМ0
10 AD1.6 Вход 6 АЦП 1
11 CAP1.3 (Timer 1) Вход 3 устр. захвата таймера 1
12–13 2 00 Port 0.22
01 AD1.7 Вход 7 АЦП 1
10 CAP0.0 (Timer 0) Вход 0 устр. захвата таймера 0
11 MAT0.0 (Timer 0) Выход 0 устр. совпадения таймера 0
14–15 58 00 Port 0.23
01 Vbus Вход обнаружения питания USB
10,11 —
16–17 — — —
18–19 9 00 Port 0.25
01 AD0.4 Вход 4 АЦП 0
10 Aout (DAC) Выход ЦАП
11 —
20–23 — — —
24–25 13 00 Port 0.28
01 AD0.1 Вход 1 АЦП 0
10 CAP0.2 (Timer 0) Вход 2 устр. захвата таймера 0
11 MAT0.2 (Timer 0) Выход 2 устр. совпадения таймера 0
36
Таблица 1.9.4 – Продолжение
Биты Конт. Код Функция Описание
26–27 14 00 Port 0.29
01 AD0.2 Вход 2 АЦП 0
10 CAP0.3 (Timer 0) Вход 3 устр. захвата таймера 0
11 MAT0.3 (Timer 0) Выход 3 устр. совпадения таймера 0
28–29 15 00 Port 0.30
01 AD0.3 Вход 3 АЦП 0
10 EINT3 Вход 3 внешнего прерывания
11 CAP0.0 (Timer 0) Вход 0 устр. захвата таймера 0
30–31 17 00 Port 0.31 Только выход
01 UP_LED (USB) Выход индикатора связи через USB
10 CONNECT (USB) Вых. программного подключения USB
11 —
38
Пример 3. Вывод одного бита в порт. Команда
IO0PIN=(IO0PIN & 0xFFFFFFBF) | Bit << 6;
дает результат
.
Имеется в виду, что переменная Bit принимает только два значения: 0 или 1,
содержащееся в младшем разряде B.
Пример 4. Вывод произвольного бита переменной в порт. Команда
IO0PIN=(IO0PIN & 0xFFFFFFFD) | (Word & 0x1000) >> 11;
скопирует 12-ый разряд переменной Word в 1-ый разряд порта:
.
Фактически логика управления портом через регистры IOxPIN,
IOxSET, IOxCLR соответствует работе D-триггера, включенного так, как по-
казано на рисунке 1.10.2, а).
Чтение регистра IOxPIN дает двоичный код, соответствующий логи-
ческим уровням на контактах микроконтроллера (причем независимо от того,
настроены они на ввод или на вывод). Выборочное считывание одного или
нескольких бит выполняется с помощью логического умножения на маску.
Пример 5. Чтение состояния одной портовой линии
Bit=IO0PIN & 0x00000040;
дает результат
,
где бит равен 0 или 1 в зависимости от электрических уровнях на линии.
Пример 6. Чтение байта из порта
Byte=IO0PIN & 0x0000FF00;
дает результат:
,
где x — нули или единицы в зависимости от электрических уровней.
IOxSET.x S Q Px.x FIOxSET.x S Q Px.x
T FIOxMASK.x T
&
IOxPIN.x D D
FIOxPIN.x
IOxCLR.x R FIOxCLR.x R
а) б)
Рисунок 1.10.2 – Структурная схема выхода портовой линии:
а) в низкоскоростном режиме, б) в высокоскоростном режиме
Перечислим регистры управления портами в низкоскоростном режиме.
Регистр IOxDIR (IO0DIR, IO1DIR) устанавливает режим ввода или
вывода через порт. Единица в разряде IOxDIR переводит соответствующую
линию порта в режим цифрового выхода, ноль соответствует режиму входа.
Регистры IOxPIN (IO0PIN, IO1PIN) управляют электрическими
уровнями на портовых линиях, а также используются для чтения уровней,
действующих на линиях. Запись числа в эти регистры приводит к установке
уровней, советующих двоичному коду числа. Чтение регистров дает код, со-
ответствующий логическим уровням на портовых линиях.
39
Регистр IOxSET (IO0SET, IO1SET). Запись числа в эти регистры
приводит к установке высоких логических уровней на выходных линиях, со-
ответствующих двоичным единицам в IOxSET. Портовые линии, соответ-
ствующие логическим нулям не меняют состояния.
Регистр IOxCLR (IO0CLR, IO1CLR). Запись числа в эти регистры
приводит к установке низких логических уровней на выходных линиях, соот-
ветствующих двоичным единицам в IOxCLR. Портовые линии, соответству-
ющие логическим нулям не меняют состояния.
1.10.2 Управление портом через высокоскоростную шину
Высокоскоростной режим включается установкой единиц в нулевом и
первом разряде регистра SCS (рисунок 1.10.3). Нулевой разряд отвечает за
режим порта 0, первый — за режим порта 1.
SCS – режим управления цифровыми портами ввода-вывода
15 8 7 4 3 2 1 0
1M
0M
O
O
PI
PI
G
G
Порт 1 Порт 0
FIOxPIN
15 0 15 0
FIOxPINU FIOxPINL
7 0 7 0 7 0 7 0
41
Событие, требующее немедленной реакции и программной обработки,
называется прерывающим событием. Возникновение такого события сопро-
вождается специальным сигналом — запросом прерывания. Устройство, ге-
нерирующее этот сигнал, будем называть источником прерывания.
Упрощенно процесс обработки прерывания можно описать так:
а) источник прерывания формирует запрос прерывания;
б) система прерываний приостанавливает выполнение основной про-
граммы и передает управление процедуре обработки прерывания;
в) после завершения процедуры обработки прерывания управление
возвращается в основную программу.
Перечисленные действия могут быть организованы алгоритмически
(программным путем) без использования специальных аппаратных средств.
Однако для этого потребуется периодически опрашивать потенциальные ис-
точники прерываний в ожидании появления запросов. Программный опрос
приведет к усложнению алгоритма и неизбежным запаздываниям в реакциях
на прерывающие события. В то время как система прерываний обеспечит не-
прерывное слежение за всеми источниками и в случае появления запроса за-
пустит процедуру обработки прерывания с минимальной задержкой.
Архитектура ARM7 поддерживает три вида прерываний: векторное
IRQ, невекторное IRQ и быстрое FIQ. Одновременно поддерживается обра-
ботка не более 16 источников векторных прерываний, каждому из которых
может быть назначен произвольный адрес обработчика. Если необходимо
обеспечить поддержку более 16 источников прерываний, то используют не-
векторные прерывания с общим адресом обработчика. Процесс реакции на
векторные и невекторные прерывания один и тот же. Быстрое прерывание
FIQ имеет приоритет выше, чем IRQ и может прерывать обработку IRQ.
Предусмотрен только один обработчик всех запросов FIQ с единственным
адресом. Запрос от каждого источника может быть классифицирован как IRQ
или FIQ через регистр VICIntSelect (раздел 1.11.4).
1.11.2 Процесс обработки прерываний IRQ
Прерывания IRQ и FIQ являются частным случаем исключительных
ситуаций. Процесс обработки прерывания подчинен общему порядку для ис-
ключений, рассмотренному в разделе 1.6.
При возникновении прерывания, классифицированного как IRQ, вы-
полняются следующие действия:
1) содержимое счетчика команд , указывающее на следующую
команду, сохраняется в R14_irq (LR);
2) слово состояния программы CPSR сохраняется в SPSR_irq;
3) режим меняется на IRQ;
4) бит I в слове состояния программы CPSR устанавливается в едини-
цу, что запрещает все прерывания IRQ;
5) регистр VICVectAddr загружается адресом процедуры обработки
прерывания из регистра VICVectAddr0–15, где 0–15 — номер слота, c кото-
рым связан данный источник прерывания;
42
6) в счетчик команд R15 (PC) записывается адрес 0x00000018, что
приводит к немедленной передаче управления по этому адресу;
7) выполняется инструкция
LDR PC, [PC, #-0x0FF0]
расположенная по адресу 0x00000018, что приводит к записи в счетчик ко-
манд содержимого регистра VICVectAddr с адресом
;
8) управление получает процедура обработки прерываний, адрес ко-
торой был задан в регистре VICVectAddr.
Процедура обработки прерываний начинается с команды STM, сохра-
няющей в стек все используемые регистры общего назначения (R0–R12).
1.11.3 Процесс обработки быстрых прерываний FIQ
При возникновении прерывания, классифицированного как FIQ, вы-
полняются следующие действия:
1) счетчик команд , сохраняется в R14_fiq (LR);
2) слово состояния программы CPSR сохраняется в SPSR_fiq;
3) режим меняется на FIQ;
4) биты I, F в слове состояния программы CPSR устанавливается в
единицу, что запрещает все прерывания IRQ и FIQ;
5) управление передается команде по адресу 0x0000001С путем запи-
си этой константы в счетчик команд R15 (PC);
6) выполняется инструкция
LDR PC, [PC, #Смещение]
что приводит к загрузке в счетчик команд адреса обработчика быстрого пре-
рывания;
7) управление получает процедура обработки быстрого прерывания.
1.11.4 Регистры управления системой прерываний
Большинство регистров, предназначенных для управления системой
прерываний или слежения за ее состоянием, имеют структуру, схематично
показанную на рисунке 1.11.1. Каждый бит регистра соответствует одному из
источников прерываний.
Регистр VICRAWStatus. Единица в любом из разрядов информирует
о получении запроса прерывания от соответствующего источника, причем
независимо от того разрешено ли прерывание (см. также VICIntEnable).
Регистр VICIRQStatus. То же, что VICRAWStatus, но единицами от-
мечаются только источники, прерывания от которых разрешены и классифи-
цированы как IRQ (см. также VICIntSelect).
Регистр VICFIQStatus. То же, что VICIRQStatus, но для прерываний,
классифицированных как FIQ.
Регистр VICIntEnable. Установка единицы в любой из разрядов раз-
решает обработку запросов прерывания от соответствующего источника.
Сброс в ноль не имеет значения. Запрет обработки прерываний осуществля-
ется через регистр VICIntEnClear.
43
Регистр VICIntEnClear. Установка единицы в любой из разрядов за-
прещает обработку запросов прерывания от соответствующего источника.
Регистр VICIntSelect. Сброс в ноль любого из разрядов классифици-
рует соответствующий источник как IRQ. Адрес обработчика прерывания
должен храниться в одном из регистров VICVectAddr0–15 в зависимости от
слота, назначенного данному источнику. Установка единицы классифициру-
ет соответствующий источник как FIQ. Тогда адрес обработчика прерывания
задается инструкцией по вектору 0x0000001C.
Регистр VICSoftInt. Установка единицы в любой из разрядов вызы-
вает обработку прерывания от соответствующего обработчика программным
путем. Прерывание будет возникать циклически, пока данный регистр со-
держит единицы в разрядах, соответствующих разрешенным прерываниям.
Регистр VICSoftIntClear. Установка единицы в любой из разрядов
снимает программный запрос прерывания, выполненный через VICSoftInt.
Регистры VICVectCntl0–15 предназначены для того, чтобы распре-
делить используемые источники прерываний по 16 слотам. Структура реги-
стра показана на рисунке 1.11.1.
● Бит 5 (SlotEN) должен быть установлен в единицу.
● Биты 0–4 (IntRequest) назначают данному слоту номер источника
прерывания. Номера источников прерываний соответствуют номерам битов
IntRequest
otE
Sl
T2
D
1
SB
0
C
AD
AD
BO
N
I2
U
EI
EI
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
C RM
C RM
SS PI1
T1
T0
0
0
T1
T0
T
I0
0
TC
er
er
M
L
e1
e0
D
C
AR
AR
P
PL
N
SP
S
A
PW
W
I2
R
or
or
EI
EI
Ti
Ti
U
44
на рисунке 1.11.1. Назначать один и тот же источник прерывания нескольким
слотам не рекомендуется, хотя практически это возможно и допустимо. Если
такое произошло, то использоваться будет слот с меньшим номером.
Регистры VICVectAddr0–15 задают адрес обработчика прерывания
для каждого слота.
Регистр VICVectAddr автоматически загружается адресом обработ-
чика из VICVectAddr0–15 при запросе прерывания. Содержимое регистра ис-
пользуется командой LDR по адресу 0x00000018 для передачи управления об-
работчику прерывания.
Регистр VICDefVectAddr — адрес обработчика невекторных преры-
ваний. Если прерывание разрешено через VICIntEnable, не классифицировано
как FIQ через VICIntSelect, но не ассоциировано ни с одним из 16 слотов че-
рез VICVectCntl0–15, оно считается невекторным. В этом случае управление
будет передано по адресу, записанному в VICDefVectAddr. Невекторные
прерывания используют, если все слоты заняты. При обработке невекторного
прерывания его источник идентифицируется через регистр VICIRQStatus.
Регистр VICProtection содержит единственный управляющий бит
(рисунок 1.11.1). Установка единицы разрешает управление прерываниями
только в привилегированных режимах. В режиме User управление прерыва-
ниями становится запрещено.
1.11.5 Порядок настройки прерывания IRQ
В ходе настройки системы прерываний рекомендуется придерживать-
ся следующего порядка действий.
1. Принять решение о том, какой из свободных слотов (0–15) будет
использоваться для данного источника прерывания.
2. Записать адрес обработчика прерывания в регистр VICVectAddr0–
15, соответствующий выбранному слоту, например для слота 0
VICVectAddr0 = (unsigned) Имя процедуры-обработчика ;
3. Назначить выбранному слоту источник прерывания
VICVectCntl0 = 0x20 | Номер источника ;
Под номером понимается десятичное число (номер источника или номер раз-
ряда на рисунке 1.11.1).
4. Настройка по пунктам 1–3 повторяется для каждого источника.
5. Включить прерывание от данного источника
VICIntEnable = Маска источника ;
Под маской понимается двоичный код с единицами в разрядах, соответству-
ющих разрешенным прерываниям (рисунок 1.11.1).
Отметим, что каждому из регистров может быть
поставлен в соответствие единственный источник прерывания, поэтому ука-
зывается его номер. В то же время через могут быть разрешены
несколько прерываний, поэтому каждому из них соответствует один бит.
Порядок настройки невекторного прерывания IRQ:
1. Аналогично пункту 2 для векторного прерывания поместить адрес
обработчика в регистр VICDefVectAddr.
45
2. Аналогично пункту 5 для векторного прерывания разрешить обра-
ботку прерывания от данного источника через регистр VICIntEnable.
1.11.6 Порядок настройки быстрого прерывания FIQ
1. Классифицировать прерывание от данного источника, как быстрое
прерывание FIQ. Установить единицу в разряд регистра VICIntSelect, соот-
ветствующий данному источнику
VICIntEnable = Маска источника ;
2. Включить прерывание от данного источника
VICIntEnable = Номер источника ;
3. Внести изменения в код инициализации Startup.s. Заменить строку
FIQ_Handler B FIQ_Handler
на
IMPORT FIQ_Handler
В дальнейшем использовать имя FIQ_Handler для процедуры-обработчика
прерывания. Заголовок процедуры-обработчика должен быть таким:
irq void FIQ_Handler ()
Имя подпрограммы может быть произвольным, но должно совпадать c име-
нем после директивы IMPORT.
1.11.7 Процедура обработки прерывания
Процедура обработки прерывания на языке Си, ориентированном на
использование компилятора RealView 4 создается по шаблону:
irq void Имя_функции()
{
...
Регистр = Код ; // Сброс флага запроса прерывания
VICVectAddr=0;
}
Строка «Сброс флага запроса прерывания» обращается к регистру
управления периферийным устройством, вызвавшим прерывание. Например,
для таймера 0 это
T0IR=1;
Если сброс флага не произвести, запрос прерывания останется активным и
обработка прерывания начнет повторяться циклически.
1.11.8 Задержка обработки прерывания
В микроконтроллерах семейства LPC21xx задержка при передаче
управления обработчику прерывания сравнительно велика. Минимальное
время от появления запроса прерывания до выполнения первой команды об-
работчика составляет 12 тактов для FIQ и 13 тактов для IRQ. Максимальное
время реакции на запрос на 20 тактов больше минимального. Дополнитель-
ные 20 тактов определяются временем, необходимым для завершения коман-
ды, с выполнением которой совпал запрос прерывания, такой как
46
LDMFA R0, {R0-R15}
Выполнение первой эффективной команды будет отложено еще на не-
сколько тактов, необходимых для сохранения в стек регистров общего назна-
чения такой командой, как
STMDB R13!, { ... }
Затраты времени на сохранение регистров зависят от их числа. На 13 реги-
стров R0–R13 уходит 14 тактов.
Таким образом, задержка обработки прерывания IRQ может варьиро-
вать от 13 до тактов; для FIQ задержка варьирует от 12 до
46 тактов.
В качестве подтверждения приведем результат простого эксперимен-
та. На вход запроса прерывания EINT3 поступают периодические импульсы
от генератора. Обработчик прерывания по внешнему сигналу в ответ форми-
рует короткий одиночный импульс. Интервал времени между фронтами им-
пульсов от генератора и ответного, формируемого микроконтроллером, соот-
ветствует задержке обработки прерывания.
Листинг программы приведен в приложении А. Отметим, что тактовая
частота микроконтроллера равна 12 МГц, умножитель отсутствует, обраще-
ние к портам выполняется через высокоскоростную шину.
На рисунке 1.11.2 приведено семейство осциллограмм, записанных
многократно в случайные моменты времени. Жирным пунктиром выделены
импульсы, соответствующие самой короткой и самой длинной задержкам.
Задержка в 21 такт для IRQ складывается из тринадцати базовых,
трех, затраченных на сохранение регистров R0–R1 и пяти на вывод в порт.
47
Вместе с тем можно предположить, что команда LDM, выполняемая до
20 тактов не встречается в программе, а самая «медленная» команда в про-
грамме выполняется 3 такта; команда STM сохраняет не все регистры и вы-
полняется 4–7 тактов. Основываясь на этих предположениях, можно считать,
что задержка от появления запроса IRQ до первой эффективной команды об-
работчика ориентировочно составляет от до так-
тов. Для FIQ задержка на 1 такт меньше.
Время реакции на прерывание FIQ можно существенно уменьшить,
приняв следующие меры:
а) В процедуре обработки прерывания использовать только регистры
R8–R12, отдельные для режима FIQ. Это даст возможность не сохранять и не
восстанавливать их командами LDM, STM.
б) Не оформлять обработчик быстрого прерывания как процедуру, а
размещать его команды, начиная с адреса 0x0000001С. Этот адрес последний
в таблице векторов исключительных ситуаций, поэтому все последующие
адреса свободны.
Компилятор RealView не содержит необходимых для этого средств,
поэтому потребуется для случая а) обработчик прерывания создавать с ис-
пользованием ассемблера (директива asm), а для случая б) включать код
обработчика прерывания непосредственно в стартовый код Startup.s.
48
EXTINT – флаги запроса внешних прерываний
15 8 7 4 3 2 1 0
T3 T2 T1 T0
N N N N
EI EI EI EI
Флаги прерываний
Полярность/выбор фронта
49
4. Если необходимо, разрешить «пробуждение» микроконтроллера по
запросу внешнего прерывания через регистр INTWAKE. Если режим отклю-
чения питания не используется, то настройка не производится.
5. Разрешить внешнее прерывание через регистры VICVectAddr0–15,
VICVectCntl0–15 и VICIntEnable.
Процедура обработки прерывания должна содержать команду сброса
флага путем записи единицы в соответствующий разряд регистра EXTINT.
1.13 Таймеры-счетчики
Таймеры-счетчики применяются для формирования и измерения ин-
тервалов времени или для подсчета числа внешних импульсов. Таймер-
счетчик представляет собой программируемый суммирующий счетчик с воз-
можностью выбора источника счетных импульсов. Микроконтроллер
LPC2148 оснащен двумя абсолютно идентичными по функциональным воз-
можностям 32-разрядными таймерами-счетчиками. Содержимое таймеров-
счетчиков доступно для чтения и записи через регистры TC0 и TC1.
1.13.1 Режим таймера и схема совпадения
В зависимости от источника счетных импульсов различают режим
таймера или счетчика. В режиме таймера ведется счет внутренних тактовых
импульсов микроконтроллера . При максимальной тактовой частоте
60 МГц разрядность позволяет продолжать счет без переполнения в течение
с. Формирования или измерение бóльших интервалов
времени возможно с использованием 32-разрядных предварительных счетчи-
ков-делителей c произвольным модулем счета в пределах разрядности (реги-
стры TxPC). Каскадное соединение таймера и предварительного делителя
практически бесконечно расширяет диапазон временных интервалов. При
тактовой частоте 60 МГц переполнение произойдет почти через 10 тысяч лет.
Временные интервалы формируются схемой совпадения, которая
сравнивает содержимое таймера с пороговыми регистрами TxMR0–TxMR3.
В момент равенства возможно выполнение следующих действий: сброс тай-
мера в ноль, остановка таймера, запрос прерывания, изменение логического
уровня на портовой линии. Четыре схемы совпадения позволяют выполнять
разные действия при достижении таймером каждого из четырех пороговых
значений.
Длительность временного интервала при увеличении таймера от 0 до
TxMRx без предварительно делителя ( ) составляет
. (1.13.1)
С предварительным делителем ( )
. (1.13.2)
Следовательно, значение порогового регистра, обеспечивающего за-
держку (без предварительного делителя) определяется выражением
. (1.13.3)
50
Здесь — ближайшее к целое, не превосходящее , а —
округленная до ближайшего целого величина .
1.13.2 Режим счетчика
В режиме счетчика подсчитываются импульсы напряжения, поступа-
ющие на портовые линии CAPx.0–CAPx.3. Максимальная частота на счетном
входе составляет 30 МГц.
1.13.3 Схема захвата
Схема захвата позволяет «запомнить» в регистрах TxCR0–TxCR3 те-
кущее состояние таймера-счетчика в момент появления сигнала на входных
портовых линиях CAPx.0–CAPx.3. Захват состояния осуществляется с мини-
мально возможной временной задержкой в один машинный цикл.
1.13.4 Управляющие регистры
Схема регистров управления таймерами-счетчиками приведена на ри-
сунке 1.13.1.
Регистры TxIR (T0TCR, T1TCR) содержат флаги прерываний от
схем совпадения и захвата. Установленный флаг должен сбрасываться в про-
цедуре обработки прерывания путем записи единицы в соответствующий
разряд. Запись нуля не оказывает влияния.
● Биты 0–3 (MR0I–MR3I) — флаги прерываний от выходов схемы
совпадения MAT0–MAT3.
● Биты 4–7 (CR0I–CR3I) — флаги прерываний от выходов схемы за-
хвата CAP0–CAP3. Регистры TxTCR (T0TCR, T1TCR) предназначены для
запуска и сброса таймеров-счетчиков МК. Каждый из них содержит только
два управляющих бита.
● Бит 0 (ENABLE). Установка единицы разрешает счет, сброс в ноль
запрещает счет.
● Бит 1 (RESET). Установка единицы приводит к сбросу таймера-
счетчика в ноль. Счет будет продолжен после сброса бита RESET в ноль.
Регистры TxCTCR (T0CTCR, T1CTCR) предназначены для
настройки режимов работы встроенных таймеров-счетчиков.
● Биты 0–1 (MODE). Отвечают за выбор режима работы таймера-
счетчика (таблица 1.13.1).
● Биты 2–3 (InputSelect). Отвечают за выбор линии CAPx.0–CAPx.3,
которая служит счетным входом или входом захвата. Номер линии (0–3) сов-
падает с двоичным кодом в InputSelect (00–11). Значение этих битов не важно
в режиме таймера ( ), когда внешние сигналы не используются.
Таблица 1.13.1 – Режимы работы таймеров-счетчиков МК LPC2148
MODE Режим таймера-счетчика
00 Режим таймера. Инкремент по фронту внутреннего сигнала PCLK
01 Режим счетчика. Инкремент по фронту внешнего сигнала CAP.
10 Режим счетчика. Инкремент по срезу внешнего сигнала CAP.
11 Режим счетчика. Инкремент по фронту и срезу сигнала CAP.
51
TxTCR – настройка таймеров-счетчиков
15 11 8 7 2 1 0
ET
ES EN
R
ВКЛ
Сброс
3 2 1 Сброс
Прерывание
Остановка
TxCCR – настройка схемы захвата
15 12 11 10 9 8 7 6 5 4 3 2 1 0
3 3 3 2 2 2 1 1 1 0 0 0
AP AP AP AP AP AP AP AP AP AP AP AP
C I C FE C RE C I C FE C RE C I C FE C RE C I C FE C RE
3 2 1 Срез
Фронт
Прерывание
TxEMR – настройка сигналов совпадения
15 12 11 10 9 8 7 6 5 4 3 2 1 0
52
● Биты 0–11 (MR0I–MR3I, MR0R–MR3R, MR0S–MR3S) задают реак-
ции на совпадение таймера с каждым из пороговых регистров TxMR0–
TxMR3 (см. таблицу 1.13.2).
Таблица 1.13.2 – Реакции на совпадение таймера-счетчика с TxMR0–TxMR3
Управляющие биты Назначение
MR0I–MR3I Разрешить/запретить запрос прерывания
MR0R–MR3R Разрешить/запретить сброс таймера-счетчика в ноль
MR0S–MR3S Разрешить/запретить остановку счета
Регистры TxCRx (T0CR0–T0CR3, T1CR0–T1CR3) содержат состоя-
ния таймеров счетчиков, захваченные при событии CAP0–CAP3.
Регистры TxCCR (T0CCR, T1CCR) — настройка схемы захвата.
● Биты 0–3 (CAP0RE–CAP3RE, CAP0FE–CAP3FE, CAP0I–CAP3I) за-
дают событие, на которое реагирует каждая из четырех схем захвата, а также
указывают на необходимость прерывания по захвату (таблица 1.13.3).
Таблица 1.13.3 – Реакции на сигнал захвата CAPx.0–CAPx.3
Управляющие биты Назначение
CAP0RE–CAP3RE Захват по фронту сигнала CAPx.0–CAPx.3
CAP0FE–CAP3FE Захват по срезу сигнала CAPx.0–CAPx.3
CAP0I–CAP3I Запрос прерывания по событию захвата
Регистры TxEMR (T0EMR, T1EMR).
● Биты 0–3 (EM0–3) отражают состояние логических уровней на вы-
ходах MATx.0–MATx.3
● Биты 4–5 (EMC0–EMC3). Биты управляют формированием внешне-
го сигнала по совпадению таймера-счетчика с каждым из пороговых реги-
стров TxMR0–TxMR3 (в соответствии с таблицей 1.13.4).
Таблица 1.13.4 – Способы формирования внешнего сигнала совпадения
ECx Реакция на совпадение
00 Не изменять внешний сигнал MATx.0
01 Установить на выходе MATx.0 сигнал «логический ноль»
10 Установить на выходе MATx.0 сигнал «логическая единица»
11 Инвертировать сигнал на выходе MATx.0
1.13.5 Формирование интервалов времени через систему прерываний
Чаще всего формирование временного интервала осуществляется с
помощью процедуры обработки прерывания, вызываемой схемой совпаде-
ния. При этом рекомендуется придерживаться следующего порядка настрой-
ки аппаратуры микроконтроллера.
1. Настроить работу схемы совпадения через регистр TxMCR. Обычно
требуется включить сброс счетчика и запрос прерывания по совпадению с
одним из пороговых регистров, например, TxMR0. Для этого достаточно уста-
новить единицы в битах MR0R, MR0I регистра TxMСR. Запрос прерывания
необходимо разрешить, даже если предполагается программный опрос флага.
53
2. Задать значение выбранного порогового регистра TxMR0–TxMR3.
Расчет выполнить в соответствии с формулой (1.13.3).
3. Выбрать режим таймера в регистре TxCTCR. Если настройка про-
изводится после сброса, этот пункт можно опустить, поскольку при сбросе
регистр TxCTCR получит нулевое значение.
4. Разрешить счет путем записи единицы в регистр TxTCR.
Остановка счета осуществляется путем записи нуля в TxTCR. Если
требуется при этом сбросить таймер в ноль, то следует записать единицы в
нулевой и первый бит, то есть число 3.
Проверка окончания временного интервала выполняется путем опроса
флага либо с помощью прерывания.
Если разрешен запрос прерывания (регистр TxMCR), то окончание
временного интервала (совпадение TxMCR и TxMRx) будет сопровождаться
установкой бита, соответствующего пороговому регистру, в регистре TxIR.
Для программного опроса флага требуется внедрить в программу команды
проверки условия и ветвления.
Чаще вместо программного опроса флага используют прерывание от
схемы совпадения. Для этого необходимо разрешить прерывание с помощью
регистров VICVectAddr0, VICVectCntl0 и VICIntEnable (раздел 1.11.4). В
конце процедуры обработки прерывания сбросить флаг прерывания путем
записи единицы в соответствующий разряд регистра TxIR.
1.13.6 Измерение периода и длительности импульса с помощью
устройства захвата
Измеряемый временной интервал может быть определен как разность
двух значений таймера, захваченных в моменты начала и конца временного
интервала. Для настройки таймера и схемы захвата предлагается придержи-
ваться следующего порядка действий.
1. Перевести выбранную портовую линию в режим CAP путем записи
в регистры PINSEL0, PINSEL1 (таблицы 1.9.3, 1.9.4).
2. Настроить схему захвата через регистр TxCCR. При измерении дли-
тельности импульса необходимо включить реакцию на оба фронта; при из-
мерении периода — на передний или задний фронт. Рекомендуется также
разрешить прерывание.
3. Включить таймер путем записи единицы в регистр TxTCR.
4. Разрешить обработку прерывания по захвату с помощью регистров
VICVectAddr0–15, VICVectCntl0–15 и VICIntEnable (раздел 1.11.4).
5. В процедуре обработки прерывания требуется сохранить захвачен-
ное значение таймера, находящееся в одном из регистров захвата TxCC0–
TxCC3. Необходимо также хранить и предыдущее значение этого регистра.
6. Определить длительность измеряемого интервала времени по раз-
ности текущего ( ) и предыдущего ( ) значения регистра захвата
. (1.13.4)
54
Такой алгоритм необходим, если окончание одного временного ин-
тервала совпадает с началом следующего. С таким случаем имеем дело при
измерении периода прямоугольного сигнала, как интервала времени между
нарастающими или спадающими фронтами импульсов.
При измерении длительности импульса можно подключить сигнал
сразу к двум входам захвата и настроить реакцию одного из них (например,
CAP0.0) на нарастающий фронт, а другого — на спадающий (например,
CAP0.1). Прерывание разрешить только по спадающему фронту. Тогда нет
необходимости сохранять в памяти значения регистров захвата. Можно
определить длительность через разность текущих значений CAP0.1 и CAP0.0.
1.13.7 Подсчет числа импульсов в единицу времени
Для реализации частотомера потребуется два таймера-счетчика. Один
используется для формирования интервала счета (например, 1 с), другой
служит счетчиком внешних импульсов. Для определенности будем считать,
что TC0 — таймер, а TC1 — счетчик.
Тогда необходимо использовать один из выходов MAT0 (таймера-
счетчика 0), сигнализирующий об окончании интервала счета, в качестве
сигнала захвата CAP1 (таймера-счетчика 1). Потребуется внешнее электриче-
ское соединение соответствующих портовых линий MAT0 и CAP1.
Порядок настройки изложен ниже.
1. Перевести одну портовую линию в режим MAT0.x, и две в режим
CAP1.x и CAP2.x.
2. Через регистр T0MCR включить сброс таймера по совпадению.
3. Через регистр T0EMR включить инверсию выбранного выхода
MAT0.x.
4. Задать длительность формируемого интервала счета установкой по-
рогового регистра T0MRx. Опираться на формулу (1.13.3).
5. Запустить таймер через T0TCR.
6. Задать режим счетчика с инкрементом по одному из фронтов, вы-
брать счетный вход для TC1 через регистр T1CTCR.
7. В регистре T1CCR включить захват TC1 по обоим фронтам сигнала
на входе CAP1.x, соединенным с сигналом совпадения MAT0.x.
8. Разрешить счет через регистр T1TCR.
9. Разрешить прерывание от таймера 1 с помощью регистров
VICVectAddr0–15, VICVectCntl0–15 и VICIntEnable.
55
1.14.1 Основы функционирования
Упрощенная функциональная схема ШИМ показана на рисунке 1.14.1.
Основу модуля ШИМ составляет счетчик PWMTC (на схеме не показан),
семь пороговых регистров PWMMR0–PWMMR6 (также не показаны), набор
схем совпадения и D-триггеров, связанных с выходными портовыми линиями
МК PWM0–PWM6. Счетчик PWMTC инкрементируется в каждом такте .
PWMTC A ==
Y
PWMMR0 B
S Q PWM1
T
A ==
Y R
PWMMR1 B
D1 MX
D0 Y S Q PWM2
T
MWMSEL2 A
A ==
Y R
PWMMR2 B
D1 MX
D0 Y S Q PWM3
T
MWMSEL3 A
A ==
Y R
PWMMR3 B
D1 MX
D0 Y S Q PWM4
T
MWMSEL4 A
A ==
Y R
PWMMR4 B
D1 MX
D0 Y S Q PWM5
T
MWMSEL5 A
A
==
Y R
PWMMR5 B
D1 MX
D0 Y S Q PWM6
T
MWMSEL6 A
A
==
Y R
PWMMR6 B
57
Рисунок 1.14.3 – Временные диаграммы работы ШИМ
в режиме управления начальной фазой (PWMSEL2–6 = 1)
Начальная фаза
. (1.14.4)
Длительность импульса
. (1.14.5)
58
явлению нового импульса. Если в этот момент увеличить частоту путем за-
писи в PWMMR0, например, числа 900, то PWMTC окажется больше
PWMMR0. Формирование нового импульса не произойдет до тех пор, пока
PWMTC не достигнет максимального значения , сбросится в ноль и
затем достигнет значения 800, что займет более 70 секунд. На это время ра-
бота ШИМ будет заблокирована.
Для предотвращения такого сбоя при изменении пороговых регистров
имеется система регистров-защелок. При этом сравнение счетчика осуществ-
ляется не с пороговыми регистрами, а с регистрами защелками, которые об-
новляются одновременно и только в начале каждого периода ШИМ. Подроб-
ней см. ниже (регистр PWMLER в разделе 1.14.3 и раздел 1.14.4).
1.14.3 Регистры управления ШИМ
Схема управляющих регистров показана на рисунке 1.14.4.
Регистры PWMTC, PWMPC — счетчик ШИМ и предварительный
делитель счетчика (соответственно). Как правило, ни в чтении, ни в записи
этого регистра необходимости не возникает.
Регистр PWMPR — регистр порогового значения для предваритель-
ного делителя, фактически, коэффициент деления частоты .
Регистр PWMTCR служит для управления счетчиком ШИМ.
● Бит 0 (CNTEN). Бит включения счетчика ШИМ. Для работы ШИМ
должен быть установлен в единицу.
● Бит 1 (RESET). Установка единицы приводит к сбросу счетчика
ШИМ. Счет блокируется, если бит равен единице.
● Бит 3 (PWMEN). Включение синхронного режима. В данном режи-
ме при изменении пороговых регистров (PWMMR0–PWMMR6) их содержи-
мое будет обновлено только в начале следующего периода. Изменение раз-
решается через регистр PWMLER (см. ниже).
Внимание! Запись в пороговый регистр PWMMR0 должна предше-
ствовать установке данного бита.
Регистр PWMMCR
● Биты 0–2 (MR0I–MR6I, MR0R–MR6К, MR0S–MR6S) задают реак-
цию на совпадение счетчика с каждым из пороговых регистров PWMMR0–
PWMMR6 (в соответствии с таблицей 1.14.1).
Регистр PWMPCR — управление начальной фазой.
● Биты 2–6 (PWMSEL2–6). Установка единицы в каждом разряде раз-
решает регулировку начальной фазы выходной линии ШИМ с тем же номе-
ром. На рисунке 1.14.1 выход Y соответствующего мультиплексора
59
PWMTCR – настройка счетчика ШИМ
15 8 7 4 3 2 1 0
M ET N
T
PW EN ES C
EN
R
ВКЛ
Вкл. защелки пороговых регистров Сброс
6 5 4
11 10 9 8 7 6 5 4 3 2 1 0
3S 3R 3I 2S 2R 2I 1S 1R 1I 0S 0R 0I
R R R R R R R R R R R R
M M M M M M M M M M M M
3 2 1 Сброс
Прерывание
Остановка
PWMPCR – настройка ШИМ
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
M M M M M M M M M M M
PW N6 PW N5 PW N4 PW N3 PW N2 PW N1 PW EL6 PW EL5 PW EL4 PW EL3 PW EL2
E E E E E E S S S S S
Включение каналов Вкл. управление начальной фазой
60
1.14.4 Порядок настройки ШИМ
1. Задать режим PWM для портовых линий, которые послужат выхо-
дами ШИМ через регистры PINSEL0, PINSEL1 (раздел 1.9.3).
2. Задать частоту импульсов путем записи в регистр PWMMR0 значе-
ния, рассчитанного по формуле (1.14.1) или (1.14.7).
3. Задать длительности импульсов и (или) начальные фазы с помощью
регистров PWMMR1–6. Необходимо устанавливать значения только тех ре-
гистров, которые связаны с задействованными выходами ШИМ. Использо-
вать выражения (1.14.2) при нулевой начальной фазе, выражения (1.14.3–
1.14.5) при регулируемой начальной фазе.
4. Произвести настройку счетчика модуля ШИМ через регистр
PWMTCR. Необходимо установить бит включения счетчика; рекомендуется
разрешить работу защелок. Следовательно, типовым значением является
.
5. Включить необходимые выходы ШИМ и выбрать режим управле-
ния начальной фазой для каждого канала через регистр PWMPCR.
После того как настройка произведена, генерирование прямоугольных
импульсов с заданными параметрами будет продолжаться, не требуя никако-
го участия со стороны программы. Изменение параметров сигнала (частоты,
начальной фазы, скважности) возможно в любой точке программы путем
следующей последовательности действий:
а) запись новых значений в регистры PWMMR0–6;
б) установка битов разрешения обновления защелок в регистре PWM-
LER. Запись единиц должна производиться одной командой.
Сброс регистра PWMLER в ноль выполняется автоматически.
Остановка ШИМ возможна путем сброса бита CNTEN в регистре
PWMTCR. Рекомендуется той же командой сбросить таймер установкой бита
RESET в том же регистре.
В разделе 3.6 приведены выражения для расчета пороговых значений,
позволяющие организовать ШИМ, частотное и фазовое управление.
61
Таблица 1.15.1 – Основные параметры АЦП МК LPC2148
Разрядность, бит 3–10
Мин. время преобразования при разрядности 10 бит, мкс 2,44
Макс. производительность при разрядности 10 бит, преобр./с 409 090
Мин. время преобразования при разрядности 3 бит, мкс 0,89
Макс. производительность при разрядности 3 бит, преобр./с 1 125 000
Число мультиплексируемых аналоговых входов (АЦП 0/1) 6/8
Диапазон измеряемого напряжения 0–3,3 В
Имеется рекомендация, в соответствии с которой для сохранения точ-
ности выходное сопротивление источника измеряемого напряжения не
должно превышать 40 кОм.
1.15.2 Общие рекомендации по использованию АЦП
Взаимодействие с аналого-цифровым преобразователем включает три
основных действия: запуск АЦП, ожидание готовности результата преобра-
зования, считывание и обработка результата. Существует несколько вариан-
тов алгоритмической реализации взаимодействия с аналого-цифровым пре-
образователем. Основное отличие состоит в способе запуска АЦП. Запуск
может осуществляться:
а) программным путем;
б) по совпадению счетчика с пороговым значением;
в) внешним электрическим сигналом;
г) окончанием предыдущего преобразования.
В таблице 1.15.2 дана краткая характеристика перечисленных спосо-
бов. Ниже будут рассмотрены все способы взаимодействия с АЦП, даны ре-
комендации по выбору каждого варианта, а также предложены шаблоны про-
граммного кода для их реализации.
Программный запуск АЦП реализуется командой, выполняемой при
наступлении некоторого события. Таким событием может быть нажатие
кнопки, получение команды от компьютера, истечение интервала времени и
т. п. Единственным преимуществом программного запуска является то, что
он не требует привлечения других ресурсов МК, таких как таймеры-
счетчики.
При решении большинства задач желательна строгая периодичность
запуска АЦП, а в некоторых случаях совершенно необходима. Могут быть
названы следующие причины. Во-первых, большинство методов цифровой
обработки сигналов разработаны для случая периодической дискретизации.
Для их применения необходимо, чтобы дискретные отсчеты напряжения бы-
ли получены через равные интервалы времени. Нарушение периодичности
неизбежно приведет к возникновению дополнительного шума квантования.
Во-вторых, одним из распространенных способов борьбы с некото-
рыми видами помех является синхронизация частоты квантования с частотой
измеряемого процесса или с частотой питающей сети.
62
Таблица 1.15.2 — Способы запуска АЦП в микроконтроллере LPC2148
Способ
Преимущества Недостатки Применение
запуска АЦП
Программный Не задействует ап- Непериодиче- Измерение посто-
паратных ская дискрети- янного или медлен-
узлов МК зация но меняющегося
напряжения с пери-
одом дискретиза-
ции от 0,1 с и выше
От таймера Периодическая дис- Задействован Широкий круг за-
кретизация; не тре- таймер дач цифровой обра-
бует участия про- ботки сигналов
граммы
Внешним Синхронизация Задействован Системы импульс-
сигналом внешним вывод МК; тре- но-фазового управ-
процессом бует источника ления, цифровая
синхросигнала обработка сигналов
Непрерывное Периодическая дис- Ограниченные Цифровая обработ-
преобразова- кретизация; не за- возможности ка сигналов с высо-
ние действует узлов выбора частоты кими частотами
МК; мин. задержки квантования квантования
между преобр.
Программный запуск АЦП практически не позволяет обеспечить
строгую периодичность запуска АЦП, а значит и периода дискретизации
сигнала. Причина заключается в том, что выполнение каждой итерации про-
граммы занимает различное время, например, из-за ветвлений с различным
числом команд в ветвях. Дополнительные временные задержки создают пре-
рывания от разных источников.
В связи с этим, программный запуск применять не рекомендуется.
Программный запуск допустим лишь в случаях, когда нет необходимости в
строгой периодичности дискретизации, например при измерении постоянно-
го или медленно меняющегося напряжения и притом, что нежелательно ис-
пользовать один из таймеров-счетчиков специально для формирования сиг-
нала запуска АЦП.
Отметим, что команда запуска АЦП, помещенная в процедуре обра-
ботки прерывания от таймера также не обеспечит строгой дискретизации.
Точнее обеспечит периодичность с некоторой погрешностью. Погрешность
возникает вследствие неизбежных временных задержек, которые имеют слу-
чайный характер (см. раздел 1.11.8).
Автоматический запуск при достижении таймером заданного по-
рогового значения. Этот способ можно назвать наиболее универсальным и
пригодным для решения большинства практических задач. Сигнал, формиру-
емый схемой совпадения таймера-счетчика, приведет к запуску без участия
программы. Запуск осуществляется строго периодически. Прерывание от
63
таймера при этом использовать не требуется. Это является еще одним пре-
имуществом — отсутствуют затраты процессорного времени на обработку
прерывания и команды запуска АЦП. Имеется единственный недостаток —
использование важного аппаратного ресурса — таймера-счетчика.
Считывание результата можно организовать путем программного опро-
са, либо с помощью прерывания от АЦП. Второй вариант предпочтителен.
Запуск внешним электрическим сигналом. Внешний пуск обеспе-
чивает синхронизацию процесса квантования с измеряемым процессом, что в
некоторых задачах совершенно необходимо, а в ряде других случаев, как
упоминалось выше, позволяет устранить некоторые составляющие случай-
ной погрешности. Использование одного из выводов МК, является несуще-
ственным недостатком. Существенную трудность составляет необходимость
построения аппаратной схемы синхронизации.
Непрерывная работа. В таком случае также обеспечивается строгая
периодичность, однако, доступна фиксированная сетка частот тактирования
АЦП и соответствующих частот квантования. При этом не предоставляется
возможность выбирать период квантования с шагом в один машинный цикл
МК. Доступный шаг гораздо больше. Следует отметить, что такой способ за-
пуска может гарантировать работу АЦП без простоев, то есть позволяет до-
биться наибольшей его производительности.
1.15.3 Управляющие регистры
Рассмотрим регистры, отвечающие за настройку аналого-цифровых
преобразователей (рисунок 1.15.1).
Регистры ADxCR
● Биты 0–7 (SEL) отвечают за выбор каналов АЦП. Каждому биту со-
ответствует канал с тем же номером AD0.0–AD0.7 (АЦП 0) или
AD1.0–AD1.7 (АЦП 1). Одновременная установка нескольких битов допус-
кается только в режиме автоматического сканирования каналов (см. ниже).
● Биты 8–15 (CLKDIV) служат для выбора тактовой частоты АЦП.
Тактовая частота определяется по формуле
, (1.15.1)
где — тактовая частота периферийных устройств, которая может быть
равна целой, половине или четверти тактовой частоты МК (раздел 1.7.2).
Значение не должно превышать 4,5 МГц.
● Бит 16 (BURST). Единица в данном разряде переводит АЦП в ре-
жим автоматического сканирования каналов. Производится поочередное
преобразование сигналов в каналах, выбранных битами SEL. В этом режиме
биты START (см. ниже) должны быть равны нулю.
● Биты 17–19 (CLKS) имеют значение только в режиме автоматиче-
ского сканирования каналов ( ). Эти биты определяют время пре-
образования и разрядность результата. Значению соответствует
время преобразования 11 тактов, разрядность 10 бит. С увеличением на еди-
ницу CLKCS, на единицу уменьшается время преобразования и разрядность.
64
ADxCR – настройка АЦП
31 28 27 26 24 23 22 21 20 19 17 16 15 8 7 0
E N ST
G START CLKS R CLKDIV SEL
ED PD BU
Способ запуска ВКЛ Число тактов Делитель частоты Выбор каналов АЦП ADx.7:0
Фронт/срез
в непр. режиме
Непрерывное преобразование
ADGSR – запуск всех АЦП
31 28 27 26 24 23 20 19 17 16 15 8 7 0
E ST
G START R
ED BU
Способ запуска
Фронт/срез
Непрерывное преобразование
ADxGDR – общий результат
31 30 29 28 27 26 24 23 16 15 8 7 6 5 0
-
E VE
N CHN RESULT
O O UN
D R
Готов Номер канала Результат аналого-цифрового преобразования
Потеря результата
ADxSTAT – состояние
31 24 23 20 19 17 16 15 8 7 0
T
IN OVERUN7:0 DONE7:0
AD
Потеря результата каналов ADx.7:0 Готовность результата каналов ADx.7:0
Флаг прерывания
ADxINTEN – управление прерыванием
31 24 23 16 15 12 11 9 8 7 0
-
G N
AD TE ADINTEN7:0
IN
Разрешение прерываний от каналов ADx.7:0
Разр. прер. от всех каналов
65
Таблица 1.15.3 – Режимы запуска АЦП
START Режим запуска АЦП
000 Преобразования не выполняются
001 Запустить преобразование немедленно
010 Запуск внешним сигналом на входе P0.16
011 Запуск внешним сигналом на входе P0.22
100 Запуск сигналом MAT0.1
101 Запуск сигналом MAT0.3
110 Запуск сигналом MAT1.0
111 Запуск сигналом MAT1.1
Значению соответствует время преобразования 4 такта, разряд-
ность 3 бита. При разрядность составляет 10 бит, преобразова-
ние занимает 11 тактов независимо от состояния CLKS.
Минимальное время преобразования определяется выражением
(мкс), (1.15.2)
где — разрядность АЦП.
● Бит 21 (PDN) включает (1) и отключает (0) АЦП. Должен быть
установлен в единицу.
● Биты 24–26 (START) служат для выбора способа запуска АЦП (таб-
лица 1.15.3). Эти биты должны быть равны нулю в режиме автоматического
сканирования каналов ( ).
Следует понимать принципиальное отличие запуска внешним сигна-
лом на входах P0.16 и P0.22 от запуска сигналами MATx.x, которые форми-
руются внутренней схемой совпадения встроенного таймера-счетчика и мо-
гут не быть подключенными к внешним выводам МК (раздел 1.13.1).
● Бит 27 (EDGE). Выбор нарастающего (0) или спадающего (1) фрон-
та сигнала запуска АЦП при .
Регистр ADGSR позволяет одновременно настроить запуск двух
АЦП. Значения битов BURST, START, EDGE абсолютно аналогичны реги-
страм ADxCR. Остальные биты должны задаваться отдельно для каждого
АЦП через регистр ADxCR.
Регистр ADxGDR. Результат аналого-цифрового преобразования счи-
тывается из регистров AD0GDR и AD1GDR (ADxGDR).
● Биты 6–15 (RESULT) содержат десятиразрядный результат аналого-
цифрового преобразования. Входное напряжение АЦП связано с результатом
АЦП и опорным напряжением, подключенным к входу Vref МК, выражением
. (1.15.3)
● Биты 24–26 (CHN) содержат двоичный номер канала АЦП от 0 (000)
до 7 (111), для которого получен результат, хранимый в разрядах RESULT.
● Бит 30 (OVERUN). Бит равен единице, если в режиме автоматиче-
ского сканирования каналов ( ) результат АЦП потерян, то есть не
66
был считан до того, как оказался перезаписан следующим результатом. Бит
очищается при чтении регистра ADxGDR.
● Бит 31 (DONE). Бит равен единице, если аналого-цифровое преобра-
зование завершено. Этот бит информирует о готовности результата. Бит
очищается при чтении РСФ ADxGDR.
Регистр ADxGDR. В то время как регистр ADGSR хранит результата
любого последнего преобразования, независимо от использованного канала,
регистры AD0DR0–7, AD1DR0–7 (ADxDRx) хранят результаты для каждого
канала в отдельности. Значения их битов идентичны битам регистра ADGSR,
за исключением отсутствующих битов CHN.
Регистр ADxSTAT. Флаги готовности и потери данных всех каналов
объединены в регистрах AD0STAT и AD1STAT (ADxSTAT).
● Биты 0–7 (DONE0–7). Биты готовности результата преобразования
сигналов в каналах 7–0. В отличие от своих копий в регистрах ADxDRx не
очищаются при чтении регистра.
● Биты 8–15 (OVERUN0–7). Биты потери результата преобразования
сигналов в каналах 0–7. При чтении регистра значение битов сохраняется.
● Бит 16 (ADINT). Флаг прерывания от АЦП. Данный разряд устанав-
ливается в единицу и инициирует прерывание в случае, если равен единице
один из битов готовности DONE0–7, при условии что прерывание для соот-
ветствующего канала разрешено (см. ниже регистр ADxINTEN).
Регистр ADxINTEN содержит биты разрешения прерывания по го-
товности результата АЦП.
● Биты 0–7 (ADINTEN0–7). Биты позволяют разрешить (1) или запре-
тить (0) прерывание, возникающее при завершении преобразования сигнала
на каждом из восьми каналов АЦП.
● Бит 8 (ADGNTEN). Установка этого бита в единицу разрешает пре-
рывание от АЦП независимо от того, для какого канала получен результат.
Для индивидуального выбора каналов следует записать ноль. При сбросе
этот бит установлен в единицу.
1.15.4 Порядок настройки АЦП
1. Выполнить настройку АЦП через регистр ADxCR. При установке
значений отдельных битов предлагается следующий порядок действий.
а) Выбрать способ запуска АЦП, принимая во внимание сведения в
таблицы 1.15.3. Записать значение битов START и BURST в соответствии с
выбранным способом запуска. Записать значение бита EDGE, если АЦП за-
пускается сигналом от таймера или внешним сигналом. Если используется
программный запуск, необходимо нулевое значение START.
б) Записать единицу в разряд PDN.
в) Если требуемое по заданию время преобразования меньше 2,44 мкс,
выбрать разрядность и время преобразования, с учетом выражения (1.15.2).
г) Выбрать тактовую частоту АЦП, так чтобы время преобразования
не превышало требуемого по заданию, но не более 4,5 МГц. Рассчитать зна-
чение битов CLKDIV по формуле (1.15.1).
67
д) Установить единицы в разряды SEL, соответствующие используе-
мым каналам. Если аппаратное сканирование каналов не используется, дол-
жен быть выбран единственный канал.
Приведем пример настройки аналого-цифрового преобразования.
AD0CR=0x00207F02;
Данная команда обеспечивает включение АЦП (бит 21), с делителем частоты
1:128 (биты 8–15), с использованием канала 1 (биты 0–7).
2. Если предполагается использование прерывания по готовности
АЦП, установить каналы, для которых будет вырабатываться прерывание
(регистр ADINTEN). Если выборочная настройка по каналам не требуется
или прерывание от АЦП не используется, оставить регистр ADINTEN без
изменений.
3. Подключить портовые линии МК, выполняющие функцию аналого-
вых входов, через регистры PINSEL0 и PINSEL1 (рисунки 1.9.1, 1.9.2).
4. Если необходимо прерывание от АЦП, настроить контроллер пре-
рываний через регистры VICVectAddr0–15, VICVectCntl0–15 и VICIntEnable.
1.15.5 Программный запуск аналого-цифрового преобразователя
Программный запуск АЦП осуществляется командой логического
сложения регистра ADxCR с числом 0x01000000. Это обеспечит установку
двоичного кода 001 в биты START, не влияя на остальные биты.
AD0CR|=0x01000000;
1.15.6 Запуск аналого-цифрового преобразователя по таймеру
Для периодического преобразования необходимо:
1. Настроить таймер и схему совпадения для формирования интерва-
лов времени, так как это было описано в разделе 1.13.5.
2. Разрешить формирование схемой совпадения установку одного из
сигналов EMC0–3 (регистр TxEMR, биты EMC0–3). При этом прерывание от
таймера разрешать не требуется.
3. При обнаружении готовности АЦП сбросить в ноль соответствую-
щий флаг в регистре TxEMR (биты EM0–3), например, командой (для тайме-
ра 0 и сигнала EMC1)
T0EMR&=0xFFFFFFFD;
1.15.7 Программный опрос готовности АЦП
Практически могут быть предложены два варианта. Отличие состоит в
том, что в первом случае программа МК «зависает» на время преобразова-
ния, что крайне нежелательно. Однако может считаться допустимым упро-
щением алгоритма в случаях, когда время преобразования пренебрежимо ма-
ло в данной конкретной специфической задаче.
Проверка готовности АЦП через опрос флага «с зависанием»
while ((AD0STAT & 0x00000002)==0) ;
ADRes=AD0DR0;
... // Обработка
68
или
do ADCRes=AD0DR0;
while ((AD0STAT & 0x00000002)==0) ;
... // Обработка
Проверка готовности АЦП без «зависания»
if ((AD0STAT & 0x00000002)!=0)
ADRes=AD0DR0;
...; // Обработка
или
ADCRes=AD0DR0;
if ((ADCRes & 0x00000002)!=0)
{
...; // Обработка
}
Подразумевается, что эти команды будут помещены в вечный цикл, чем
обеспечится их периодическое и частое выполнение.
Переменная ADRes должна быть объявлена как целое без знака.
unsigned int ADCRes;
1.15.8 Опрос готовности АЦП по прерыванию
Наиболее эффективным и универсальным можно считать считывание
и обработку результата, вынесенную в процедуру обработки прерывания.
Для разрешения прерывания по готовности АЦП необходимо:
1. Если требуется запрашивать прерывание по завершении преобразо-
вания для нескольких каналов выборочно, произвести соответствующую
настройку через регистр ADxINTEN. Если прерывание должно происходить
при каждом преобразовании, этот пункт пропустить.
2. Настроить систему прерываний с помощью регистров
VICVectAddr0–15, VICVectCntl0–15 и VICIntEnable.
3. Процедура обработки прерывания должна содержать команду сбро-
са в ноль сигнала EMCx, если прерывание вызвано схемой совпадения тай-
мера (раздел 1.15.4).
1.15.9 Считывание и масштабирование результата АЦП
Результирующий код аналого-цифрового преобразования может быть
считан из регистра ADxDRx путем наложения маски и сдвига на шесть раз-
рядов вправо:
N=(AD0DR0 & 0xFFC0) >> 6;
или
N=((AD0DR0 >> 6) & 0x3FF);
Наложение маски (логическое умножение на 0xFFC0) выделяет результат
АЦП, сбросив все остальные биты регистра ADxDRx в ноль. Сдвиг вправо
удаляет незначащие нули. При этом будет получен результат АЦП «как есть»
от 0 до 1023, который может быть сохранен в целочисленную переменную N.
69
На практике, обычно, требуется перейти от безразмерного результата
АЦП к физической величине, которой он соответствует. Для этого выполня-
ется масштабирование.
Код АЦП связан с напряжением, приложенным непосредственно к
входу формулой (1.15.3). Повторим ее с другими обозначениями
,
где — опорное напряжение, В; — входной код АЦП.
Соответственно, масштабирующий множитель
. (1.15.4)
Очевидно, что этот множитель при имеет смысл веса единицы
младшего разряда АЦП.
Теперь примем во внимание, что измерительный канал может иметь
не единичный коэффициент передачи . Тогда вес младшего разряда
. (1.15.5)
Заметим, что связывает входное напряжение АЦП с физической величи-
ной, возможно неэлектрической. Поэтому может иметь размерность.
Если числовое значение не равно степени двух, то вес младше-
го разряда оказывается «длинной» дробью. В то же время индицируемый ре-
зультат измерения должен быть округлен до разумного числа десятичных
разрядов. Практически это приводит к увеличению шума квантования.
Несмотря на то, что коэффициент является свойством аппаратных
узлов измерительного канала, обычно им можно варьировать. Имеется также
некоторая свобода в выборе величины источника опорного напряжения. Так
можно добиться того, что вес младшего разряда имеет вид
, где — цифра от 1 до 9, а — целое число. Тогда индикация в де-
сятичной системе счисления возможна без округления результата измерения.
Сохранение результата в формате с плавающей точкой может выпол-
няться командой, подобной следующей
N=(AD0DR0 & 0xFFC0)*Vref/С/65536.0;
Имеется в виду, что переменная N объявлена как float или double;
Vref — переменная или константа, равная опорному напряжению; C —
коэффициент передачи измерительного канала.
Поясним значение множителя Vref/65536.0. Результат оказывается
смещен на 6 разрядов влево, поскольку справа он дополнен шестью нулевы-
ми двоичными разрядами. С учетом этого обстоятельства и формулы (1.15.5)
находим масштабирующий множитель .
70
но малом шуме квантования. Напряжение формируется на линии AOUT.
Диапазон выходного напряжения ЦАП от 0 В до опорного напряжения, под-
ключенного к контакту Vref.
1.16.1 Регистр управления ЦАП
Регистр DACR. Управление ЦАП осуществляется с помощью един-
ственного регистра (рисунок 1.16.1).
● Биты 6–15 (VALUE). Код выходного напряжения ЦАП. Значение
разрядов VALUE связано с напряжением на выходе AOUT выражением
. (1.16.1)
● Бит 16 (BIAS). Бит определяет время установления выходного
напряжения ЦАП (таблица 1.16.1).
Таблица 1.16.1 – Управления временем установления ЦАП
BIAS Время установления Ток, потребляемый модулем ЦАП
0 1 мкс 700 мкА
1 2,5 мкс 350 мкА
DACR – настройка ЦАП
19 17 16 15 8 7 6 5 4 3 0
AS
VALUE
BI
71
разряды VALUE. Расчет кода выполняется в соответствии с выражением (1).
Средства, сигнализирующие о завершении переходного процесса, отсут-
ствуют. В программе следует предусматривать временные задержки, необхо-
димые для установления выходного напряжения.
О применении ЦАП для формирования аналоговых сигналов разной
формы см. раздел 3.7.
EN STA STO SI AA
Старт/Стоп Подтвержд.
ВКЛ
Флаг прерывания
I2CxCONCLR – сброс состояния I2C
15 8 7 6 5 4 3 2 1 0
EN STA SI AA
Старт Подтвержд.
ВКЛ
Флаг прерывания
I2CxSTAT – состояние I2C
15 8 7 3 2 0
STATUS
Состояние I2C
73
. Число передаваемых бит совпадает с двоичным кодом BITS.
соответствует пакету 8 бит, — 15 бит,
— 16 бит.
Регистр S0SPDR. Двунаправленный регистр передачи данных. Запись
в регистр приводит к началу передачи данных по SPI. Повторная запись до-
пускается только после завершения передачи. На время передачи запись в ре-
гистр блокируется.
Чтение регистра дает принятые данные. Отсутствующие старшие раз-
ряды заполнены нулями.
Регистр S0SPCCR. Делитель частоты для синхросигнала SPI. Диапа-
зон допустимых значений 8–254. В режиме ведущего на линии SCK будет
установлена частота
. (1.17.1)
Внимание! Значение S0SPCCR должно быть четным и не менее восьми. По-
этому частота не может превысить МГц.
Частота равна битовой скорости передатчика (бит/с). Например,
популярный сдвиговый регистр 74HC595 допускает частоту синхроимпуль-
сов МГц (в зависимости от производителя).
Регистр S0SPSR отражает состояние приемопередатчика SPI.
● Бит 3 (ABRT). Отмена передачи. Бит устанавливается в единицу, ес-
ли в режиме ведомого передача прерывается переходом в пассивное состоя-
ние сигнала SSEL. Бит сбрасывается в ноль при чтении регистра.
● Бит 4 (MODF). Ошибка режима. Бит устанавливается в единицу, ес-
ли в режиме ведущего сигнал SSEL перешел в активное состояние, сигнали-
зируя о том, что на линии есть еще один ведущий. Бит сбрасывается в ноль
после чтения данного регистра и записи регистра S0SPCR.
● Бит 5 (ROVR). Потеря данных при чтении. Бит устанавливается в
единицу, если новый пакет был принят до того, как считан предыдущий из
регистра данных S0SPDR. Бит сбрасывается в ноль при чтении регистра.
● Бит 6 (WCOL). Конфликт записи. Бит устанавливается в единицу,
если новый пакет был записан в регистр данных S0SPDR во время передачи.
Бит сбрасывается в ноль после чтения данного регистра и доступа к регистру
данных S0SPDR.
● Бит 7 (SPIF). Значение 1 индицирует готовность после передачи.
Флаг сбрасывается в ноль после двух действий: чтения регистра S0SPSR и
обращению к регистру данных S0SPDR.
Регистр S0SPINT содержит единственный бит — запрос прерывания.
● Бит 0 (SPINT). Флаг запроса прерывания. Флаг сбрасывается в ноль
путем записи в него единицы.
1.17.3 Передача и прием данных в режиме ведущего
1. Настроить портовые линии на режим SPI через регистры PINSEL0,
PINSEL1. В простейшем случае потребуются лишь две линии SCK и MOSI.
74
2. Настроить скорость обмена данными, задав делитель тактовой ча-
стоты через регистр S0SPCCR (1.17.1). Требуется принимать во внимание
допустимую частоту для других устройств, подключенных к шине SPI.
3. Настроить модуль SPI через регистр S0SPCR. Обычно требуется
лишь включить режим ведущего (бит MSTR) и задать число передаваемых
бит (разряды BITEN и BITS).
4. При необходимости включить прерывание от модуля SPI через ре-
гистры VICVectAddr0, VICVectCntl0 и VICIntEnable.
Передача инициируется путем записи в регистр S0SPDR передавае-
мых данных.
Готовность приемопередатчика может быть проверена путем опроса
бита SPIF (бит 7) в регистре S0SPSR. Единица обозначает завершение пере-
дачи. Альтернатива — использование системы прерываний.
Передача данных приводит к формированию синхроимпульсов и од-
новременно сопровождается приемом последовательных битов с входа
MISO. Если прием задействован, то после распознавания готовности пере-
датчика принятый пакет может быть считан из того же регистра S0SPDR. В
режиме ведущего осуществить прием без передачи невозможно, поскольку
только передача сопровождается формированием синхроимпульсов.
1.17.4 Передача и прием данных в режиме ведомого
1. Настроить портовые линии на режим SPI через регистры PINSEL0,
PINSEL1. В простейшем случае потребуются лишь одна линия: MOSI (для
приема) или MISO (для передачи).
2. Настроить модуль SPI через регистр S0SPCR. Обычно требуется
лишь включить режим ведомого (бит MSTR) и задать число передаваемых
бит (биты BITEN и BITS).
3. При необходимости включить прерывание от модуля SPI через ре-
гистры VICVectAddr0, VICVectCntl0 и VICIntEnable.
Как и в режиме ведущего передача инициируется путем записи пере-
даваемых данных в регистр S0SPDR. Передача не является обязательной. Ес-
ли требуется только прием данных, то достаточно только контроля готовно-
сти приемопередатчика.
Готовность приемопередатчика может быть проверена путем опроса
бита SPIF (бит 7) в регистре S0SPSR (единица — обмен завершен) или через
прерывания.
После обнаружения готовности можно считать принятый пакет из ре-
гистра S0SPDR. В режиме ведущего может осуществляться только передача,
только прием или и то и другое.
START STOP
Адрес A6-A0 R/W A Данные D7-D0 A A
76
Микроконтроллер LPC2148 оснащен двумя идентичными модулями
2
I C (I2C0 и I2C1). Здесь будем рассматривать только работу в режиме веду-
щего. Режим ведомого может потребоваться только для организации переда-
чи данных между двумя или несколькими микроконтроллерами. Полное опи-
сание можно найти в литературе [1] или в документации к LPC214x.
1.18.2 Управляющие регистры
Схема регистров управления модулями I2C показана на рисунке 1.18.2.
Регистры I2CxCONSET и I2CxCONCLR — управляют состоянием
модулей I2C. Запись единицы в один из разрядов регистра xSET переводит
модуль в соответствующие состояние. Запись единица в xCLR снимает соот-
ветствующие состояние. Запись нулей в эти регистры не имеет значения.
● Бит 2 (AA) разрешает или запрещает генерирование подтверждения
в режиме приема данных. Во время передачи байтов пакета обычно требует-
ся устанавливать в единицу, при передаче последнего байта сбросить в ноль.
I2CxCONSET – установка состояния I2C
15 8 7 6 5 4 3 2 1 0
EN STA STO SI AA
Старт/Стоп Подтвержд.
ВКЛ
Флаг прерывания
I2CxCONCLR – сброс состояния I2C
15 8 7 6 5 4 3 2 1 0
EN STA SI AA
Старт Подтвержд.
ВКЛ
Флаг прерывания
I2CxSTAT – Состояние I2C
15 8 7 3 2 0
STATUS
Состояние I2C
78
Обычно скважность сигнала SCL равна 2 и эти регистры содержат равные
значения, хотя это не обязательно. Частота не должна превышать
кГц. Следовательно, для расчета значений регистров можно рекомендо-
вать следующее выражение:
, (1.18.2)
где частота задана в мегагерцах.
1.18.3 Настройка модуля I2C
Для настройки модуля I2C, как правило, достаточно:
а) выбрать режим портовых линий SDA и SCL через регистр
PINSEL0;
б) присвоить одинаковые значения регистрам выбора скорости
(I2CxSCLH, I2CxSCLL), рассчитанные по формуле 1.18.2;
в) включить модуль I2C, записав код 0x40 в регистр I2CxCONSET.
1.18.4 Типовые циклы обмена данными по шине I2C
На практике чаще всего встречаются три вида циклов обмена данны-
ми по шине I2C. Цикл содержит ожидание готовности I2C через регистры
I2CxCONSET и I2CxSTAT, установку и снятие состояний через регистры
I2CxCONSET и I2CxCONCLR, прием и передачу данных через регистр
I2CxDAT. Ниже приведены алгоритмы каждого цикла обмена.
Цикл «Адрес–Передача»
1. Установить START.
2. Дождаться состояния 0x08 (START передан); снять START; пере-
дать адрес и .
3. Дождаться состояния 0x18 (адрес передан); передать байт.
4. Дождаться состояния 0x28 (данные переданы); передать следующий
байт. Если передан последний (или единственный) байт, установить STOP.
Цикл «Адрес–Прием»
1. Установить START.
2. Дождаться состояния 0x08 (START передан); снять START; если
требуется принять больше одного байта, разрешить подтверждение; передать
адрес и . Если байт всего один, пункт 3 пропустить.
3. Дождаться состояния 0x50 (данные получены, подтверждение от-
правлено); сохранить принятый байт. Если получен предпоследний байт, за-
претить подтверждение (запретить сразу, если байта всего два).
4. Дождаться состояния 0x58 (данные получены, подтверждение НЕ
отправлено). Установить STOP.
Цикл «Адрес–Передача–Прием»
1. Установить START.
2. Дождаться состояния 0x08 (START передан); снять START; пере-
дать адрес и .
3. Дождаться состояния 0x18 (адрес передан); передать байт.
79
4. Дождаться состояния 0x28 (данные переданы); передать следующий
байт. Если передан последний (или единственный) байт, установить START.
5. Дождаться состояния 0x10 (повторный START передан); снять
START; если требуется принять больше одного байта, разрешить подтвер-
ждение; передать адрес и . Если байт всего один, пункт 4 пропустить.
6. Дождаться состояния 0x50 (данные получены, подтверждение от-
правлено); сохранить принятый байт. Если получен предпоследний байт, за-
претить подтверждение (запретить сразу, если байта всего два).
7. Дождаться состояния 0x58 (данные получены, подтверждение НЕ
отправлено). Установить STOP.
В качестве примера приведем шаблон реализации самого сложного
цикла «Адрес–Передача–Прием» через опрос флага готовности в регистре
I2C0CONSET.
I2C0CONSET=0x20;
while (!Finished)
if (I2C0CONSET & 0x08)
{
switch (I2C0STAT)
{
case 0x08: ... ; break;
case 0x18: ... ; break;
case 0x28: ... ; break;
case 0x10: ... ; break;
case 0x50: ... ; break;
case 0x58: ... ; Finished=1;
}
I2C0CONCLR=0x08;
}
Алгоритм упрощается с использованием прерываний. Требуется по-
местить в процедуру обработки прерывания конструкцию switch...case и
команду сброса флага в I2CxCONCLR.
80
ло и конец символа обозначаются стартовым битом (логический ноль) и сто-
повым битом (логическая единица). Стоповых битов может быть один или два.
На рисунке 1.19.1 Показаны осциллограммы сигнала, передаваемого
по интерфейсу RS-232 персональным компьютером, а также эквивалентного
сигнала стандартных уровней ТТЛ/КМОП, полученного с помощью преобра-
зователя уровней MAX232.
81
U0TER – Включение передатчика
11 8 7 6 0
EN
TX
Вкл
82
Таблица 1.19.1 – Оптимальные по точности настройки скорости UART
МГц МГц МГц
Стандартная
скорости, %
скорости, %
скорости, %
DivAddVal
DivAddVal
DivAddVal
Отн. погр.
Отн. погр.
Отн. погр.
скорость
U0DLM
U0DLM
U0DLM
U0DLL
U0DLL
U0DLL
MulVal
MulVal
MulVal
2400 226 4 4 1 0 113 2 4 1 0 23 1 5 2 0,006
4800 113 2 4 1 0 23 1 5 2 0,006 93 0 10 11 0,006
9600 23 1 5 2 0,006 93 0 10 11 0,006 71 0 8 3 0,032
19200 93 0 10 11 0,006 71 0 8 3 0,032 38 0 7 2 0,059
38400 71 0 8 3 0,032 38 0 7 2 0,059 19 0 7 2 0,059
57600 31 0 10 11 0,006 19 0 7 5 0,059 12 0 14 5 0,059
Битовая скорость определяется выражением
; (1.19.1)
83
● Бит 1 (RX FIFO Reset). Запись единицы приводит к очистке буфера
приемника, после чего бит автоматически будет сброшен в ноль.
● Бит 2 (TX FIFO Reset). Запись единицы приводит к очистке буфера
передатчика. Бит также сбрасывается в ноль автоматически.
● Биты 6–7 (RX Trigger Level) — порог буфера. Определяют число
принятых байт, при котором вырабатывается прерывание (см. таблицу
1.19.2). Биты должны быть установлены до включения прерывания.
Таблица 1.19.2 – Пороговое значение буфера приемника
RX Trigger Level Число приятных байт, вызывающих прерывание
00 1
01 4
10 8
11 14
Регистр U0LCR — регистр управления линией.
● Биты 0–1 (World Length Select) выбирают разрядность передаваемых
и принимаемых символов (см. таблицу 1.19.3).
Таблица 1.19.3 – Настройка числа принимаемых и передаваемых бит
World Length Select Число принимаемых и передаваемых бит
00 5
01 6
10 7
11 8
● Биты 4–5 (Parity Select). Настройка контроля четности (в соответ-
ствии с таблицей 1.19.4).
● Бит 2 (Stop Bit Select). Нулевое значение соответствует одному сто-
повому биту, единица — двум стоповым битам.
Таблица 1.19.4 – Настройка контроля четности
Parity Select Настройка бита честности
00 Число двоичных единиц в символе нечетно
01 Число двоичных единиц в символе четно
10 Бит четности всегда равен 1
11 Бит четности всегда равен 0
● Бит 3 (Parity Enable). Установка в единицу приводит к формирова-
нию бита четности при передаче и контролю четности при приеме.
● Бит 6 (Break Control). Запись единицы приводит к установке логиче-
ского нуля на выходе передатчика TxD. Низкий уровень на линии TxD будет
удерживаться пока этот бит равен единице.
● Бит 7 (DLAB). Установка единицы открывает доступ к регистрам
настройки скорости (см. выше).
Регистр U0LSR индицирует состояние линии.
84
● Бит 0 (RDR). Единица показывает, что буфер приемника содержит
принятые данные, готовые для считывания через U0RBR. Бит сбрасывается в
ноль, когда буфер опустеет.
● Бит 1 (OE). Единица устанавливается в случае переполнения буфера
приемника, то есть поступлении более 16 символов подряд без извлечения
данных из U0RBR. Бит сбрасывается в ноль при чтении регистра U0LSR.
● Бит 2 (PE). Единица обозначает возникновение ошибки контроля
четности. Значение бита относится к самому «старому» символу в буфере-
очереди. При извлечении очередного символа буфер сдвигается, и флаг PE
обновляется для очередного символа. Бит сбрасывается при чтении U0LSR.
● Бит 3 (FE). Единица показывает, что стоповый бит распознан как
логический ноль. При возникновении такой ошибки приемник будет пытать-
ся восстановить синхронизацию, считая стоповый бит пропущенным, а нуле-
вой уровень стартовым битом следующего символа. Значение бита также от-
носится к очередному символу в буфере, обновляется при чтении U0RBR и
сбрасывается в ноль при чтении U0LSR.
● Бит 4 (BI). Устанавливается в единицу, если на протяжении всего
символа состояние линии RXD0 неизменно и равно логическому нулю. Чте-
ние U0LSR сбрасывает бит в ноль.
● Бит 5 (THRE). Единица показывает, что буфер передатчика пуст и
готов принимать данные через U0THR. При записи в U0THR бит сбрасывает-
ся в ноль.
● Бит 6 (TEMT). Единица показывает, что свободны и буфер передат-
чика, и сдвиговый регистр передатчика. То есть в настоящий момент пере-
датчик простаивает. Ноль устанавливается, если в буфере или в сдвиговом
регистре появляются данные.
● Бит 7 (RXFE). Устанавливается в единицу, если в любой из ячеек
буфера имеется символ приятный с ошибкой (FE, PE или BI). Бит сбрасыва-
ется в ноль при чтении U0LSR при условии все байты, хранящиеся в буфере,
приняты без ошибок.
Регистр U0ACR — управление автоматической настройкой скорости.
● Бит 0 (Start). Установка в единицу запускает процедуру автоматиче-
ского определения скорости. По завершении бит автоматически будет сбро-
шен в ноль.
● Бит 1 (Mode). Режим 0 (скорость определяется по стартовому биту и
младшему биту данных) или режим 1 (скорость определяется только по стар-
товому биту).
● Бит 2 (Auto Restart). Установка единицы приводит к автоматическо-
му перезапуску процедуры в случае неудачи.
● Бит 8 (ABEOIntClr). Запись единицы сбросит соответствующий
флаг запроса прерывания в регистре U0IIR. Запись нуля не имеет значения.
● Бит 9 (ABTOIntClr). Запись единицы сбросит соответствующий
флаг запроса прерывания в регистре U0IIR. Запись нуля не имеет значения.
Регистр U0TER предназначен для запрета передачи. Содержит един-
ственный управляющий бит.
85
● Бит 7 (TXEN). По умолчанию бит равен единице. Запись нуля за-
прещает работу передатчика. Если бит сброшен в ноль во время передачи, то
она будет завершена, но следующий символ из буфера передаваться не будет
до тех пор, пока биту не будет присвоена единица.
Регистр U0IER предназначен для включения прерываний, связанных
с событиями в модуле UART0.
● Бит 0 (RBR) разрешает формирование запроса прерывания при нали-
чии данных в буфере приемника, которые не были считаны через U0RBR.
● Бит 1 (THREE) разрешает запрос прерывания при опустошении бу-
фера передатчика.
● Бит 2 (RX Line Status) разрешает прерывание при обнаружении
ошибки (OE, PE, FE, BI) в ходе прима данных. Подробней об ошибках см.
описание регистра U0LSR.
● Бит 8 (ABTO Int En) разрешает запрос прерывания по успешному
завершению процедуры автоматического определения скорости.
● Бит 8 (ABEO Int En) разрешает запрос прерывания по неудачному
завершению процедуры определения скорости.
Регистр U0IIR — идентификатор прерываний UART0. Все прерыва-
ющие события, священные с модулем UART0 считаются относящимися к
одному источнику. Поэтому требуется алгоритмически определять причину
прерывания с помощью следующих битов.
● Бит 0 (Interrupt Pending) Равенство единице показывает, что ни одно
из прерываний не запрошено.
● Биты 1–3 (Interrupt Identification) содержат идентификатор прерыва-
ния в соответствии с таблицей 1.19.5.
Таблица 1.19.5 – Идентификация прерываний приемопередатчика UART
U0IIR[0–3] Значение Условие сброса в ноль
0001 Прерывание не запрошено —
0110 Ошибка в ходе приема
Чтение U0LSR
(биты OE, PE, FE, BI в U0LSR)
0100 Чтение U0RBR или число байт,
Буфер приемника полон
в буфере, становится порога
1100 Буфер частично заполнен и
Чтение U0RBR
приемник простаивает
0010 Чтение U0IIR или запись
Буфер передатчика пуст
в регистр THR
● Бит 6–7 (FIFO Enable) Эти биты повторяют бит 0 регистра U0FCR.
● Бит 8 (ABEO Int). Единица показывает, что процедура автоматиче-
ского определения скорости завершена успешно.
● Бит 9 (ABTO Int). Единица показывает, скорость не удалось опреде-
лить автоматически.
Здесь необходимо дать некоторые пояснения. Идентификаторы 0100 и
1100 свидетельствуют о наличии необработанных данных в буфере приемни-
ка. Различие состоит в том, что код 0100 устанавливается, когда число байт в
86
буфере достигает порогового значения 1, 4, 8 или 14 (см. выше регистр
U0FCR). Код 1100 устанавливается, если в буфере есть хотя бы один байт, но
число принятых байт меньше порогового значения, и приемник простаивает
в течение интервала 3,5…4,5 символа. Этот интервал не может быть изменен
и зависит от нескольких настроек UART (см. техническое описание
LPC214x).
Необходимость различать эти события поясним на простом примере.
Пусть требуется принять и обработать пакет из 100 байт, следующих непре-
рывным потоком. Порог буфера установлен на 14 байт. То есть прерывание
запрашивается через каждые 14 принятых байт. После седьмого прерывания
из буфера будут извлечены байт. Последние 2 байта не дадут за-
полнения буфера. Однако прекращение непрерывного потока будет обнару-
жено и запрошено прерывание с идентификатором 1100.
Практически обработка этих событий может быть абсолютно одина-
ковой. Если порог буфера равен единице, всегда получаем код 0100.
Отметим также, что прерывания будут постоянно вырабатываться до
тех пор пока буфер приемника не опустеет, а буфер передатчика не будет за-
гружен хотя бы одним байтом.
1.19.3 Настройка порта UART
Для настройки можно рекомендовать следующий порядок действий.
1. Выбрать режим портовых линий RxD и (или) TxD через регистр
PINSEL0.
2. Установить в единицу бит DLAB в регистре U0LCR (необходимо
для настройки скорости).
3. Задать скорость приемопередатчика через регистры U0DLM,
U0DLL, и U0FDR. Воспользоваться таблицей 1.19.1 или выражениями
(1.19.2, 1.19.3).
4. Настроить параметры протокола обмена (число информационных и
стоповых битов, контроль четности) через регистр U0LCR. При этом седьмой
бит (DLAB) сбросить в ноль.
5. Включить буферы приемопередатчика (бит 0 регистра U0FCR) и
задать в том же регистре порог буфера — число накопленных принятых байт,
вызывающее прерывание. Если механизм прерываний применять не предпо-
лагается, то можно рекомендовать порог в один байт. При использовании
прерываний желательно, чтобы они возникали как можно реже, поэтому ре-
комендуем порог в 8 или 14 байт.
1.19.4 Прием байта с опросом флага
Команды приема байта с опросом флага могут быть размещены в про-
извольном месте программы. Необходимо обеспечить условия, при которых
частота опроса будет не менее 1/16 байтовой скорости.
1. Дождаться появления единицы в младшем разряде (RDR) регистра
U0LSR.
2. Считать принятый байт из U0RBR.
87
3. Повторять опрос флага RDR и чтение из U0RBR до тех пор пока
буфер не окажется пуст ( ).
1.19.5 Передача байта с опросом флага
1. Записать от 1 до 16 байт в регистр U0THR подряд.
2. Дождаться появления единицы в бите THRE регистра U0LSR.
3. После появления флага опустошения буфера THRE передача может
быть продолжена.
1.19.6 Прием и передача данных с использованием прерываний
1. Дополнить настройку UART разрешением формирования запросов
прерываний (регистр U0IER). Обычно можно установить три младших бита в
единицу, записав код 0x07.
2. Настроить систему прерываний через регистры VICVectAddr0–15,
VICVectCntl0–15 и VICIntEnable.
3. В процедуре обработки прерывания следует считать идентификатор
прерывания и состояние линии, например, командами:
IntID=U0IIR & 0x0F; // Выделение идентификатора прер.
LineStat=U0LSR; // Чтение состояния линии
4. Путем анализа идентификатора прерывания, сохраненного в пере-
менной IntID можно организовать ветвление, то есть выполнять либо прием,
либо передачу, либо обработку ошибок. При этом можно рекомендовать сле-
дующую конструкцию:
switch (IntID)
{
case 0x04:
case 0x0C:
while (U0LSR & 1)
{
... // Чтение из U0RBR байта и сохранение
}
break;
case 0x06:
if (LineStat & 0x02) ... ; // Обработка ошибок
... ;
break;
case 0x02:
... // Передача от 1 до 16 байт
}
Первая ветвь выполняется при наличии данных в буфере и содержит
команду циклического чтения до тех пока буфер не окажется пуст (фиксиру-
ется по флагу RBR в регистре U0LSR). Об обработке ошибок см. ниже. Пере-
дача может выполняться до 16 байт подряд.
88
1.19.7 Прием и передача пакетов данных
При работе с пакетами данных требуется обеспечить кадровую син-
хронизацию, то есть обозначить границы пакетов. Для этого в состав пакета
включают заранее известный заголовок (префикс) или постфикс. Это может
быть кодовая комбинация, которая не встречается в информационной части
пакета, так как это сделано в протоколе обмена с модемом (символы «AT»)
или в протоколе SCPI (Standard Commands for Programmable Instruments)
(символы «*» или «:» в начале и символ «?» в конце).
Если выбрать код, не встречающийся среди данных невозможно, то в
качестве заголовка используют любую достаточно длинную кодовую комби-
нацию (не менее 4-х байт). Высокая разрядность этой комбинации делает ма-
ловероятным случайное совпадение с фрагментов данных.
В состав пакета можно ввести поле для обозначения длины пакета,
что избавит от потребности в завершающей кодовой комбинации (постфик-
се). Может также потребоваться введение поля циклического кода контроля
ошибок, например, CRC32.
Стоит сказать, что обмен данными между персональным компьюте-
ром и встраиваемым микроконтроллером может быть организован по прин-
ципу «запрос-ответ». То есть МК будет отправлять пакет данных только в
ответ на соответствующую команду ПК. В таком случае синхронизация не
потребуется так же как и передача длины пакета.
1.19.8 Диагностика ошибок
Диагностика ошибок осуществляется путем анализа регистра U0LSR.
Следует учитывать, что большинство флагов этого регистра автоматически
сбрасываются при чтении. Поэтому прежде чем анализировать состояние
U0LSR его необходимо одной командой скопировать в специально создан-
ную переменную, а затем проверять ее значение.
Реакция на возникшую ошибку диктуется спецификой решаемой за-
дачи. Это может быть игнорирование ошибки, появление предупреждающего
сигнала или информирование об ошибке по линии UART. В то же время, об-
работка ошибки переполнения буфера всегда предполагает очистку буфера
путем многократного чтения из U0RBR или установкой бита RX FIFO Reset в
регистре U0FCR.
1.19.9 Автоматическая настройка скорости
Для автоматической настройки скорости необходимо установить еди-
ницу в младший бит (Start) регистра U0ACR. Скорость будет измерена во
время приема следующего символа. Необходимо чтобы нулевой (младший
разряд) этого тестового символа был равен единице, а следующий (первый)
бит — нулю. То есть первый символ, передаваемый после запуска процедуры
измерения скорости, должен иметь двоичный формат xxxxxx01. Если же
установить режим 1 (бит Mode регистра U0ACR), то достаточно только одно-
го единичного младшего бита. Этому правилу подчинены AT-команды (код
символа «A» — 0x41, символа «a» — 0x61).
89
Отметим, что сам тестовый символ не теряется. Он будет принят и
помещен в буфер.
Факт определения скорости можно отследить через соответствующие
прерывания или путем опроса флагов в регистре U0IIR. В случае неудачи
можно повторить процедуру или установить какую-либо скорость по умол-
чанию.
90
ILR – флаги запросов прерываний CCR – управление часами
11 8 7 4 3 2 1 0 11 8 7 5 4 3 2 1 0
L
T
F
C
C
R
R
CTTEST
IF
S
L
EN K
C TC
A TC
R TC
SR LK
Тест Вкл
«Будильник» Инкремент
Источник тактирования Сброс
AMR – управление запросами прерываний по «будильнику»
31 24 23 16 15 8 7 6 5 4 3 2 1 0
R
N
Y
M
C
A
A
A
A
A
AM
AM
A
AR
IN
O
O
O
O
O R
M
SE MR
D MR
M MR
D MR
D MR
YE MR
H
N
Y
M
C
W
U
AR
IN
O
O
O
O
O
M M
SE M
D IM
M IM
D IM
D IM
YE IM
H IM
YEAR
День в году (0–366)
91
Таблица 1.20.1 – Основные регистры-счетчики часов реального времени
Счетчики Объединенные Диапазон
Регистры
времени регистры Назначение возможных
будильника
и даты Регистр Биты значений
SEC ALSEC 0–5 Секунды 0–59
MIN ALMIN 8–13 Минуты 0–59
CTIME0
HOUR ALHOUR 16–20 Часы 0–23
DOW ALDOW 24–26 День недели 0–6
1–28, 1–29, 1–30 или
Число 1–31 в зависимости
DOM ALDOM 0–4
месяца от месяца и
CTIME1
високосного года
MONTH ALMONTH 8–11 Месяц 1–12
YEAR ALYEAR 16–27 Год 0–4095
1–365 или 1–366 для
DOY ALDOY CTIME2 0–11 День в году
високосного года
Регистр CCR управляет счетчиком часов реального времени.
● Бит 0 (CLKEN). Единица разрешает работу часов, ноль —
запрещает.
● Бит 1 (CTCRST). Запись единицы сбрасывает в ноль счетчик-
делитель. Сброс действует до тех пор, пока этот бит не будет очищен.
● Бит 2–3 (CTTEST). Биты должны быть сброшены в ноль.
● Бит 4 (CLKSRC). Если бит равен единице, источником тактового
сигнала для часов реального времени служит отдельный генератор с частотой
32768 Гц. Сброс в ноль приводит к тактированию сигналом с предваритель-
ного делителя, который в свою очередь тактируется сигналом .
Регистр CTCR — 15-разрядный счетчик-делитель часов реального
времени. Входная частота счетчика 32768 Гц, выходная — 1 Гц. Выход счет-
чика подключен к входу счетчика секунд.
Регистр ILR содержит флаги прерываний от часов реального време-
ни.
● Бит 0 (RTCCIF). Равенство единице свидетельствует о прерывании
по инкременту одного из счетчиков времени. Запись единицы приводит к
сбросу соответствующего флага прерывания (см. также регистр CIIR).
● Бит 1 (RTCALF). Равенство единице свидетельствует о прерывании
по «будильнику». Запись единицы приводит к сбросу флага прерывания (см.
также регистр CIIR).
Регистр CIIR управляет запросами прерывания по инкременту каж-
дого из счетчиков часов реального времени. В зависимости от битов, уста-
новленных в единицу, прерывания могут запрашиваться по инкременту се-
кунд (IMSEC), минут (IMMIN), часов (IMHOUR), числа месяца (IMDOM),
дня недели (IMDOW), числа года (IMDOY), месяца (IMMON) или года
(IMYEAR).
92
Регистр AMR управляет запросами прерывания от «будильника». Его
структура аналогична регистру CIIR — каждый бит (AMRSEC–AMRYEAR)
отвечает за определенный временной интервал от секунды до года. Установ-
ка единицы в каждый разряд запрещает запрос прерывания при совпадении
соответствующего счетчика с установкой будильника. Например, ежедневное
срабатывание будильника в 8:00 потребует установки всех битов кроме AM-
SEC, AMMIN и AMHOUR. Установка в единицу всех разрядов отключит
«будильник».
Регистры PREINT, PREFRAC задают предварительный делитель,
предназначенный для получения опорной частоты 32768 Гц из любой такто-
вой частоты периферийных устройств . Строго говоря, при этом такто-
вый сигнал не является колебаниями с частой 32768 Гц, а представляет собой
последовательность из 32768 неодинаковых по длительности импульсов, по-
вторяющуюся каждую секунду.
Расчет значений регистров выполняется по формулам:
; (1.20.1)
(1.20.2)
1.20.3 Рекомендации по применению
Настройка часов реального времени проста:
1. При необходимости присвоить начальные значения счетчикам вре-
мени SEC–YEAR.
2. Включить часы и тактирование от низкочастотного генератора (за-
пись кода 0x11 в регистр CCR).
Если необходимо тактировать часы от основного тактового генерато-
ра, потребуется присвоить регистрам и величины, рас-
считанные по формулам (1.20.1–1.20.2). Для частоты МГц
, . При МГц ,
. Тогда в регистр CCR записать код 0x01.
Настройка прерываний:
1) разрешить необходимые прерывающие события, записав маску в
регистры IIR и/или AMR;
2) разрешить прерывание от часов с помощью регистров
VICVectAddr0–15, VICVectCntl0–15 и VICIntEnable.
93
б) Режим отключения (Power Down Mode). В отключенном состоянии
прекращается питание всех узлов микроконтроллера. Однако сохраняется со-
стояние регистров, оперативной памяти и электрические уровни на выводах.
Потребляемая мощность снижается до 40–100 мкА. Выход из режима отклю-
чения производится внешним прерыванием или сбросом.
Гибкое управление потребляемой мощностью возможно путем от-
ключения питания отдельных периферийных устройств.
Следует напомнить, что потребляемая мощность связана с тактовой
частотой ядра и шины периферийных устройств . Уменьшение
этих частот (раздел 1.7) приведет к снижению потребляемой мощности.
Микроконтроллер оснащен монитором контроля напряжения питания.
Монитор реагирует на два порога: 2,9 В и 2,6 В и предоставляет возможность
генерировать запрос прерывания при снижении напряжения до 2,9 В, а также
переводить микроконтроллер в состояние сброса при снижении напряжения
до 2,6 В.
1.21.2 Управляющие регистры
Схема управляющих регистров приведена на рисунке 1.21.1.
Регистр PCON — управление режимом энергопотребления.
Бит 0 (IDL). Установка единицы переводит микроконтроллер в режим
ожидания.
Бит 1 (PD). Установка единицы переводит МК в режим отключения.
RSIR – идентификация источника сброса
15 8 7 4 3 2 1 0
TR
R
TR
R
D
PO
D
BO
EX
W
PD
L
G
D
M
B
ID
BO
BO
Ожидание
Сброс от монитора питания Отлючение
ВКЛ монитор питания
ВКЛ монитор питания
в режиме отключения
C
AD
I2
U
15 13 12 11 10 9 8 7 6 5 4 3 2 1 0
T1
T0
0
0
I1
I0
0
TC
er
er
0
M
C
AR
AR
AD
SP
SP
PW
m
I2
R
Ti
Ti
U
94
Бит 2 (BODPDM). Установка единицы приводит к отключения мони-
тора питания. Это приводит к дополнительному снижению потребляемой
мощности, однако, в случае снижения напряжения питания выхода перехода
микроконтроллера в активный режим не произойдет. Соответственно не бу-
дет реакции на аварийную ситуацию.
Бит 3 (BOGD). Установка единицы отключает монитор питания.
Бит 4 (BORD). Установка единицы запрещает формирование сброса
при понижении напряжения до 2,6 В.
Регистр RSIR (только для чтения) предназначен для идентификации
источника сброса.
Бит 0 (POR). Единица в этом разряде свидетельствует о сбросе по
включению питания.
Бит 1 (EXTR). Сброс вызван внешним сигналом на входе RESET.
Бит 2 (WDTR). Сброс вызван сторожевым таймером.
Бит 3 (POR). Сброс вызван монитором питания вследствие падения
напряжения питания до 2,6 В.
Регистр PCONP предназначен для выборочного отключения питания
периферийных устройств микроконтроллера. Каждый разряд данного реги-
стра соответствует одному из периферийных узлов микроконтроллера. Схема
соответствия показана на рисунке 1.21.1. Сброс разряда в ноль приводит к
отключению питания связанного с ним устройства.
95
Часть 2. Разработка и отладка программ с помощью
современных инструментальных средств
97
смежных числа, записанные в коде Грея, отличаются только одним каким-
либо разрядом. Код Грея в отличие от рассмотренных выше является непози-
ционным, можно сказать, подобно римской системе записи чисел.
Преобразование из обычного позиционного двоичного кода в код Грея
и обратно выполняется с помощью операций сдвига и сложения по модулю
два. Для наглядности введем обозначение для операции сдвига вправо дво-
ичного кода на разрядов (младший разряд при сдвиге теряется, стар-
ший заменяется нулем)
.
Будем применять традиционное обозначение « » не только к разряду,
но и к коду, подразумевая при этом, что операция «сложение по модулю два»
(она же «исключающее ИЛИ», она же «неравнозначность») выполняется по-
разрядно. Тогда код Грея получается из позиционного двоичного кода
по формуле
. (2.1.5)
Обратное преобразование требует циклического повторения:
или короче
. (2.1.6)
98
Таблица 2.1.1 – Форматы представления целых чисел
Тип Си Объем
Диапазон представления чисел
(компилятор RealView 4) памяти
char и unsigned char
1 байт
signed char
unsigned short
2 байта
short
unsigned int и
unsigned long 4 байта
int и long
unsigned long long
8 байт
long long
Программисту полезно запомнить двоичные и шестнадцатеричные
представления всех чисел от 0 до 15, а также некоторых других положитель-
ных и отрицательных чисел (см. таблицу 2.1.2).
Таблица 2.1.2 – 2-чные и 16-ричные представления некоторых целых чисел
Двоичный Числа без знака Числа со знаком
и (прямой код) (дополнительный код)
16-ричный Числовое Пример Числовое Пример
коды значение для значение для
99
31 30 23 22 0
S P M
Знак Порядок Мантисса
8 разрядов 23 разряда
63 62 52 51 0
S P M
Знак Порядок Мантисса
11 разрядов 52 разряда
0 0 0 0
0 0 0
0 255 1023
неопреде-
>0 255 1023
ленность
101
2.2.1 Структура программы
Упрощено структуру программы на языке Си можно показать так:
Директивы компилятора
Объявление глобальных переменных
Объявление функций и процедур обработки прерываний
int main()
{
Объявление локальных переменных основной программы
Блок, выполняемый однажды
while (1)
{
Блок, выполняемый циклически
}
}
Программа обычно начинается с одной или нескольких директив ком-
пилятора, например, предназначенных для подключения стандартных биб-
лиотек. Далее следует раздел объявления глобальных переменных. Функции
и процедуры обработки прерываний включаются в программу до основной
программы. Основная программа и каждая функция может иметь раздел объ-
явления локальных переменных.
Комментарии обозначаются двумя способами. Однострочные коммен-
тарии начинаются с двух символов «слэш»
// Однострочный комментарий
Многострочный комментарий начинается символами «/*» и заканчивается
теми же символами в обратном порядке «*/»
/*
Многострочный комментарий
*/
Символы после «//» до конца строки, а также между «/* */» иг-
норируются компилятором.
2.2.2 Числовые константы
Целочисленные константы записываются в десятичной, восьмеричной
или шестнадцатеричной системе счисления. Восьмеричные числа начинаются
с нуля; шестнадцатеричные обозначаются предшествующими символами 0x.
Символьная константа (один символ, заключенный в апострофы) яв-
ляется тоже, на самом деле, является числовой. Вместо символа подставляет-
ся его ASCII-код размером 1 байт. Символ соответствует типу char.
Ниже предложены несколько примеров записи целочисленных кон-
стант, причем, идентичных с точки зрения машинного представления.
90 // Десятичное число 90
0132 // Число 90, представленное в 8-ричной форме
0x5A // Число 90, представленное в 16-ричной форме
'Z' // Символ Z, с кодом 90
102
Дробные (вещественные) числа записываются через точку, отделяю-
щую целую часть от дробной, либо в экспоненциальном формате. Например,
следующие две записи эквивалентны
0.00125
12.5E–4 // 12.5*10^(-4)=0.00125
2.2.3 Переменные и именованные константы
Любая переменная должна быть объявлена до того, как впервые упо-
минается в программе. Синтаксис объявления переменной следующий
Тип Имя1, Имя2, ... ;
или
Тип Имя1 = Значение1, Имя2 = Значение2, ... ;
Здесь Тип — один из типов данных, рассмотренных в разделах 2.1.2, 2.1.3;
Имя — идентификатор (имя переменной); Значение — значение, которое бу-
дет присвоено переменой по умолчанию (указывать не обязательно). Допус-
кается через запятую перечислять несколько однотипных переменных.
Имя переменной подчиняется правилам, общим для большинства
языков программирования: состоит из латинских букв, цифр и символа под-
черкивания, первый символ не должен быть цифрой. Внимание! В Си разли-
чаются малые и прописные буквы в именах переменных.
Пример объявления четырех переменных с именами Var1–Var4:
char Var1;
unsigned int Var2=0x80000000, Var3=0;
float Var4=7.5;
Блок объявления переменных может быть расположен:
1) до основной программы (объявление глобальных переменных);
2) в начале основной программы (первая запись после открывающейся
операторной скобки «{»);
3) в начале каждой функции.
В зависимости от того, где объявлены переменные, они являются гло-
бальными (доступны в любой функции) или локальными (доступны в преде-
лах функции или основной программы). Первый вариант размещения дает
глобальные переменные, второй и третий — локальные. Если локальных пе-
ременных немного, компилятор использует для их хранения регистры обще-
го назначения R0–R12. Это сокращает расход памяти и увеличивает быстро-
действие программы. Поэтому локальным переменным следует отдавать
предпочтение.
Помимо переменных могут также использоваться именованные кон-
станты. Объявляются они также, но с ключевым словом const.
const Тип Имя1 = Значение1, Имя2 = Значение2, ... ;
Пример:
const double pi=3.141592653589793238462643383;
Так можно создавать массивы данных, объем которых превышает
объем оперативной памяти. Константы при этом размещаются в ПЗУ.
103
2.2.4 Оператор присваивания, выражения и операции
Общая форма оператора присваивания такова
Переменная = Выражение ;
Допустимо присваивание нескольким переменным одного и того же
значения в одном операторе
Переменная1 = Переменная2 = ... = Выражение ;
Выражения конструируются с участием других переменных, число-
вых констант и знаков арифметических и логических операций. Выполнение
операций выполняется в порядке их приоритетов.
Основные операции с комментариями и примерами приведены в таб-
лице 2.2.1. В правой колонке указаны приоритеты операций (1 — самый вы-
сокий, 12 — самый низкий). Для изменения приоритета, как обычно, служат
круглые скобки «( )». Операции над выражениями в скобках имеют первый
(высший) приоритет.
Часто новое значение переменной рассчитывается с использованием
старого. Тогда одна и та же переменная оказывается и слева, и справа от зна-
ка присваивания. В этом случае удобна сокращенная форма записи оператора
присваивания, которая имеет следующий общий вид.
Переменная Операция = Выражение ;
Эта запись тождественна следующей привычной форме
Переменная = Переменная Операция (Выражение) ;
Здесь скобки показывают, что какой бы ни была Операция, Выражение вы-
числяется в первую очередь, потому что сокращенная форма имеет низший
14-ый приоритет. В качестве примера рассмотрим две команды, которые да-
дут одинаковый результат.
A=A*(B+С);
A*=B+С;
2.2.5 Условный оператор
Условный оператор предназначен для выбора одного из выражений в
зависимости от некоторого условия. Обычно с целью присваивания. Форма
записи условного оператора следующая
Условие ? Выражение1 : Выражение2 ;
Результатом является Выражение1, если Условие не равно нулю. В
противном случае, результат — Выражение2.
Приведем пример.
A=B+(C<0?-1:1);
Здесь переменной A будет присвоено значение B, увеличенное или умень-
шенное на единицу в зависимости от знака переменной C.
2.2.6 Приведение и преобразование типов
Если в выражении участвуют операнды разных типов, то они приво-
дятся к одному типу по следующим правилам:
104
Таблица 2.2.1 – Основные операторы языка Си
Опер. Описание Пример Примечание Приор.
* Обращение по адресу *A Обращение к данным, по адресу в указателе 2
& Взятие адреса &A Возвращает 32-разрядный адрес переменной или константы 2
! Логическое НЕ !A Результат 1, если операнд равен 0, иначе 0 2
~ Поразрядное НЕ ~A 2
++ Инкремент ++A или A++ Увеличение операнда на 1 до или после использования 2
–– Декремент ––A или A–– Уменьшение операнда на 1 до или после использования 2
* Умножение A*B 3
Для целочисленных операндов дает целую часть от деления,
/ Деление A/B 3
округленную до меньшего по модулю
% Остаток от деления A%B Только для целочисленных операндов 3
+ Арифметическое сложение A+B 4
– Арифметич. вычитание A–B 4
>> Сдвиг вправо A >> B 5
Второй операнд обозначает число разрядов сдвига
<< Сдвиг влево A << B 5
> Больше A>B 6
< Меньше A<B 6
Результат 1, если неравенство справедливо, иначе 0
>= Больше или равно A >= B 6
<= Меньше или равно A <= B 6
== Равно A == B Результат 1, если неравенство или равенство 7
!= Не равно A != B справедливо, иначе 0 7
& Поразрядное И A&B 8
^ Поразрядное исключ. ИЛИ A^B 9
| Поразрядное ИЛИ A|B 10
&& Логическое И A && B Результат 1, если оба операнда не равны 0, иначе 0 11
|| Логическое ИЛИ A || B Результат 1, если один из операндов не равен 0, иначе 0 12
105
1. Приведение типов выполняется попарно в порядке приоритетов
операций. То есть, сначала приводятся типы операндов связанных операцией
с наивысшим приоритетом.
2. Если в операции участвуют знаковые и беззнаковые операнды, ре-
зультат приводится к беззнаковому типу. Знак теряется.
3. Если в операции участвуют операнды разной длины, то результат
будет иметь длину наибольшего из операндов. Правило касается как чисел с
фиксированной точкой, так и с плавающей.
4. Если в операции участвуют операнды с фиксированной и с плава-
ющей точкой, результат приводится к формату с плавающей точкой.
Пример 1:
int A=75, B=10;
double C;
...
C=A/B; // C=7
Здесь операнды имеют один и тот же тип. Поэтому преобразование типов не
производится, несмотря на то, что для сохранения результата деления без по-
терь информации необходим формат с плавающей точкой.
Нередко это становится причиной ошибок даже с константами.
X=Y/2;
даст всегда целый результат, потому что 2 интерпретируется как целочис-
ленная константа, в то время как
X=Y/2.0;
дает дробный результат, если X вещественного типа (float или double).
Пример 2:
int A=–1;
unsigned int B=10;
double C=1, D;
...
D=A*B*C; // D=4294967286
Результат умножения A*B в соответствии с правилом 2 получает беззнаковый
тип. В то же время изменение порядка множителей даст другой результат.
int A=–1;
unsigned int B=10;
double C=1, D;
...
D=C*A*B; // D=–10
Результат умножения C*A в соответствии с правилом 4 сразу приводится к
формату с плавающей точкой, поэтому в дальнейшем потери знака не проис-
ходит.
В рамках выражения можно принудительно преобразовать тип одного
из операндов или части выражения, указав перед ним тип в скобках.
int A=–1;
106
unsigned int B=10;
double D;
...
D=(int)(A*B); // D=-10
И то же с примером 1:
int A=75, B=10;
double C;
...
C=(double)A/B; // C=7.5
C=A/(double)B; // C=7.5
2.2.7 Массивы
Массив — это совокупность однотипных элементов, которые иденти-
фицируются по индексу или нескольким индексам.
Одномерные массивы объявляются следующим образом
Тип Имя[Размерность]={Значениие1, ... ,ЗначениеN};
Массивы могут быть многомерными. Рассмотрим синтаксис для дву-
мерных массивов.
Тип Имя[Размерность1][Размерность2]=
{{Знач.11, ... ,Знач.1N}, ... ,{Знач.M1, ... ,Знач.MN}};
Начальные значения при объявлении присваивать не обязательно. В
то же время, если присваивание выполняется, можно не указывать размер-
ность, поставив две скобки подряд «[]». Тогда размерность автоматически
определяется числом элементов в фигурных скобках.
Обращение к элементам массива производится с указанием индексов
в квадратных скобках
A[5]
B[m][n]
В Си индексация элементов массива всегда начинается только с нуля.
Индекс является смещением относительно базового адреса.
Часто применяется компактная запись, сочетающая обращение к эле-
менту массива с изменением индекса:
A[k++]=...
...=B[m][++n]
В первом случае выборка элемента массива из памяти предшествует инкре-
менту индекса, во втором используется уже инкрементированный индекс.
2.2.8 Строки символов
Строка представляет собой одномерный массив элементов типа char,
последний из которых всегда равен нулю (обозначает конец строки). Строко-
вые константы записываются в двойных кавычках. Ниже приведены эквива-
лентные примеры
char S[7]="Превед";
char S[7]={'П','р','е','в','е','д',0};
107
Обратим внимание на то, что в основной программе строковую кон-
станту нельзя присвоить строковой переменной, также как нельзя одной ко-
мандой присвоить значение массиву. Это допустимо только в разделе объяв-
ления переменных. Вместе с тем строковые константы, заключенные в ка-
вычки могут быть параметрами функций.
Для символов, которые невозможно набрать с клавиатуры, преду-
смотрено специальное обозначение: «\xКод». Код используется шестнадца-
теричный. Например
"I \x01 ARM7" // Дает "I ♥ ARM7"
2.2.9 Структуры
Структура, в отличие от массива, — это совокупность разнотипных
данных, называемых полями, идентифицируемых по имени. Среди полей мо-
гут быть и массивы. Объявление структуры имеет вид
struct
{
Объявление1 ;
...
ОбъявлениеN ;
} Имя ;
При обращении к элементам структуры ее имя отделяется от имени
поля точкой, например
Structure1.Field2=...
Может быть задано начальное значение, например:
struct
{
int Header;
int CRC;
char Data[8];
} Frame={0x12345678,0,{1,2,3,4,5,6,7,8}};
2.2.10 Объединения
Объединения дают возможность обращаться к одной и той же области
памяти, как к данным разных типов.
union
{
Объявление1 ;
...
ОбъявлениеN ;
} Имя ;
Обычно (но не обязательно) все элементы объединения имеют одну и
ту же длину. Приведем пример записи области памяти как массива четырех
байтов и чтения той же области уже как числа с плавающей точкой, состоя-
щего из этих байтов.
108
union
{
float F;
char C[4];
} Buffer;
...
for (k=0; k<4; k++) Buffer.С[k]=...;
...=Buffer.F;
2.2.11 Указатели
Указатель представляет собой 32-разрядную величину, хранящую ад-
рес переменной произвольного типа. При объявлении указателя после типа
данных ставится символ «*», например,
float* F;
Фактически с помощью указателей в Си реализуется косвенная адре-
сация. Присваивание указателю числовой константы недопустимо, в принци-
пе возможно и осуществляется так.
Имя_указателя = ( Тип* ) Значение;
Например, в нашем случае
F=(float*)0x40000010;
Однако это изменит не данные, а адрес, на который ссылается указатель. При
программировании для ARM7 распределение памяти, как правило, полно-
стью доверяется компилятору. В таком случае с уверенностью сказать, что
конкретный адрес памяти свободен, — невозможно. Поэтому инициализация
(присваивание значения) указателя обычно выполняется так
F=&D;
Здесь D — имя переменной, а & оператор взятия адреса (таблица 2.2.1). Такая
команда приведет к тому, что указатель F будет ссылаться на переменную D.
Для обращения к самим данным используется такой синтаксис
*F=23; // Запись по адресу, хранящемуся в F
...=*F; // Чтение адреса, хранящегося в F
Здесь * — оператор обращения по адресу (таблица 2.2.1).
В нашем примере следующие операции будут идентичны.
*F=...;
D=...;
В сущности, массивы тоже являются указателями на нулевой элемент
(базовый адрес). Поэтому наряду с традиционным обращением к массиву
M[2]=100;
вполне допустимо
*(M+2)=100;
2.2.12 Ветвление
Конструкция ветвления имеет следующую структуру
109
if ( Выражение )
{
... ; // Блок операторов 1
}
else
{
... ; // Блок операторов 2
}
Здесь Выражение — любое арифметическое выражение целого типа.
Если это Выражение имеет ненулевое значение, выполняется блок операто-
ров 1, иначе — блок операторов 2. Такую форму записи можно назвать пол-
ной. Сокращенная форма записи не содержит ветви else.
Если блок операторов состоит лишь из одной команды, то оператор-
ные скобки { } можно опустить.
Пример 1
if ((A>0) && B) // Выполнить операторы 1–2, если
{ // A>0 и B≠0
Оператор 1 ;
Оператор 2 ;
}
Else // Иначе выполнить оператор 3
Оператор 3 ;
Отметим, что в Си допустимо совмещать вычисления и проверку
условия. Приведем несколько примеров.
Пример 2.
if (--k==0) // Декремент k, если результат
{ // равен нулю, то выполнять операторы
Операторы ;
}
Пример 3.
if (k++>100) // Если k>100, то выполнять операторы
{ // После проверки увеличить k на 1
Операторы ;
}
Пример 4.
if (A|=B) // Присвоить A поразрядное ИЛИ A и B
{ // Выполнять операторы, если результат ≠0
Операторы ;
}
2.2.13 Множественное ветвление
Конструкция множественного ветвления имеет следующую структуру
switch ( Выражение )
110
{
case Значение1:
... ; // Блок операторов 1
break;
case Значение3:
... ; // Блок операторов 3
break;
...
default
... ; // Блок операторов N
}
Выполняется условный переход на одно из Значений Выражения. Ес-
ли ни одно из указанных Значений не соответствует реальному значению, то
происходит переход на точку default. Заметим, что после выполнения лю-
бого блока операторов будет продолжено выполнение операторов всех дру-
гих блоков ниже, если в конце не дать команду выхода break.
2.2.14 Цикл со счетчиком
Конструкция цикла со счетчиком имеет вид
for (Команда1; Выражение; Команда2)
{
... ; // Операторы
}
Команда1 выполняется перед выполнением всего цикла; обычно со-
держит команду присваивания счетчику начального значения. Цикл повторя-
ется пока Выражение не равно нулю; как правило, Выражение имеет вид
операции отношения вида
Счетчик < Предельное_значение
Команда2, чаще всего представляет собой инкремент или декремент счетчи-
ка, например k++. Команда1 и Команда2 могут отсутствовать. В качестве
вечного цикла можно использовать конструкцию
for (;;)
{
... ; // Операторы
}
Оператор continue досрочно прекращает текущую итерацию и
начинает следующую; оператор break досрочно завершает весь цикл.
2.2.15 Циклы с предусловием и постусловием
Конструкция цикла с предусловием имеет вид
while (Выражение)
{
... ; // Операторы
}
111
Тело цикла выполняется по крайней мере один раз независимо от зна-
чения Выражения, а затем повторяется пока целочисленное Выражение не
равно нулю. Часто используется такая конструкция для вечного цикла
while (1)
{
... ; // Операторы
}
Конструкция цикла с предусловием имеет вид
do
{
... ; // Операторы
} while (Выражение)
Если Выражение равно нулю, тело цикла не выполняется ни разу.
Здесь также допустимо использование операторов continue и break.
2.2.16 Функции
Функция объявляется по шаблону
Тип Имя(Параметр1,...,ПараметрN)
{
... ; // Тело функции
return Выражение ;
}
Если не предполагается возврат результата и включение функции в
правую часть оператора присваивания, то в качестве типа указывается пустой
тип void и оператор return опускается. Список параметров также может
быть опущен.
Вызов функции осуществляется по ее имени, после которого в скоб-
ках перечисляются параметры. Скобки обязательны, даже если параметры
отсутствуют.
С сущности в Си не существует понятия выходных параметров. Ре-
зультат может присваиваться только самой функции. Разумеется, часто этого
недостаточно.
Для того чтобы функция могла возвращать измененные данные в ос-
новную программу, в качестве параметра функции передают указатель на пе-
ременную, массив или структуру. Сам параметр и в этом случае остается
неизменным, но функция получает возможность записи в область памяти, на
которую ссылается указатель и доступную для чтения в основной программе.
При объявлении функции такие параметры описывают как указатели
(с символом * перед именем), а при вызове функции передают не саму пере-
менную, а адрес (указывая перед именем символ взятия адреса &).
Ниже приведен пример функции, иллюстрирующий передачу не-
скольких параметров, в том числе массива С.
int Function(char A, int *B, char *C)
{
112
A+=10;
C[5]=*B+A;
*B=0;
return 1;
}
int main()
{
A=5; B=10; C[5]=20;
D=Function(A,&B,C); //A=5,B=0,C[5]=25,D=1
}
Здесь при вызове функции ей передается входной параметр A (без возможно-
сти изменения) и два выходных параметра (с возможностью изменения): це-
лое B и массив C. Видно, что в результате выполнения функции A не измени-
лась, несмотря на то, что внутри функции ей присвоено новое значение. В то
же время изменилась переменная B и пятый элемент массива C. Переменная D
получила единичное значение, возвращенное через команду return.
2.2.17 Некоторые директивы компилятора
Директивы не являются частью программы и не компилируются в ин-
струкции процессора, а управляют процессом компиляции. Здесь коснемся
лишь двух наиболее часто встречающихся директив
Директива присоединения файла.
#include "Имя_файла"
или
#include <Имя_файла>
В Си-программу будет «вшит» заданный файл. Это может быть файл заго-
ловков (*.h), в котором описаны переменные, константы или функции, а мо-
жет быть другая Си-программа (*.C).
Если имя указано в двойных кавычках, то поиск файла будет осу-
ществляться сначала в текущем каталоге, где находится проект, а затем, в
стандартных каталогах компилятора. Если использованы треугольные скобки
(знаки «больше» и «меньше»), то поиск в текущем каталоге будет пропущен.
Директива подстановки имеет следующий вид.
#define Имя Значение
Такая команда вводит символическое обозначение Имя для Значения.
Далее вместо имени будет подставляться присвоенное ему значение. В отли-
чие от переменной память для постоянного хранения данных при этом не
выделяется.
2.2.18 Библиотека математических функций MATH.h
Для использования в программе математических функций необходи-
мо в начале подключить библиотеку директивой
#include <math.h>
При этом станут доступны функции, приведенные в таблице 2.2.2.
113
Таблица 2.2.2 – Основные математические функции библиотеки MATH.h
Функция Объявление функции Описание Действие
Основные
abs(x) int abs(int x) модуль целого аргумента
cbrt(x) double cbrt(double x) кубический корень
exp(x) double exp(double x) экспонента
expm1(x) double expm1(double x) экспонента, уменьшенная на единицу
fabs(x) double fabs(double x) модуль вещественного аргумента
hypot(x,y) double hypot(double x, double y) корень из суммы квадратов аргументов
ldexp(x) double ldexp(double x, int n) возвращает значение , целое
log(x) double log(double x) натуральный логарифм
log10(x) double log10(double x) десятичный логарифм
log1p(x) double log1p(double x) натуральный логарифм
sqrt(x) double sqrt(double x) квадратный корень
pow(x,y) double pow(double x, double y) возводит в степень
Округление, остаток от деления, выделение целой и дробной части
ceil(x) double ceil(double x) округление до большего целого
floor(x) double floor(double x) округление до меньшего целого
fmod(x,y) double fmod(double x, double y) остаток от деления на
возвр. нормализованную мантиссу числа
frexp(x,&n) double frexp(double x, int *n)
и экспоненциальную часть , как степень 2
modf(x,&I) double modf(double x, double *I) возвр. дробную часть , — целая часть
Тригонометрические и обратные тригонометрические
asin(x) double asin(double x) арксинус
acos(x) double acos(double x) арккосинус
atan(x) double atan(double x) арктангенс
114
Таблица 2.2.2 – Продолжение
Функция Объявление функции Описание Действие
atan2(x) double atan2(double x, double y) арктангенс отношения
cos(x) double cos(double x) косинус
sin(x) double sin(double x) синус
tan(x) double tan(double x) тангенс
Гиперболические и обратные гиперболические
acosh double acosh(double x) гиперболический арккосинус
asinh double asinh(double x) гиперболический арксинус
atanh double atanh(double x) гиперболический арктангенс
cosh(x) double cosh(double x) гиперболический косинус
sinh(x) double sinh(double x) гиперболический синус
tanh(x) double tanh(double x) гиперболический тангенс
Специальные
erf(x) double erf(double x) функция ошибок
erfc(x) double erfc(double x) дополнительная функция ошибок
lgamma(x) double lgamma(double x) логарифм гамма-функции
Тестирование чисел в формате IEE754
возвращает единицу, если
isfinite(x) double isfinite(double x)
не равен бесконечности
возвращает единицу, если
isinf(x) double isinf(double x)
равен бесконечности
возвращает единицу, если
isnan(x) double isnan(double x)
равен неопределенности
signbit(x) int signbit(double x) возвращает знаковый разряд числа
115
2.2.19 Функция создания форматированных строк SNPRINTF
Функция snprintf входит в библиотеку STDIO.h, которая подключается
директивой
#include <STDIO.h>
Основное назначение функции — перевод двоичной числовой инфор-
мации в десятичную (или другую) систему счисления, представление в фор-
мате, удобном для восприятия человеком.
snprintf(S,L,"Формат",N1,N2,...);
Здесь S — переменная строкового типа (массив char), в которую сохраняется
результат; L — целочисленная константа, на единицу превышающая число
символов в строке S; «Формат» — строка, определяющая форматирование
(см. ниже), N1, N2 и т. д. — числовые переменные или константы.
Строка формата — это произвольный текст, в который внедрены спе-
циальные символы форматирования. Функция snprintf повторит этот текст в
переменной S, а в место символов форматирования подставит числа N1, N2
по порядку. Числа будут соответствующим образом отформатированы.
Каждое обозначение формата начинается с символа «%», за которым
следуют несколько необязательных символов и один обязательный указатель
типа (рисунок 2.2.1).
Необязательные
% F W .P L T
116
Таблица 2.2.3 – Возможные значения поля «Тип»
Тип Пояснения
d Десятичное целое со знаком
u Десятичное целое без знака
o Восьмеричное целое
x, X Шестнадцатеричное целое
f, F Дробный формат
e, E Экспоненциальный формат
Таблица 2.2.4 – Возможные значения поля «Флаг»
Флаг Пояснения
Выравнивание по левому краю. Если длина строки (W) превышает
– фактическое число символов, строка дополняется нулями справа. По
умолчанию — слева (выравнивание по правому краю).
+ Отображать знак «+» для положительных чисел
Обозначать восьмеричные числа нулем слева, а шестнадцатеричные
#
символами «0x» или «0X» в зависимости от формата «x» или «X»
Дополнять слева пробелом положительные числа, резервируя пози-
пробел
цию под знак «–»
Таблица 2.2.5 – Примеры применения функции snprintf для форматирования
Числовая переменная Формат Результат
int N=123; snprintf(S,11,"%d V",N) –123˽V˽˽˽˽
int N=–123; snprintf(S,11,"%8d V",N) ˽˽˽˽–123˽V
snprintf(S,11,"%-8d V",N) 123˽˽˽˽˽˽V
int N=123; snprintf(S,11,"%8.8d V",N) 00000123˽V
snprintf(S,11,"% 8d V",N) ˽˽˽˽˽123˽V
snprintf(S,11,"% 8d V",N) ˽˽˽˽–123˽V
int N=–123;
snprintf(S,11,"%8.5d V",N) ˽˽–00123˽V
snprintf(S,11,"%+8d V",N) ˽˽˽˽+123˽V
int N=123;
snprintf(S,11,"%o",N) 710˽˽˽˽˽˽˽
snprintf(S,11,"%u",N) 4294968173
snprintf(S,11,"%x",N) ffffff85˽˽
snprintf(S,11,"%X",N) FFFFFF85˽˽
int N=–123;
snprintf(S,11,"%#x",N) 0xffffff85
snprintf(S,11,"%hX",N) FF85˽˽˽˽˽˽
snprintf(S,11,"%hhX",N) 85˽˽˽˽˽˽˽˽
snprintf(S,11,"%f",N) 3.141593˽˽
snprintf(S,11,"%8.4f",N) ˽˽3.1416˽˽
snprintf(S,11,"%.2рад",N) 3.14рад˽˽˽
float N=3.1415927; snprintf(S,11,"%-7.2fрад",N) 3.14˽˽˽рад
snprintf(S,11,"%+-7.2fрад",N) +3.14˽˽рад
snprintf(S,11,"%5.3e",N) 3.142e+00˽
snprintf(S,11,"%5.3E",N) 3.142E+00˽
117
Модификатор длины «h» заставляет считать число двухбайтным, а
«hh» — однобайтным независимо от истинного размера переменной.
Обращаем внимание на то, что функция snprintf не поддерживает тип
long long.
Таблица 2.2.5 содержит множество полезных примеров формирования
строки S из 10 символов, объявленной как char S[11].
2.2.20 Ассемблер в Си-программах
Раздел 2.6 посвящен составлению программы на ассемблере без уча-
стия Си-компилятора. Здесь речь пойдет о внедрении кода на ассемблере в
Си-программу.
Как известно, код, генерируемый Си-компилятором, в некоторой сте-
пени избыточен. Поэтому он неоптимален с точки зрения быстродействия и
(или) объема. С целью оптимизации в Си-программы внедряют фрагменты,
составленные на ассемблере. Компилятор RealView 4 поддерживает два спо-
соба, так называемые, «внедряемый ассемблер» (Embedded Assembler) и
«встраиваемый ассемблер» (Inline Assembler).
Блок внедряемого ассемблера имеет формат
asm
{
... ; // Инструкции ассемблера
}
Использование внедряемого ассемблера ограничено несколькими об-
стоятельствами:
а) вместо регистров используются «виртуальные регистры», то есть
компилятор вправе размещать данные, обозначенные как R0–R12 в произ-
вольных регистрах общего назначения;
б) доступ к регистрам R13–R15 невозможен;
в) если оптимизация кода в настройках компилятора включена, то она
будет применена и к коду внедряемого ассемблера; так что точное совпаде-
ние инструкций и исполнимого кода не гарантируется;
Фрагмент встраиваемого ассемблера всегда оформляется как функция:
asm void Имя_функции(Параметры)
{
... ; // Инструкции ассемблера
}
Ограничения, перечисленные выше для внедряемого ассемблера,
здесь не действуют. Отметим, что практически код повторяется в точности.
Так что даже команда возврата из подпрограммы (bx LR) автоматически не
будет сгенерирована компилятором.
Пример использования встраиваемого ассемблера для формирования
временной задержки рассмотрен в практическом занятии №2 (раздел 3.2.6).
118
2.3 Интегрированная среда разработки Keil µVision 4
Интегрированная среда Keil µVision — широко известное средство
разработки для микроконтроллеров. Причина ее популярности в поддержке
нескольких семейств микроконтроллеров: Intel MCS-51, Intel MCS-251, ARM
многих модификаций и Infineon XC166.
Keil µVision включает реактор исходных текстов программы; ассем-
блер; Си-компилятор; симулятор, моделирующий работу микроконтроллера;
поддержку нескольких внутрисхемных отладчиков и трассировщиков.
В данном разделе коротко рассмотрим основные приемы работы с ин-
тегрированной средой разработки Keil µVision 4.
Этот программный продукт является весьма дорогостоящим, однако в
учебных целях может свободно использоваться некоммерческая версия с
ограничением объема используемой памяти 32 кбайта. Этого вполне доста-
точно для полноценного обучения программированию.
2.3.1 Создание проекта
Стандартный ярлык для запуска среды Keil µVision изображен на ри-
сунке 2.3.1.
119
Рисунок 2.3.2 – Диалоговое окно выбора типа микроконтроллера
120
Рисунок 2.3.5 – Контекстное меню проекта
По умолчанию отладка программы производится в режиме симуля-
ции. Симулятор моделирует работу реального микроконтроллера. Можно
наблюдать за пошаговым выполнением программы, за состоянием регистров,
содержимым памяти и течением модельного времени.
Если вместо компьютерной имитации работы программы предполага-
ется загрузка кода в память микроконтроллера и внутрисхемная отладка, то
необходимо настроить взаимодействие с отладочной аппаратурой.
Выбор режима: симуляция или внутрисхемная отладка, производится
переключателем Use на вкладке Debug окна свойств проекта. Настройку
внутрисхемного отладчика рассмотрим на примере прибора J-Link.
Для перехода в режим аппаратной отладки следует установить пере-
ключатель Use в правое положение; в выпадающем списке выбрать J-LINK /
J-TRACE; включить опции Load Application at Startup и Run to main() (ри-
сунок 2.3.6).
Рекомендуется также вызвать диалог настройки отладчика кнопкой
Settings; в нем установить адаптивный выбор тактовой частоты опцией
Adaptive Clocking (рисунок 2.3.7) и режим сброса Hardware, halt after reset
using WP.
Внимание! Следует отметить еще одну опцию — флаг Use Memory
Layout from Target Dialog на вкладке Linker (рисунок 2.3.16). Эта опция
должна быть включена.
Отметим, что среда Keil µVision 4 не содержит средств для загрузки
программы в память микроконтроллера через последовательный интерфейс
RS-232, что поддерживается микроконтроллером LPC2148 наряду с интер-
фейсом отладки JTAG. Загрузки по RS-232 требует применения дополни-
тельных программ (см. раздел 1.5.3). Такие программы импортируют ском-
пилированный код через объектный файл в формате Intel HEX, предвари-
тельно созданный в Keil µVision. Для создания HEX-файла следует на вклад-
ке Output включить опцию Create HEX File.
121
Рисунок 2.3.6 – Выбор симулятора или отладчика
122
Простейшая программа, не содержащая функций, составляется по
следующему шаблону.
#include <LPC214x.h>
... // Объявление функций и глобальных переменных
int main(void)
{
... // Объявление локальных переменных и настройка
while (1)
{
... // Основной цикл программы
}
}
2.3.5 Компиляция программы
На этапе компиляции будет создан объектный код, готовый к записи в
память программ микроконтроллера. Компиляция выполняется нажатием
кнопки F7. При этом формируется отчет, который можно просмотреть в окне
Build Output в нижней части основного окна Keil µVision. В отчете, прежде
всего, следует обратить внимание на число ошибок (Errors) и предупрежде-
ний (Warnings). На рисунке 2.3.8 приведен пример отчета с ошибками, а на
рисунке 2.3.9 — без ошибок.
124
1
18
2
17
11
3 16
4
5
12
6
14 15
13
7
8
9
10
127
ражается общее время выполнения программы (2), а также отдельных под-
программ (3). Время рассчитывается исходя из числа прошедших машинных
тактов и тактовой частоты, заданной в свойствах проекта Options for Target
`Target 1` Target Xtal (MHz). Сброс счетчика времени производится
кнопкой (1).
1 – имена переменных;
2 – элементы массива в
десятичном представ-
2 лении;
1
3 3 – шестнадцатеричное
значение переменной
2 3
128
1 – имена регистров или
переменных;
1 2–3 – кнопки добавления
3
или удаления сигнала;
4 – способ представления
2
сигнала (аналоговый,
двоичный, временная
диаграмма);
5 – выбор диапазона по ам-
4 5 плитуде;
6 – маска (через логическое
«И»);
7 – сдвиг право
6 7
129
Рисунок 2.3.15 – Настройка размещение подпрограммы в оперативной памяти
1 2
3
131
циональный генератор. Надо сказать, что в большой степени цифровой ос-
циллограф может заменить другие измерительные приборы, выполняя функ-
ции измерения напряжения, интервалов времени и частоты.
Прежде всего, предлагается выполнить процедуру, названную автора-
ми «быстрый поиск ошибок» (раздел 2.4.1). Эта процедура позволяет с ми-
нимальными затратами времени выявить самые грубые ошибки, которые ча-
сто встречаются на практике, причем делают совершенно неработоспособной
программу и систему, которой она управляет.
Быстрый поиск не позволяет выявить ошибки в настройках перифе-
рийных устройств. Диагностике периферии посвящены разделы 2.4.2–2.4.13.
2.4.1 Быстрый поиск ошибок
Алгоритм процедуры быстрой отладки показан на рисунке 2.4.2.
Напомним, что проверка программы выполняется нажатием Ctrl+F5 и F5.
Перед началом любой диагностической операции необходимо остановить
выполнение программы кнопкой Stop.
Ошибочный режим ядра. После запуска и остановки программы,
прежде всего, следует обратить внимание на режим работы ядра (см. рисунок
2.4.1). Если после остановки программы ядро находится в режиме Us-
er/System, это нормально. Любой другой режим, чаще всего, следствие гру-
бой ошибки, причины которых перечислены ниже.
132
Начало
Остановить программу
User/System Supervisor
Режим ядра
1
Нет вечного цикла
Да
Зависание?
Нет Abort
2
Конец
Индекс массива вне
Нет Прерывание допустимого диапазона
используется? или
переполнение стека
Да
Всегда только Interrupt
Точка останова 3
в проц. обраб. прерыв.
Не сбрасывается флаг
Создать прерывающее
прерывания
событие
Да Нет
Остановка?
4
Ошибка в настройке
Возобновить работу системы прерываний
программы и повторить
прерывающее событие
5
Не включен запрос
Да Нет
Остановка? прерывания
7
Останов на команде Нет обнуления 6
ввода-вывода, VICVectAddr Нет прерывающего
выполнение команды события (ошибка в
ввода-вывода настройки периферии)
Ввод-вывод Да
верный? 8
Неверный режим
Нет
портовой линии
Проверка настроек 9
периферии.
Ошибка направления
Пошаговая проверка
портовой линии
алгоритма
10
Не выбрана
Конец
скорость порта
133
4
3
2
1
134
произошла в точке выше вечного цикла, это говорит о зависании программы.
Чаще всего такое зависание возникает в случае неудачной инициализации
внешних устройств. Например, когда ЖК модуль не отвечает на команды.
Ошибки, связанные с системой прерываний. Если прерывания не
используются, этот этап поиска ошибок следует пропустить.
Необходимо установить точку останова на любой команде внутри
процедуры обработки прерывания (рекомендуется на первой) и запустить
программу. Далее дождаться прерывающего события или создать его. Если
остановка не происходит или происходит лишь однажды, то можно предпо-
ложить возникновение одной из следующих ошибок.
● Ошибка в настройке системы прерываний. Открыть окно настройки
прерываний с помощью меню Peripherals Vectored Interrupt Controller
(рисунок 2.4.4). Основную часть окна занимает таблица, в которой перечис-
лены все источники прерываний (1–2). Требуется убедиться, что:
а) прерывание от интересующего источника (1) разрешено (6);
б) обычно, классифицировано как IRQ (3);
в) ассоциировано с нужным слотом (3) (только для IRQ);
г) адрес обработчика задан (4), то есть не равен нулю.
● Отключен запрос прерывания. Запрос прерывания от каждого ис-
точника включается через управляющие регистры соответствующего пери-
ферийного устройства. Для проверки разрешено ли формирование запроса
требуется открыть окно периферийного устройства. О проверке этих битов
сказано ниже в разделах 2.4.2–2.4.13.
● Ошибка в настройке периферии. В том же окне можно обнаружить,
что периферийное устройство (источник прерывания) вообще отключено или
неверно настроено. Поэтому запросы прерывания не генерируются.
4
5
1
6
2
136
Внимание! Порт не будет функционировать, если обращение к нему
выполняется в высокоскоростном режиме (регистры FIOx…), а высокоско-
ростной режим отключен (регистр SCS). То же и наоборот. Следует убедить-
ся, что флажки GPIOxM в окне System Control Block System Control &
Status установлены для высокоскоростного режима или сброшены для низ-
коскоростного.
2.4.2 Ввод и вывод дискретных сигналов
Для тестирования ввода дискретного сигнала рекомендуется:
1. Установить точку останова на команду обращения к порту. Коман-
да чтения обычно имеет формат:
Имя переменной = IOxPIN & Маска ;
Команда записи
IOxPIN/SET/CLR = Имя переменной & Маска ;
Маска может отсутствовать. В высокоскоростном режиме вместо IOx… ис-
пользуются FIOx….
2. При вводе добиться желаемого уровня на дискретном входе, вы-
полнив необходимые коммутации в аппаратуре. Желательно контролировать
электрический уровень на входе вольтметром или осциллограмм. При выводе
просто контролировать сигнал.
3. Открыть окно просмотра состояния портов ввода-вывода
Peripherals GPIO Slow Interface Port 0 или Peripherals GPIO Fast
Interface Port 0. На рисунке 2.4.6 показаны оба варианта.
1
2
3
4
5
138
1
2
4
5
6
3
7
8
9
10
11
12
13
14
15 17
16
18
139
2. Проверить выбор режима счетчика (17) и счетного входа (18).
3. Если счетчик при наличии внешнего сигнала не инкрементируется,
следует искать ошибку в настройке портовой линии.
2.4.6 Таймер-счетчик. Устройство захвата
1. Добиться нормального функционирования таймера.
2. Подключать источник дискретного сигнала амплитудой от 0 до 5 В
и к одному из входов CAPx.x. Открыть окно таймера.
3. Убедиться, что разрешен захват по фронту и/или срезу по крайней
мере одного из внешних сигналов (12–13).
4. Если ни один из флажков 15 не активен (закрашен серым цветом),
значит режим порта настроен неверно.
5. При изменении уровня внешнего сигнала захваченное состояние
таймера должно обновляться в окне (11). Обновление будет происходить
только при любой активности отладчика: открыть/закрыть окно таймера, вы-
полнить очередную команду (F10/F11) и т. д.
2.4.7 Широтно-импульсный модулятор
1. Во время тестирования ШИМ рекомендуется контролировать ос-
циллографом сигнал на выходах PWMx. Окно настроек вызывается пунктом
меню Peripherals Pulse Width Modulator.
Верхняя часть окна (рисунок 2.4.8) аналогична окну настроек таймера.
Ниже расположена таблица, в которой показаны настройки каждого из семи
устройств совпадения.
2
3
4
5
7
8
9
6
140
2. Необходимо убедиться, что счетчик включен (2) и не сброшен (3).
После запуска программы содержимое счетчика (1) не должно быть нулевым.
3. Пороговые значения для каждого канала отображаются в таблице
(4). Нулевой порог должен быть наибольшим, далее, чаще всего, в порядке
возрастания.
4. Обычно остановка отключена (5), а сброс счетчика включен для ну-
левого порога (видно также и в таблице в столбцах Reset и Stop).
5. Убедиться, что все задействованные каналы ШИМ включены (8).
6. Установка бита PWMSELx (7) включает управление начальной фа-
зой каждого канала.
2.4.8 Аналого-цифровой преобразователь
На этапе тестирования следует подключить к АЦП источник постоян-
ного напряжения, величину которого контролировать вольтметром или ос-
циллографом. Окно настроек АЦП открывается через меню Peripherals
A/D Converter A/D Converter 0/1 (рисунок 4.2.9).
2 1
5
3
6
4 7
8
9
10
11
12
13
15
14
141
1. Убедиться, что настройки верны: АЦП включен (1); частота (6) не
превышает 4,5 МГц; разрядность соответствует желаемой (3).
2. Убедиться, что выбран верный канал АЦП (2) и притом только
один. Выбор нескольких каналов допускается только в режиме циклического
опроса (BURST = 1).
3. Проверить, верно ли выбран способ запуска АЦП (4).
4. Поместить точку останова после цикла ожидания результата АЦП;
создать условие, при котором АЦП запустится. Если остановка не произо-
шла, следует искать ошибки в настройке узлов, запускающих АЦП (таймер
или порт ввода-вывода).
5. Если результат получен, его следует сверить с ожидаемым, прини-
мая во внимание опорное напряжение.
2.4.9 Цифро-аналоговый преобразователь
Окно управления ЦАП доступно через меню Peripherals D/A Con-
verter (рисунок 2.4.10). Ненулевое значение в поле (1) должно немедленно
приводить к установке на выходе AOUT соответствующего напряжения, ко-
торое можно измерить вольтметром или осциллографом. Если этого не про-
исходит, значит, выход P0.25 настроен неверно.
В режиме симулятора доступно поле (2) для величины опорного
напряжения. Симулятор автоматически рассчитывает выходное напряжение
(3) на основе кода и опорного напряжения.
1 – код управления напряжением;
2 – опорное напряжение, В;
3 – выходное напряжение
1
142
выходу SCK цифровой осциллограф в режиме однократной или ждущей раз-
вертки; выполнить команду передачи (F10/F11). На осциллографе должны
появиться тактовые импульсы, в окне должен установиться флаг SPIF (8).
Так же следует просмотреть сигналы на линиях MOSI, MISO.
Если при правильной настройке осциллографа осциллограмма не за-
фиксирована, значит, передача не выполнялась, вероятно, из-за ошибочного
выбора режима портовых линий.
1–2 – управление разрядностью;
3 3 – разрешение запроса прерывания;
4 4 – очередность (первый бит млад-
1 ший/старший);
5
2 5 – режим (ведущий/ведомый);
6
7 6–7 – управление полярностью и фа-
зой;
8 – диагностика;
8 9 – скорость бит/с;
10 – активность запроса прерывания
9
10
5
2
3
6
144
1. Убедиться, что приемопередатчик включен (2); проверить настрой-
ку разрядности, числа стоповых бит и четности (1).
2. В режиме симулятора доступна расчетная битовая скорость (5). Она
должна совпадать со скоростью COM-порта персонального компьютера с
ошибкой не более 5%.
3. Следует обратить внимание на число байт в буфере приемника,
накопление которых вызывает прерывание (3), а также биты разрешения пре-
рываний (7).
4. Установить точку останова внутри блока, отвечающего за обработ-
ку принятого байта и вызываемого только, если байт принят. Если ожидание
байта реализовано через прерывания, то установить точку останова внутри
процедуры обработки прерываний. Послать с персонального компьютера
один или несколько байт (не более 16) и проследить за реакцией программы.
5. Если остановки не произошло, значит либо настройки интерфейса
приемника и передатчика не соответствуют, либо неверно настроен режим
портовых линий, либо ошибка в настройке системы прерываний.
6. Если реакция есть, проверить принятый байт в поле (9).
7. Для диагностики приема рекомендуется поместить точку останова
на команду передачи (записи в UxTHR), и выполнить эту команду, наблюдая
за результатом на персональном компьютере и, по возможности, с помощью
цифрового осциллографа.
2.4.13 Часы реального времени
Окно настроек показано на рисунке (2.4.14.). Ниже даны рекоменда-
ции по проверки этих настроек.
1
3
2
6
5
4
7
8
145
1. Счетчик часов реального времени должен быть включен (1); бит
выбора источника тактирования сброшен (2), если тактирование не осу-
ществляется от основного тактового генератора.
2. Один или оба бита выбора прерывающего события (3) должны быть
установлены. И выбрано, какие именно события будут вызывать запрос пре-
рывания (5).
3. Должны быть заданы маски прерывающих событий (4, 7).
146
Основными являются поля операций и операндов. Допустимые опера-
ции и их синтаксис приведены в таблице (1.4.2)
Метка — это символьное обозначение адреса команды. Везде вместо
метки будет выполняться подстановка адреса команды, которой предшеству-
ет метка. Чаще всего метки используются в командах передачи управления.
Каждая метка должна быть уникальной и при этом является не обязательной.
В отличие от многих других версий, в ассемблере RealView метки не закан-
чиваются двоеточием («:»).
Комментарии по желанию помещаются в конце строки и отделяются
точкой с запятой («;»).
Приведем простой пример.
Label ADD R1, R1, R0, LSL #2 ; R1 = R1 + R0 << 2
...
BEQ Label ; Перейти по метке, если Z = 0
2.5.2 Псевдокоманды
Ассемблер RealView поддерживает так называемые псевдокоманды.
Псевдокоманда — это мнемоническое обозначение, которое на самом деле не
соответствует системе команд процессора, а заменяется одной или (реже) не-
сколькими командами. Псевдокоманды являются своего рода макросами и
служат для упрощения синтаксиса. Перечень поддерживаемых псевдокоманд
приведен в таблице (2.5.1).
2.5.3 Директивы ассемблера
В отличие от команд директивы не создают исполнимого кода, загру-
жаемого в память микроконтроллера. Директивы представляю собой лишь
предписания ассемблеру, управляют формированием исполнимого кода.
Рассмотрим часто используемые директивы ассемблера RealView 4.
Имя EQU Константа
Назначает Константе символьное обозначение Имя, которое стано-
вится синонимом константы. Основное назначение — введение имен управ-
ляющих регистров,
AREA Имя, Параметры
Определяет область памяти с заданным Именем. С помощью парамет-
ров указывается назначение области памяти, например, DATA (данные) или
CODE (код). От выбранного назначения зависят адреса определяемой области.
Область CODE размещается, начиная с адреса 0x00000000, область DATA — с
адреса 0x40000000. В программе обязательно должна существовать область
CODE c именем RESET. Константы, размещаемые в памяти программ, следует
объявлять в секции с парой параметров CODE, READONLY.
ENTRY
Обозначает точку входа в программу, показывает ее «начало». Одна
такая директива всегда должна присутствовать в программе. Обычно поме-
щается непосредственно после директивы AREA RESET, CODE.
147
Таблица 2.5.1 – Псевдокоманды, поддерживаемые ассемблером RealView 4
Мнемоническое обозначение
Операция Фактическая реализация
и синтаксис
Сложение или вычитание константы из PC ко-
ADR{Усл} , Загрузка адреса в регистр
мандами ADD или SUB
Загрузка адреса в регистр
ADRL{Усл} , Дважды ADD или SUB с участием PC
(расширенный диапазон адресов)
ASR{Усл}{S} , , Загрузка регистра командой MOV с использова-
Арифметический сдвиг вправо
ASR{Усл}{S} , , нием сдвигового операнда
Загрузка регистра командой LDR с косвенной
LDR{Усл} , Загрузка адреса в регистр
адресацией (PC + непосредственное смещение)
Размещение константы в памяти программ
Загрузка 32-разрядной константы в
LDR{Усл} ,= и загрузка с помощью LDR с индексной адреса-
регистр
цией. Смещением служит PC.
LSL{Усл}{S} , , Загрузка регистра командой MOV с использова-
Логический сдвиг влево
LSL{Усл}{S} , , нием сдвигового операнда
LSR{Усл}{S} , , Загрузка регистра командой MOV с использова-
Логический сдвиг вправо
LSR{Усл}{S} , , нием сдвигового операнда
Восстановление регистров командой
POP{Усл} Восстановить регистры из стека
LDMIA R13!,{...}
Сохранение регистров командой
PUSH{Усл} Сохранить регистры в стек
STMDB R13!,{...}
ROR{Усл}{S} , , Загрузка регистра командой MOV с использова-
Циклический сдвиг вправо
ROR{Усл}{S} , , нием сдвигового операнда
Циклический сдвиг вправо через Загрузка регистра командой MOV с использова-
RRX{Усл}{S} ,
перенос на 1 разряд нием сдвигового операнда
148
Имя SPACE Размер
Резервирует память для хранения данных заданного Размера. Имя
становится синонимом адреса зарезервированного пространства. Единство
адресного пространства позволяет применять эту директиву, как для посто-
янной, так и для оперативной памяти. Основное назначение — создание гло-
бальных переменных в оперативной памяти (в области DATA).
Метка DCB/DCW/DCD Константа
«Прошивают» данные (числовые Константы) в памяти программ.
Метка становиться синонимом адреса, по которому будут записаны данные.
Разные директивы (DCB, DCW и DCD) служат для данных разного размера:
байт, 16-разрядное слово, 32-разрядное слово (соответственно).
END
Служит признаком конца файла. Весь текст после этой директивы иг-
норируется ассемблером.
2.5.4 Макросы
Макрос представляет собой предопределенный фрагмент программы,
выполняющий какую-либо распространенную операцию. В отличие от под-
программ, вызываемых с помощью команд передачи управления, использо-
вание макросов не снижает быстродействия, но не снижает и расход памяти
программ. Потому что при каждом вызове макроса ассемблер внедряет в
программу полностью его текст.
Для объявления макроса служит следующая конструкция
MACRO
Имя $Параметр1, $Параметр2, ...
...
MEND
Параметры позволяют модифицировать текст макроса при каждом обраще-
нии к нему. Внутри (в теле) макроса параметры используются также с пред-
шествующим знаком «$». Вместо параметров в теле макроса подставляются
параметры, указанные при вызове.
Вызов макроса осуществляется так:
Имя Параметр1, Параметр2, ...
Имеется возможность организовать проверку условия и ветвление.
IF "$Параметр" == "Значение"
...
ELSE
...
ENDIF
Обращаем внимание на то, такая конструкция не приводит к про-
граммной проверке условия микроконтроллером. Проверку условия осу-
ществляет ассемблер в ходе формирования исполнимого кода.
149
2.5.5 Пример простой программы
В качестве наглядной иллюстрации предлагаем рассмотреть простую
программу, формирующую пачки из пяти прямоугольных импульсов. После
каждой пачки следует пауза, равная по длительности тем же пяти импульсам.
В программе используется прерывание от таймера 0 и глобальная пе-
ременная счетчик Counter. Вначале счетчику присваивается значение 20. При
каждом достижении таймером порога значение счетчика декрементируется,
формируется перепад на портовой линии P0.7. Генерирование импульсов не
производится, если счетчик больше десяти. При достижении счетчиком нуля
ему снова присваивается значение 20 и цикл повторяется.
IO0PIN EQU 0xE0028000
IO0DIR EQU 0xE0028008
T0IR EQU 0xE0004000
T0TCR EQU 0xE0004004
T0MCR EQU 0xE0004014
T0MR0 EQU 0xE0004018
VICIntEnable EQU 0xFFFFF010
VICVectAddr EQU 0xFFFFF030
VICVectAddr0 EQU 0xFFFFF100
VICVectCntl0 EQU 0xFFFFF200
MACRO
LoadConst $Val, $Reg, $Length
LDR R0, =$Reg
IF "$Length" == "Short"
MOV R1, #$Val
ELSE
LDR R1, =$Val
ENDIF
STR R1, [R0]
MEND
B Start
SPACE 16
150
DCD 0x77BFA08A
LDR PC, [PC, #-0x0FF0]
SPACE 4
Start
MSR CPSR_c, #0x12
LDR SP, =StackBottom+1024
MSR CPSR_c, #0x10
Loop B Loop
Timer0Int
STMDB SP!, {R0-R3}
END
151
Дадим некоторые пояснения. Текст программы начинается с объявле-
ния имен регистров. Стандартным именам присваиваются соответствующие
адреса директивой EQU.
Далее объявлен макрос LoadConst, содержащий команды загрузки ко-
манды в управляющий регистр. Макрос имеет три параметра: загружаемая
числовая константа (Val), адрес регистра (Reg) и модификатор (Length). С
помощью директив IF…ELSE…ENDIF загрузка осуществляется либо командой
MOV, либо LDR. Если константа может быть предоставлена в виде сдвигового
12-разрядного операнда, передается параметр Length = Short и выполняется
команда MOV, иначе загрузка выполняется командой LDR.
Директива AREA…DATA определяет область памяти для стека. А SPACE
резервирует под стек 1024 байта. Начало этой области получает имя Stack-
Bottom.
Аналогично создается глобальная переменная Counter размером
4 байта.
Область кода программы объявляется директивой AREA…CODE.
Первой инструкцией программы является команда безусловного пере-
хода на точку входа, обозначенную ниже меткой Start.
В области векторов прерываний занята командой передачи управле-
ния процедуре обработки прерываний (LDR PC, [PC, #-0x0FF0]), а также
контрольной суммой (директива DCD). Директивы SPACE заполняют пустые
пространства.
Основная программа начинается после метки Start. Первые три стро-
ки: перевод ядра в режим IRQ; инициализация указателя стека (SP) режима
IRQ; перевод ядра в режим User. Здесь инициализация стека выполняется пу-
тем загрузки в него суммы базового адреса стека и объема стека (1024 байта),
зарезервированного ранее.
С помощью макроса LoadConst выполняется настройка портовой ли-
нии, таймера и системы прерываний; присваивается начальное значение пе-
ременной-счетчику Counter.
Основная программа завершается командой вечного цикла (переход
на метку Loop).
Ниже размещается подпрограмма обработки прерываний (метка
Timer0Int). Вначале сохраняются в стек регистры R0–R3 (команды STMDB).
Далее выполняется декремент счетчика и присваивание начального
значения (20) в случае равенства нулю.
Следующий блок пропускается (метка Skip), если счетчик больше 10.
Блок содержит команды инверсии портовой линии.
Далее выполняется обычная процедура возврата из прерывания: с по-
мощью макроса LoadConst снимается флаг запроса прерывания и обнуляется
регистр VICVectAddr. Регистры общего назначения восстанавливаются из
стека, выполняется возврат командой SUB с участием счетчика команд.
152
2.6 Распространенные средства разработки и отладки
2.6.1 Демонстрационные платы EA-EDU-001 и EA-EDU-011
Одной из наиболее удачных демонстрационных плат на основе мик-
роконтроллеров семейства LPC2000, по мнению авторов, является плата EA-
EDU-001 производства фирмы Embedded Artists. На рисунке 2.6.1 приведена
фотография платы, а на рисунке 2.6.2 схематично изображено размещение
основных электронных узлов с указанием линий микроконтроллера, управ-
ляющих ими.
Плата EA-EDU-001 сочетает разнообразие установленных устройств и
возможность расширения благодаря 50-контактому разъему, к которому под-
ключено большинство портовых линий микроконтроллера.
Причислим устройства, установленные на плате:
1) микроконтроллер LPC2148 с кварцевыми резонаторами 12 МГц и
32768 Гц;
2) восемь светодиодов, подключенных к порту ввода-вывода;
3) трехцветный светодиод, подключенный к трем каналам ШИМ;
4) кнопка, подключенная к входу запроса внешнего прерывания;
5) джойстик, состоящий из пяти кнопок;
6) два потенциометра, подключенных к входам АЦП;
7) динамик, подключенный к выходу ЦАП;
8) фильтр нижних частот, для получения постоянного напряжения с
помощью ШИМ;
9) символьный ЖК индикатор 16×2 символа (LMB162A);
10) светодиодная матрица 8×8 точек (LMD08088);
11) миниатюрный шаговый двигатель (20BY20L033);
153
USB
Память EEPROM UART0 D–/D+ – прием/передача
SDA0 – данные TxD0 – передача P0.23 – Vbus
SCL0 – тактирование RxD0 – прием P0.31 – Connect
Трехцветный светодиод
P0.7/PWM2 – красный
P0.8/PWM4 – синий
Flash-карта MMС/SD
P0.9/PWM6 – зеленый
MOSI0 – передача
MISO0 – прием
SCK0 – тактирование
P0.11 – CS Жидкокристаллический
индикатор
Светодиодная матрица
P1.16–P1.23 – D0–D7 (данные)
MOSI0 – передача
P1.24 – RS (команда/данные)
MISO0 – прием
P0.22 – RW (чтение/запись)
SCK0 – тактирование
P1.25 – E (стробирование)
P0.15 – CS
P0.30 – подсветка
Динамик
AOUT
154
Рисунок 2.6.2 – Схема размещения компонентов учебной платы EA-EDU-001 с указанием адресов каналов управления
Рисунок 2.6.3 – Фотография платы расширения EA-EDU-011
Ethernet
P0.14 – INT
MOSI0 – передача
MISO0 – прием
SCK0 – тактирование
P0.14 – CS
Джойстик
P0.8 – центр
P0.10 – вверх
P0.11 – вправо
P0.9 – влево
P0.12 – вниз
155
Рисунок 2.6.4 – Схема размещения компонентов учебной платы EA-EDU-011
с указанием адресов каналов управления
12) электрически перепрограммируемое ПЗУ емкостью 2 кбита
(CAT1025);
13) цифровой датчик температуры (LM75);
14) разъем карт памяти MMS/SC;
15) мост USB/UART (FT232R);
16) интерфейс USB;
17) интерфейс JTAG.
Питание платы осуществляется либо от порта USB персонального
компьютера, либо от отдельного источника постоянного тока 9–15 В (не ме-
нее 200 мА).
50-штырьковый разъем может использоваться для расширения платы
с использованием любой аппаратуры, разработанной и сконструированной
пользователем. Фирма Embedded Artists выпускает плату расширения EA-
EDU-011, содержащая дополнительный набор устройств:
1) джойстик;
2) две кнопки и 16 светодиодов, подключенный через параллельный
порт (PCA9532);
3) цветной светодиодный экран 130×130 точек совместимый с
Nokia 6100 и контролером Philips PCF8833.
4) аналоговый трехосевой акселерометр (MMA7260QT);
5) разъем microSD;
6) интерфейс RS-232 с полным набором модемных сигналов;
7) интерфейс Ethernet 10 Мбит через мост SPI/Ethernet (ENC28J60).
Фотография платы показана на рисунке 2.6.3, на рисунке 2.6.4 приве-
дена схема размещения компонентов с указанием адресов подключения к
микроконтроллерной плате EA-EDU-001.
2.6.2 Внутрисхемный отладчик J-Link
При составлении и настоящего учебного пособия авторы использова-
ли внутрисхемный отладчик J-Link фирмы Segger. Фотография прибора и его
расширенной модификации J-Link Ultra, показаны на рисунках 2.6.5, 2.6.6.
10
11
1
3
6
7 4
9
8
2
157
5) считать идентификатор устройства (после этого шага в поле Device
должен появиться теп микроконтроллера);
6) если это необходимо установить флажок Execute Code after Upload
(запустить программу после загрузки);
7) нажать кнопку Upload to Flash; начнется процесс загрузки.
Помимо загрузки программы имеется возможность сравнения вы-
бранного HEX-файла с содержимым Flash-памяти микроконтроллера (8).
Сброс микроконтроллера можно выполнить кнопкой (9).
Программа Flash Magic позволяет «прошивать» микроконтроллеры и
других семейств производства NXP, например 8051. Для записи исполнимого
кода необходимы следующие действия: выбрать тип устройства кнопкой
Select Device (1); выбрать последовательный порт (2); выбрать скорость пе-
редачи данных (не более 38400 бит/с) (3); ввести частоту кварцевого резона-
тора в мегагерцах (4); выбрать загружаемый HEX-файл (5); нажать кнопку
Start (6).
1
2
3
158
нажать кнопку (1). Флаги (3–4) позволяют выбрать формат передаваемой и
принимаемой информации.
Для передачи символа, он или его код вводится в поле 5 и нажимается
кнопка Send (6). Если нужно передать несколько символов в формате ASCII,
они водятся подряд. Если передается последовательность кодов, то они раз-
деляются запятой. Причем запятая ставится и в конце последнего кода. Над
строкой (5) появляется подсказка с примером.
1 2 3 4 5 6
159
Часть 3. Решение типовых задач локального управления
1
Настройка портовых
линий P0.7–P0.9
Да 2 Нет
k=1; k<N; k++
3
Инверсия P0.7
160
В начале вечного цикла организовать цикл задержки
for (k=0; k<N ; k++) ;
где N — число итераций, которое можно приближенно принять равным
100 000.
3. После цикла задержки инвертировать портовую линию с помощью
команды сложения по модулю два.
IO0PIN^= Код ;
где Код содержит единственную единицу в седьмом разряде (соответственно
разряду порта P0.7).
Провести компиляцию проекта (F7) исправить синтаксические ошиб-
ки, если они имеются.
3.1.4 Отладка
Поскольку это первое задание, несмотря на его исключительную про-
стоту подробно рассмотрим порядок отладки программы. Таким образом
продемонстрируем на конкретном примере приемы отладки, подробно рас-
смотренные в разделе 2.4. Итак, рекомендуется придерживаться следующего
порядка действий.
1. Перевести среду в режим отладки (Ctrl+F5). При этом работает си-
мулятор. Запись программы в память микроконтроллера не производится.
2. Проследить за пошаговым выполнением программы (F11).
3. Установить точку останова на команду инверсии порта (двойной
щелчок по серому полю слева). Открыть окно порта ввода-вывода (Periph-
erals GPIO Port 0).
4. Несколько раз запустить программу до точки останова (F5). Про-
следить периодическое изменение состояния портовой линии в окне.
5. Открыть окно логического анализатора (раздел 2.3.7). Получить ос-
циллограмму сигнала лини P0.7.
6. Определить время выполнения одной итерации с помощью окна
хронометража (раздел 2.3.7).
7. Вернуться в режим программирования (Ctrl+F5). Откорректировать
предельное значение счетчика так, чтобы время итерации составило 0,5 с.
Скомпилировать программу.
8. Вызвать свойства проекта. Выбрать в качестве инструмента внут-
рисхемный отладчик (раздел 2.3.3).
9. Перейти в режим отладки (Ctrl+F5). Переход будет сопровождаться
загрузкой кода программы в память микроконтроллера.
10. Запустить программу нажатием кнопки F5. Убедиться в работо-
способности программы.
3.1.5 Дополнительные сведения о формировании временной задержки
Несмотря на указанные недостатки, формирование временной за-
держки с помощью пустого цикла применяется в некоторых случаях (напри-
мер, практическое занятие №10).
161
В дальнейшем предлагается вместо пустого цикла for использовать
следующую функцию, составленную из инструкций ассемблера. Внедрение
кода на ассемблере позволяет получить наименьший возможный шаг в
настройке длительности импульса.
asm void Delay(int R0) // Параметр R0 -
{ // число повторов
subs R0, R0, #1 // Уменьшение счетчика на 1
bne {PC}-4 // Повтор, если не равен 0
bx LR // Возврат из функции
}
Обращаем внимание на то, что в строках ассемблера необходим от-
ступ хотя бы в один пробел.
С помощью такой функции последовательность прямоугольных им-
пульсов может быть сформирована так:
while (1)
{
FIO0SET= Маска ; // Высокий уровень
Delay( Числовая константа ); // Задержка
FIO0CLR= Маска ; // Низкий уровень
}
Заметим, что здесь используется управление портом ввода-вывода че-
рез высокоскоростную шину (раздел 1.10.2).
, (3.1.2)
где — длительность такта (по умолчанию нс),
— числовая константа, передаваемая функции Delay в качестве пара-
метра; — числа тактов, выделяемых для считывания команд из памяти,
которое по умолчанию равно 4 (о модуле ускорения памяти см. раздел 1.8).
162
Минимальный период, который может быть получен таким способом
нс, минимальная длительность импульса нс. Ми-
нимальный шаг настройки нс.
На рисунке (3.1.2) показана осциллограмма импульсов на одной из
портовых линий микроконтроллера, генерируемых приведенной выше про-
граммой. Использовались следующие параметры: нс, ,
, что с тактовой частой МГц приводит к периоду импуль-
сов нс и длительности нс.
Для сравнения приведем осциллограмму сигнала (рисунок 3.1.3),
формируемого кодом без временной задержки при нулевом уровне оптими-
зации кода.
while (1)
{
FIO0SET= Маска ;
FIO0CLR= Маска ;
}
163
долей миллисекунд. Недостаток в том, что программа «зависает» на 0,5 с и
не может выполнять никаких других задач, кроме «мигания светодиодом».
На практике формирование временной задержки производится с помощью
таймера, схемы совпадения и системы прерываний. Настройка таймера и
схемы совладения производится так, чтобы каждые 0,5 с вырабатывался за-
прос прерывания. Процедура обработки прерывания, вызываемая при этом
автоматически, содержит команду инверсии порта. В этом случае микро-
контроллер свободен для выполнения любого алгоритма, поскольку ожида-
ние обеспечивается аппаратурой микроконтроллера параллельно.
Отметим, что низкая частота сигнала, которую предстоит получить на
выводе P0.7 выбрана лишь для лучшей визуализации работы программы. Во-
обще предлагаемое решение можно применять при частотах сигнала до сотен
килогерц. Алгоритм решения задачи показан на рисунке 3.2.1.
Основная программа Процедура обработки прерывания
Начало Начало
1 7
Настройка портовых Инверсия
линий на вывод портовой линии
4
2 Настройка системы 8
Настройка таймера: прерываний Сброс флага
вкл. сброс и запроса прерывания
запрос прерывания 5
Запуск таймера 9
3 Инициализация
Задание порогового системы прерываний
значения для таймера 6
Пустая команда
Конец
165
Начало 2
Скопировать порт
1 в NewPort
Настройка портовой
с наложением маски
линии на вывод
Да 3 OldPort>0 и
NewPort=0
4 Нет
Инверсия P0.7
5
OldPort=NewPort
167
Броски напряжения, вызванные дребезгом, устраняются включением
конденсатора небольшой емкости параллельно контактам. Существует также
надежное программное решение, которое будет рассмотрено далее.
Идея состоит в том, чтобы, распознав однажды нажатие кнопки пре-
кратить опрос на 10–50 мс. Этого времени вполне достаточно, чтобы контак-
ты надежно замкнулись или разомкнулись, но слишком мало, чтобы пропу-
стить действительное нажатие кнопки.
Предлагается сформировать интервал времени для блокировки клави-
атуры с помощью таймера. Использование механизма прерываний здесь из-
лишне; проще организовать периодический опрос флага совпадения таймера
с пороговым значением.
Алгоритм решения поставленной задачи показан на рисунке 3.5.4.
Начало
5 Да
1 Совпадение
Настройка портовых 6
линий на вывод Скопировать порт
Нет
в NewPort
2 с наложением маски
Настройка таймера:
вкл. сброс, остановку,
запрос прерывания
7 Да
3 OldPort≠NewPort
Задание порогового 8
значения для таймера Сброс запроса
Нет
прерывания
4
Запуск таймера 9
Запуск таймера
10
Обработка реакций
11
OldPort = NewPort
168
ми. Заметим, что после установки флага обновление содержимого порта в
NewPort осуществляется периодически в каждой итерации главного цикла.
2. Условие 7 предназначено для распознавания изменения в состоянии
кнопок. Заметим, что это условие проверяется независимо от флага совпаде-
ния таймера, но пока NewPort не обновляется (блок 6), условие 7 всегда ложно.
3. Если состояние порта изменилось (контакты кнопок замкнулись
или разомкнулись), выполняются блоки 8–11. Сброс флага совпадения при-
ведет к тому, что при следующей проверке условие 5 будет ложно. Таким об-
разом, при любом изменении клавиатура окажется заблокирована снова. За-
пуск таймера гарантирует автоматическую установку флага совпадения через
несколько миллисекунд и разблокирование клавиатуры. Блок 10 содержит
ряд следующих одно за другим условий проверки каждого бита переменной
NewPort и выполнения требуемых действий.
4. Обновление переменной OldPort (блок 11) приведет к тому, что при
следующей проверке условие 7 окажется ложным. Повторной реакции на
нажатие кнопки не произойдет. Прежде чем блоки 8–11 будут выполняться
снова состояние кнопок должно измениться, причем не ранее чем через не-
сколько миллисекунд.
3.4.3 Алгоритм программы
Потребуется объявить переменные NewPort и OldPort типа int.
1. Настроить поровую линию P0.7 на вывод путем записи управляю-
щего кода в регистр IO0DIR0 (см. раздел 1.10.1).
2. Настроить схему совпадения одного из таймеров МК через регистр
TxMCR (раздел 1.13.4). Включить остановку таймера, сброс в ноль, форми-
рование запроса прерывания. Может быть выбран любой из двух таймеров
произвольно. Также произвольно выбирается номер устройства совпадения
(0–3). Однако для определенности далее будем считать, что используется
таймер 0 и устройство совпадения 0.
3. Рассчитать пороговое значение для таймера по формуле (1.13.3) так,
чтобы интервал времени, отводимый для прекращения дребезга контактов,
был от 10 до 50 мс. Напомним, чему равны тактовые частоты, необходимые
для расчета.
МГц.
4. Дать команду запуска таймера путем записи в регистр T0TCR.
Блоки 1–4 относятся к настройке узлов микроконтроллера и должны
выполняться лишь однажды при сбросе. Блоки ниже помещаются в тело
«вечного» цикла.
while (1)
{
...
}
5. Записать команду проверки флага совпадения таймера. Анализиро-
вать содержимое регистра с наложением маски.
169
6. Если обнаружено совпадение таймера с пороговым регистром, при-
своить переменной NewPort содержимое порта 0. При этом необходимо с по-
мощью операции логического умножения наложить маску, обеспечив копи-
рование единственного бита P0.14 (подробнее см. раздел 1.10.1).
7. Проверить неравенство переменных OldPort и NewPort. Команды,
соответствующие блокам (9–11) должны выполняться при неравенстве этих
переменных.
8. Сбросить флаг запроса прерывания через регистр T0IR. Напомним,
что сброс флага выполняется записью единицы, а не нуля.
9. Запустить таймер через регистр T0TCR.
10. Поместить блок реакции на нажатие кнопок, в данном случае со-
стоящий одного условия, проверяющего бит 14 регистра NewPort. Если бит
равен нулю дать команду инверсии линии P0.7. Для этого использовать сло-
жение по модулю два регистра IO0PIN с константой.
11. Обновить переменную OldPort.
3.4.4 Отладка
Ниже названы некоторые причина возможных ошибок.
1. Не работает таймер, флаг T0IR не устанавливается. Установить
точку останова на команде, соответствующей блоку (5). Запустив программу,
проверить, достигается ли периодически эта команда. Если нет, то просле-
дить за состоянием таймера в окне Peripherals Timer Timer 0. Убе-
диться, что таймер инкрементируется, все три события по совпадению (оста-
новка, сброс, запрос прерывания) разрешены, что модуль счета достаточно
мал для быстрого совпадения.
2. Порт не считывается или неверно маскирование. Установить точку
останова на команду блока 8; запустить программу; нажать кнопку на плате.
Ошибка диагностируется, если останова при этом не происходит. Проверить
маскирование (блок 6), условие (блок 7). Рекомендуется использовать про-
смотр переменной NewPort через окно Watch.
3. Неверно условие проверки битов переменной NewPort (блок 10).
Установить точку останова на команду инверсии линии P0.8. Если при нажа-
тии кнопки (притом что отладка по пунктам 1–3 ошибок не выявила) состоя-
ние портовой линии не меняется, искать ошибку в командах блока 10.
4. Дребезг сохраняется из-за неверной инициализации схемы совпаде-
ния. Проверить команды блоков 8 и 9.
5. Состояние портовой линии меняется и при нажатии, и при отпуска-
нии кнопки. Проверить команду блока 11.
171
Начало
5 Да
1 Совпадение 0
Настройка портовых 6
линий на вывод Скопировать порт
Нет
в NewPort
2 с наложением маски
Настройка схем
совпадения
3 7 Да
Загрузка таймера и Совпадение 1 или
OldPort≠NewPort
пороговых регистров 8
Сброс запроса
4 Нет
прерывания 1
Запуск таймера
9
Обработка реакций
10 Да
OldPort≠NewPort
11
Загрузка таймера
Нет
12
Сброс запроса
прерывания 0
13
OldPort = NewPort
172
Пороговое значение T0MR0 больше на величину, соответствующую
интервалу с. Вопрос выбора этого интервала обсуждался в
разделе 3.5.3.
. (3.5.2)
Рассчитав T0MR0, T0MR1, T0TC, включить в программу команды
присваивания значений этим регистрам.
4. Запустить таймер через регистр T0TCR.
5. Блоки 5–13 помещены в «вечный цикл». Проверить совпадение
MR0 путем сравнения с единицей флага MR0I в регистре T0IR. Для проверки
единственного бита необходимо выделить его наложением маски операцией
логического умножения.
6. Если совпадение произошло (флаг равен единице), обновить пере-
менную NewPort, скопировав в нее содержимое порта с наложением маски.
7. Последующие блоки выполняются при выполнении одного из усло-
вий: совпадение MR1 или неравенство переменных NewPort и OldPort.
8. В случае выполнения условия блока 7 необходимо сбросить запрос
прерывания и обеспечить обработку реакции на кнопку. В соответствии с за-
данием реакция состоит в инверсии линии порта P0.8 или P0.9 в зависимости
от нажатой кнопки P0.18 или P0.19.
9. При обнаружении изменения порта (блок 10) потребуется снова за-
грузить в таймер начальное значение, рассчитанное по формуле 3.5.1 (блок
11). Сбросить флаг совпадения 0 (блок 12), что обеспечит блокировку опроса
порта ложным условием 5. И обновить прежнее значение порта (блок 13), что
позволит обнаружить очередное изменение при следующем выполнении
блоков 7 и 10.
3.5.4 Отладка
1. Из-за неверной настройки таймера и схемы совпадения 0 нет об-
новления переменной NewPort (блок 6). Установить точку останова на ко-
манду блока 6 и, запустив программу, проверить достигается ли эта точка.
Если останова не происходит, проверить настройки таймера.
2. Из-за неверной настройки схемы совпадения 1 нет анализа измене-
ний порта. Установить точку останова на команду блока 8. Проверить дости-
гается ли она, запустив программу и нажав на кнопку учебной платы. Если
останова не происходит, проверить настройку схемы совпадения 1. Рекомен-
дуется также сопоставить содержимое порта и переменной NewPort.
3. После обработки реакции на изменение уровня таймеру не присева-
ется требуемого начального значения, в результате чего до порогового зна-
чения T0MR0 (см. рисунок) таймер доходит несколько минут. Проверить со-
держимое таймера, установив точку останова на команду блока 12.
4. Проверить команды, отвечающие непосредственно за реакцию на
изменения уровней (блок 9).
5. Состояние светодиода меняется и при нажатии и при отпускании
кнопки либо при удерживании кнопки они мигают с очень высокой частотой.
Проверить команды, отвечающие за реализацию блоков 10–13.
173
3.6 Формирование импульсного управляющего сигнала
с помощью модуля ШИМ
3.6.1 Задание
Разработать программу, генерирующую три последовательности пря-
моугольных сигналов, смещенных по фазе на 120º. Параметры сигналов: ча-
стота ; скважность (коэффициент заполнения задаются препо-
давателем). Пример осциллограммы сигнала показан на рисунке 3.6.1
174
Таблица 3.6.1 – Настройки для трехфазной системы ШИМ
Пороговые Значения пороговых регистров PWMSELx
регистры (переменная — )
PWMMR0 —
PWMMR1 0 (не имеет значения) —
PWMMR2 0
PWMMR3 0
PWMMR4 1
PWMMR5 0
PWMMR6 1
Таблица 3.6.2 – Настройки для трехфазной системы СИФУ
Пороговые Значения пороговых регистров PWMSELx
регистры (переменная — , град.)
PWMMR0 —
PWMMR1 —
PWMMR2 ¿ fP CLK + PWMMR1 1
PWMMR3 0
PWMMR4 1
PWMMR5 0
PWMMR6 1
Таблица 3.6.3 – Настройки для трехфазной системы частотного управления
Пороговые Значения пороговых регистров PWMSELx
регистры (переменная — )
PWMMR0 —
PWMMR1 0 (не имеет значения) —
PWMMR2 0
PWMMR3 0
PWMMR4 1
PWMMR5 0
PWMMR6 1
3.6.3 Алгоритм программы
Широтно-импульсных модулятор является одним из самых простых
узлов микроконтроллера. Для получения сигнала с неизменными параметра-
ми требуется однократно выполнить настройку модуля ШИМ. Алгоритм
настройки приведен на рисунке 3.6.2.
1. Перевести портовые линии P0.7–P0.9 в режим PWM2, 4, 6 соответ-
ственно (регистр PINSEL0).
2. Задать частоту ШИМ Гц (регистр PWMMR0). Восполь-
зоваться первой формулой в таблице 3.6.1.
3. Рассчитать и присвоить регистрам PWMMR1–6 значения, обеспе-
чивающие необходимую скважность (коэффициент заполнения и начальные
фазы). Начальная фаза канала PWM2 задается регистром PWMMR1, его ко-
175
эффициент заполнения — разностью PWMMR2 и PWMMR1. По аналогии
следующая пара регистров PWMMR3–PWMMR4 определяет параметры сиг-
нала PWM4, а пара PWMMR5–PWMMR6 — сигнала PWM6. Принять
начальную фазу второго канала нулевой, остальные в соответствии с задани-
ем смещены на 120º. Все необходимые формулы есть в таблице 3.6.1.
Основная программа 4
Настройка схемы
Начало
совпадения ШИМ
1
Настройка режимов 5
Включить счетчик
портовых линий
ШИМ в синхронном
P0.7–P0.9
режиме
2 6
Задание частоты ШИМ
Включить каналы с
3 управлением фазой
Задание коэфф.
заполнения
и начальные фазы 7
Пустая команда
176
совпадению с порогом PWMMR0, а сбрасывать его в процедуре обработки
прерываний.
Если допустить усложнение алгоритма, то можно, кроме того, изме-
рять частоту внешнего сигнала и корректировать значения всех пороговых
регистров с учетом действительной частоты. Измерение частоты рассматри-
вается в разделе 3.17.
177
На частотах порядка 500 Гц быстродействия микроконтроллера недо-
статочно для вычисления дискретных отсчетов синусоидального сигнала в
реальном времени. То есть для вычисления одной точки синуса требуется
время, превышающее . Поэтому таблица синусов вычисляется заранее. В за-
висимости от того меняются ли параметры сигнала в ходе работы программы
или они постоянны, таблица рассчитывается либо на этапе разработки про-
граммы и «прошивается» в ПЗУ, либо рассчитывается по программе самим
микроконтроллером и хранится в ОЗУ. Здесь будем рассматривать только
второй случай. Если расчет таблицы выполняется микроконтроллером, то
вычисление тригонометрической функции связано с существенными времен-
ными затратами. Можно рекомендовать рассчитать шаблон синусоидального
сигнала фиксированной амплитуды и постоянно хранить в памяти в формате
с плавающей точкой. Будем обозначать этот шаблон . В таблице 3.7.1 при-
ведены выражения и соответствующие команды Си для расчета однополяр-
ного шаблонного сигнала разных форм в диапазоне .
Таблица 3.7.1 – Выражения для расчета шаблонных сигналов
Форма Математическое Реализация с помощью
сигнала выражение ( ) команды Си
Меандр u[k] = k<N/2? 0 : 2;
u[k] = k<N/2 ?
Треугольник
k*4.0/N : 4-k*4.0/N;
u[k] =
Синус
sin(6.283185307*k/N)+1;
Всякий раз, когда необходимо изменить амплитуду, на основе шабло-
на путем масштабирования, смещения и округления рассчитывается циф-
ровой сигнал . Этот сигнал должен быть представлен в формате с фиксиро-
ванной точкой. Он содержит отсчеты, готовые для записи в ЦАП.
Сигнал рассчитывается на основе по общей формуле (независи-
мо от формы):
, (3.7.1)
Начало Начало
1 1
K=0 Запись в ЦАП v[K]
2 2
Настройка режима K=K+1
линии P0.25
3 Да
K=N
Нет 3 Да 4
k = 0; k < N; k++ Нет K=0
4
6 Расчет u[k]
Настройка таймера: 5
5 Инициализация
задание порога, вкл.
Расчет v[k] системы прерываний
сброс и запрос прерывания
7 Конец
Настройка системы
прерываний
8
Пустая команда
180
T0MR0=T[0];
4. Задать еще одно пороговое значение таймера, соответственно пери-
оду сигнала, например
T0MR1=60E6/f-1;
или (лучше) с округлением:
T0MR1=floor(60E6/f-0.5);
5. Настроить схемы совпадений таким образом, чтобы T0MR0 давало
только запрос прерывания, а переполнения давало T0MR1.
6. Процедуру обработки прерывания (непосредственно после блока 1)
дополнить командой задания нового порогового значения
T0MR0=T[K];
Теперь в начале каждой дискреты таймер не сбрасывается, а продол-
жает инкрементироваться. При этом самому пороговому значению T0MR0
дается приращение, соответствующее длительности очередной дискреты.
Сброс таймера в ноль осуществляется устройством совпадения T0MR1.
Сброс происходит одновременно с концом последней дискреты.
3.7.5 Выбор числа дискрет
Число дискрет стремятся сделать как можно больше. Чем выше ,
тем меньше шум квантования и выше его частота. Однако быстродействие
как цифроаналогового преобразователя, так и микроконтроллера ограничива-
ет число дискрет. Расход процессорного времени связан с обработкой преры-
ваний. С помощью микроконтроллера LPC2148 при практически не
удается получить частоту сигнала больше 20 кГц (длительность дискреты
около 1,6 мкс). В то же время на низких частотах есть возможность увели-
чить до сотен и тысяч.
Если требуется регулировать частоту сигнала в широких пределах,
можно рекомендовать динамическое изменение числа дискрет , увеличивая
его с уменьшением частоты и сохраняя малой длительность дискреты при
любой частоте.
Например, расчет числа дискрет можно производить по формуле:
, (3.7.2)
181
однажды, но с избыточностью, например, для . На низких
частотах будет использована вся таблица, а с ростом частоты только каждый
2-ой, 4-ый, 8-ой и т. д. элемент. Это легко реализуется, если в процедуре об-
работки прерывания придавать счетчику неединичное (переменное) при-
ращение :
. (3.7.3)
Пример реализации на Си
n=N >> (int)floor(log(20E3*16/f)/log(2));
if (n==0) n=1;
Условный оператор вводит ограничение .
Блок 2 процедуры обработки прерывания потребуется заменить на
K+=n;
P0.21 6 7 6 8 5 8
Положение
ротора
Рисунок 3.8.2 – Временные диаграммы,
поясняющие управление шаговым двигателем
3.8.3 Алгоритм программы
Задача решается с помощью таймера, генерирующего прерывания
каждые 0,5 с. Процедура обработки прерываний содержит команды инверсии
портовых линий в соответствии с кодом Грея. Перевод позиционного двоич-
ного кода в код Грея рассматривается в разделе 2.1.
Поскольку здесь имеем дело лишь с четырьмя кодовыми комбинаци-
ями, проще заранее найти их, поместить в массив, а далее выводить в порт в
порядке, соответствующим направлению вращения.
Схема алгоритма показана на рисунке 3.8.3.
В программе потребуются следующие глобальные переменные:
а) целочисленный со знаком счетчик шагов ;
б) целочисленное со знаком приращение счетчика ;
183
Основная программа Процедура обработки прерывания
Начало Начало
1 1
Включение Вывод в порт кода
высокоскоростного P[n%4]
режима порта 0
2
2 n=n+D
Настройка на вывод
P0.12 и P0.21
Нет 3
n < 0 или n > 10
3
Задание маски
для порта 0 Да
4
4 n = n – 2D
Настройка таймера:
задание порога, вкл. 5
сброс и прерывание D = –D
5
Настройка системы 6
прерываний Инициализация
системы прерываний
6
Пустая команда Возврат
184
6. Завершить программу вечным циклом.
Схема процедуры обработки прерывания показана на рисунке 3.8.3.
1. Вывести в порт очередную кодовую комбинацию. Индекс элемента
массива последовательно должен принимать значения 0, 1, 2, 3, 0, 1 и т. д. В
то время как счетчик шагов n будет меняться от 0 до 10 и обратно до 0. Оче-
видно, что индекс массива можно вычислить как остаток от деления n на 4.
Поэтому блок 1 реализуется командой
FIO0PIN=P[n%4];
2. Увеличить счетчик шагов n на величину приращения D.
3–5. Если n вышел за границы интервала [0; 10], сделать шаг в проти-
воположном направлении вычитанием удвоенного D; далее изменить знак D.
Это приведет к изменению порядка чередования кодовых комбинаций на
противоположный и реверсу двигателя.
6. Завершить процедуру обработку прерывания сбросом флага запроса
(T0IR) и обнулением VICVectAddr.
185
му закону. Выше показана осциллограмма гармонического напряжения ча-
стотой 2 Гц, полученного путем фильтрации. В данном случае частота следо-
вания импульсов в 50 раз превышает частоту модулирующего колебания
( Гц). При этом отчетливо видна высокочастотная составляющая в
составе гармонического напряжения.
Осциллограмма для случая тысячекратного превышения ( кГц)
показана на рисунке 3.9.3.
Для реализации генератора предлагается использовать таблицу дис-
кретных отсчетов гармонического сигнала и изменение длительности моду-
лированных импульсов по таймеру (многократно за период).
Введем следующие обозначения: , Гц — частота гармонического
сигнала; — число модулированных импульсов, заключенных в периоде
гармонического сигнала. — коэффициент, связывающий частоту импуль-
сов и частоту модулирующего колебания.
186
В частности, может меняться длительность каждого импульса, как на
рисунке 3.9.2. Однако при большом это приведет к чрезмерному увеличе-
нию отсчетов генерируемого сигнала и, как следствие, объема памяти для
хранения таблицы. Вполне допустимо длительность нескольких импульсов
подряд оставлять неизменной. Тогда число градаций длительности импуль-
сов и коэффициент заполнения (обозначать его ) будет меньше . Так сиг-
нал на рисунке 3.9.2 получен при пачках из импульсов одинако-
вой длительности.
Опираясь на выражение (1.14.1), выразим значение регистра
PWMMR0, определяющее период модулированных импульсов:
. (3.9.1)
Аналогично в соответствии с (1.13.3) пороговое значение таймера, за-
дающее интервал постоянства коэффициента заполнения:
. (3.9.2)
Каждый дискретный отсчет, определяющий длительность импульса
рассчитывается по формуле
, (3.9.3)
187
Основная программа 7 Процедура обработки
Расчеты таблицы прерывания
Начало
отсчетов сигнала
Начало
1 8
Ввод f0, M, N 1
k=0
PWMMR2=u[k]
2
Настройка режима 9
Настройка таймера: 2
портовой лини P0.7 Инкремент k
вкл. cброс и
3 запрос прерывания 3
Задание частоты ШИМ Стробирование
10 защелки ШИМ
4 Задание порогового
Настройка схемы значения для таймера
совпадения ШИМ 4 Да
11 k=N
5 Настройка системы
Вкл. cч. ШИМ в прерываний 5
Нет k=0
синхронном режиме
12
6 Запуск таймера
Включить канал PWM2 6
Инициализация
13 системы прерываний
Пустая команда
Конец
Рисунок 3.9.4 – Схемы алгоритмов основной программы
и процедуры обработки прерывания от таймера
5. Включить счетчик ШИМ в синхронном режиме (с использованием
защелок) через регистр PWMTCR.
6. Включить выход канала PWM2 (регистр PWMPCR). Управление
фазой для всех каналов оставить отключенной.
7. Расчет таблицы выполнить по формуле (3.9.3), которая реализуется
на Си следующим образом:
for (k=0; k<N; k++)
u[k]=floor((PWMMR0-1)/2*
(sin(2*3.1415927*k/N)+1)+0.5);
8. Значение счетчика будет использоваться в дальнейшем, поэтому
после цикла важно присвоить ему нулевое значение.
9–13. Блоки абсолютно идентичны соответствующим блокам про-
граммы генератора прямоугольного сигнала (практическое занятие №2). От-
метим лишь, что присвоить задать пороговое значение (3.9.2) удобно коман-
дой
T0MR0=15E6/f/N-1;
3.9.4 Алгоритм процедуры обработки прерывания
Оформление процедуры обработки прерывания от схемы совпадения
таймера рассматривалось в практическом занятии №2.
1–2. Загрузить новое значение в пороговый регистр PMWMR2. Оба
блока реализуются одной командой Си
188
PWMMR2=u[k++];
3. Разрешить обновление защелки пороговых значений в начале сле-
дующего периода. Для этого установить единицу в разряд регистра
PWMLER, соответствующий второму каналу ШИМ.
4–5. Реализовать проверку равенства счетчика предельному числу ,
обнулить k в случае равенства.
6. Сброс флага прерывания и инициализация адреса обсуждалась в
практическом занятии № 2.
Строка 2 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4A 0x4B 0x4C 0x4D 0x4E 0x4F
191
Функция Функция вывода строки Функция
выполнения команды инициализации ЖКИ
Начало
Начало Начало
1
1 Ввод Sym, Pos 1
Ввод Data, RS Настроить режим и
2 направление
2 k=0
портовых линий
RW=0
3
Перевести курсор в 2
3 Вкл. подсветку
Вывод RS позицию Pos
(Set DDRAM Address) 3
4 Задержка 50 мс
Вывод Data
4
5 Нет 4 Function Set
Формирования Sym[k]>0 (DL=1, N=1, F=0)
импульса 575 нс
Да 5
6 Display On
Задержка 1,71 мс 5 (D=1, C=0, B=0)
Вывод символа Sym[k]
Возврат (Write Data) 6
Clear Display
Возврат
Возврат
а) б) в)
Рисунок 3.10.3 – Схемы алгоритмов функций управления модулем ЖКИ
1. Входные параметры функции: байт Data, выставляемый на шину
данных индикатора; сигнал RS, принимающий два значения 0 и 1. Оба пара-
метра должны иметь тип unsigned char.
2. Установить низкий уровень на линии RW, что соответствует режи-
му отправки данных. Рекомендуется использовать обращение к порту ввода-
вывода в режиме байта (регистр FIO0CLR2). Схема подключения входов ин-
дикатора к портовым линиям микроконтроллера показана на рисунке 3.10.4.
3. Установить на линии RS (регистр FIO1PIN3) логический уровень в
соответствии со значением одноименного параметра функции. Типовая зада-
ча вывода бита в порт рассмотрена в разделе 1.10.1 (пример 3).
4. Вывести байт Data на шину данных (регистр FIO1PIN2).
FIO1PIN3 – третий байт порта 1 FIO1PIN2 – второй байт порта 1
31 28 27 25 24 23 16
sy
E DB7:DB0
S
Bu
R
Рисунок 3.10.4 – Схема портовых линий МК, используемых для управления ЖКИ
192
5. Сформировать строб на линии E — импульс длительностью не ме-
нее 575 нс. Для этого установить высокий уровень на линии E с помощью ре-
гистра FIO1SET3, вызвать процедуру задержки с параметром , предвари-
тельно рассчитав числовое значение N по формулам 3.1.2, затем установить
низкий уровень сигнала E через регистр FIO1CLR3.
6. Сформировать новую задержку, достаточную для завершения лю-
бой команды (не менее 1,71 мс).
3.10.4 Функция вывода строки символов
Основной функцией в библиотеке является подпрограмма вывода
строки символов. Обозначим функцию PrintSymbol. Ее алгоритм показан на
рисунке 3.10.3, б).
Функции передается два параметра: указатель Sym (строка символов)
и байт Pos (номер позиции индикатора для первого символа). Переменная k
служит счетчиком символов. Первый вызов функции LCDWrite обеспечивает
выполнение команды индикатора Set DDRAM Address, то есть перемещение
курсора в позицию Pos. Далее в цикле повторяется выполнение команды за-
писи кода символа в память модуля индикации. Переменная-счетчик k ис-
пользуется как индекс массива и при каждом обращении инкрементируется
([k++]). Выполнение цикла продолжается до тех пор, пока не встретится
символ конца строки — символ с кодом 0x00, обозначающий конец строки.
void PrintSymbol(char *Sym, char Pos)
{
char k=0;
LCDWrite(0x80 | Pos,0);
while (Sym[k]>0)
LCDWrite(Sym[k++],1);
}
3.10.5 Разработка функции инициализации модуля ЖКИ
Алгоритм функции инициализации показан на рисунке 3.10.3, в).
Объявить функцию пустого типа
void LCDInit()
1. Выбрать высокоскоростной режим обмена с портами ввода-вывода
через регистр SCS (раздел 1.10.2). Настроить на вывод все линии, задейство-
ванные для управления индикатором (по рисункам 3.10.1, 3.10.4). Можно ре-
комендовать использовать регистры FIO0DIRU и FIO1DIRU. Причем лучше
для установки у них единиц использовать не команду присваивания, а логи-
ческое сложение, например
FIO0DIRU|= Код ;
Это сохранит неизменными остальные разряды, что очень важно в дальней-
шем при сопряжении разрабатываемой библиотеки с другими программами.
2. Включить подсветку, установив высокий уровень на линии P0.30.
3. Обеспечить задержку не менее 50 мс, необходимую для начала ра-
боты модуля индикации.
193
5–6. С помощью функции LCDWrite подать на индикатор команды
Function Set, Display On и Clear Display. Значения управляющий битов указа-
ны в блок-схеме алгоритма.
3.10.6 Разработка тестовой программы
Тестовая программа должна содержать директиву подключения биб-
лиотеки функций управления ЖКИ
#include "LCD.C"
Блок-схема тестовой программы показана на рисунке 3.10.5, а).
1. Вызвать функцию инициализации ЖКИ
LCDInit();
2. Выполнить вывод одной или нескольких произвольных строк сим-
волов, вызывая функцию из библиотеки, например:
PrintSymbol("Preved, Medved!", Номер позиции );
Напомним, что позиции верхней строка индикатора нумеруются 0–15
(шестнадцатеричные значения 0x00–0x0F), а нижней — 64–79 (0x40–0x4F).
3.10.7 Управление ЖКИ с опросом флага готовности
Предлагается разработать полный аналог функции LCDWrite, рас-
смотренной в разделе 3.10.4, но вместо «слепого» ожидания готовности вос-
пользуемся опросом флага. Алгоритм функции показан на рисунке 3.10.5, б).
Блоки 1–4 полностью идентичны 3.10.3, а).
5. Здесь рекомендуется длительность строба 1,5 мкс. Это гарантирует,
что период следования импульсов будет не меньше допустимых 1,2 мкс.
6–7. После формирования строба необходимо подготовиться к цикли-
ческому опросу флага готовности: для этого настроить портовую линию, от-
вечающую за сигнал DB7 на ввод (регистр FIO0DIR2), и установить сигналы
, .
8–9. Реализовать повтор в цикле while (...) ... ; строба пока на
линии DB7 фиксируется низкий логический уровень. Строб формировать с
той же временной задержкой 1,5 мкс.
10. Восстановить режим вывода для линии DB7.
3.10.8 Программирование произвольных символов
Память знакосинтезатора имеет восемь свободных позиций символы с
кодами 0–7. Графическое изображение этих символов может быть запро-
граммировано произвольным образом. Для этого необходимо дать команду
Set CGRAM Address, после чего подать байт, задающий графическое изобра-
жение одного столбца таблицы знакогенератора. Каждый байт определяет
строку символа, причем старшие три бита не задействованы, поскольку сим-
вол состоит только из пяти столбцов. Полное изображение символа форми-
рую 8 байт. Таким образом, адреса памяти знакогенератора с 0x00–0x07 со-
ответствуют изображению символа с кодом 0x00, адреса с 0x08–0x0F —
символа с кодом 0x01 и т. д.
194
Функция программирования символов незначительно отличается от
функции вывода символов PrintSymbol. Предложим ее исходный текст.
void ProgSymbol(char *Mask, char Pos)
{
char k;
LCDWrite(0x40 | Pos,0);
for (k=0; k<8; k++) LCDWrite(Mask[k],1);
}
Функция выполнения команды
Начало 6
Настроить
1 линию DB7 на ввод
Основная программа Ввод Data, RS
7
Начало 2 RS=0, RW=1
RW=0
1
Инициализация 3
8
ЖКИ Вывод RS
Формирования
4 импульса 1,5 мкс
2
Вывод строки Вывод Data
5
9 Да
Формирования DB7=0
3
Пустая команда импульса 1,5 мкс
Нет
10
Восстановить режим
вывода для линии DB7
Возврат
а) б)
Рисунок 3.10.5 –Алгоритмы основной программы взаимодействия с модулем ЖКИ
(а) и функции выполнения команды с ожиданием флага готовности (б)
Адрес 0x00-0x07 0x08-0x0F 0x10-0x17 0x18-0x1F 0x20-0x27 0x28-0x2F 0x30-0x37 0x38-0x3F
196
Управление светодиодами осуществляется с помощью сдвиговых ре-
гистров типа 74HC595 производства фирмы NXP. Выходы регистра управле-
ния столбцами усилены p-n-p транзисторами, так как суммарный ток свето-
диодов превышает предельно допустимый ток выходов регистра и составляет
примерно 48 мА. Через каждую линию строк протекает ток только одного
светодиода (около 6 мА), поэтому строки (катоды светодиодов) подключены
к регистрам непосредственно.
Как видно из схемы, для управления как строками, так и столбцами
матрицы активным уровнем является логический ноль.
Для формирования символов предлагается использовать файл
Font_6x8.h, содержащий объявление массива — таблицы знакогенератора.
Файл имеет следующую структуру:
const char Font_6x8_Data[]=
{
...
0x00, 0x7f, 0x09, 0x09, 0x09, 0x01, // 0x46 - 'F'.
...
}
Каждая строка файла соответствует символу таблицы ASCII. Пример приве-
ден для латинской буквы «F». Байты соответствуют столбцам точечного
изображения символа (двоичная единица — точка светится, двоичный
ноль — не светится). Массив является одномерным, поэтому индекс каждого
элемента должен рассчитываться по формуле
, (3.11.1)
где — ASCII-код символа; — номер столбца изображения символа. На
рисунке 3.11.1 показана схема кодирования символов таким способом.
3.11.3 Алгоритм основной программы
К программе необходимо подключись файл, содержащий таблицу
знакогенератора Font_6x8.h директивой
0x45·6 0x45·6+5 0x46·6 0x46·6+5 0x47·6 0x47·6+5
0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 0
0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1
0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 1 1 1
0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1
0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1
0 1 1 1 1 1 0 1 0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x00
0x7F
0x49
0x49
0x49
0x41
0x00
0x7F
0x09
0x09
0x09
0x01
0x00
0x3E
0x41
0x49
0x49
0x7A
Начало Начало
1 1
Настройка режима Формирование кода C
линий P0.6 и P0.4 для столбца K
2 2
Настройка направления Инкремент K
линии P0.15
3
3 Да
Настройка SPI K>7
4
4 K=0
Нет
Настройка таймера и
схемы совпадения,
включение таймера 5
Передача по SPI С
5
Настройка системы
прерываний 6 Да
Передача ?
6
Формирование
карты матрицы Нет
7
Строб на P0.15
7
Пустая команда 8
Инициализация
системы прерываний
Возврат
198
Рисунок 3.11.3 – Осциллограммы сигналов интерфейса SPI
RCK OUT
RG
SCL Q7 0
Q6 1
Q5 0
Q4 0
Q3 1
Q2 1
Направление сдвига
Q1 0
SER Q0 1
1 << K Map[K]
Направление сдвига
199
Настроить тактовую частоту на линии SCK через регистр S0SPCCR
(выражение 1.17.1). В соответствии с техническом описанием для регистра
74HC595 фирмы NXP допустимая частота составляет 20 МГц.
4. Выполнить настройку таймера. Значение порогового регистра
T0MR0 рассчитать по формуле (1.13.3) для времени не более
мс. Разрешить сброс таймера и запрос прерывания при
совпадении (регистр T0MCR). Включить таймер (регистрT0TCR).
5. Включить прерывание от таймера.
6. Формирование карты светодиодной матрицы может выполняться
следующим кодом (для изображения цифры «7»)
for (k=0;k<6;k++)
Map[k+1]=Font_6x8_Data[6*'7'+k];
Массив столбцов светодиодной матрицы Map заполняется кодами из таблицы
знакогенератора Font_6x8_Data. Индекс каждого байта таблицы вычисля-
ется по формуле , где — ASCII-код отображаемого символа,
— счетчик цикла, соответствующий номерам столбцов светодиод-
ной матрицы. Индексу массива Map придается смещение, равное единице
(Map[k+1]). Это необходимо для симметрирования изображения на светоди-
одной матрице (символ имеет ширину 6 точек, а матрица — 8). Таким обра-
зом, при будут заполнены средние 6 столбцов.
7. Программа заканчивается конструкцией вечного цикла.
3.11.4 Алгоритм процедуры обработки прерывания
В процедуре объявляется локальная переменная Code типа unsigned
int.
1. Формирование 16-разрядного кода Code осуществляется в соответ-
ствии со схемой на рисунке 3.11.4. Предложим команду, формирования
управляющего кода.
Code=0x100 << K | Map[K];
Старший байт содержит одну единицу, в позиции K-го столбца, пита-
ние которого предстоит включить. Этот байт формируется путем сдвига
шестнадцатеричного числа 0x100 на K разрядов влево. Младший байт зани-
мает K-ый код управления светодиодами столбца из массива Map. Он внед-
ряется операцией логического сложения.
2–4. Необходимо увеличить на единицу счетчик столбцов K и его об-
нулить, если в результате он стал равен семи.
5. Передача по SPI осуществляется присваиванием регистру S0SPDR
управляющего кода Code. Как следует из схемы на рисунке 3.11.1, активны-
ми уровнями являются логические нули. Поэтому перед присваиванием пе-
ременную необходимо инвертировать:
S0SPDR=~Code;
6. Далее требуется дождаться завершения передачи по SPI, ожидая в
цикле while аппаратной установки единицы в разряде SPIF регистра S0SPSR.
while (!(S0SPSR & 0x80)) ;
200
7. Получив подтверждение окончания передачи, то есть загрузки
сдвиговых регистров, необходимо сформировать строб на входах RCK мик-
росхем 74HC595, подключенных параллельно к линии P0.15. Для этого дать
подряд команды на установку в единицу и сброс в ноль этой портовой линии.
Длительность такого импульса даже при тактовой частоте микроконтроллера
60 МГц окажется больше минимально допустимого значения 24 нс. По
нарастающему фронту сигнала RCK в выходные защелки двух регистра пе-
репишется принятый код и на выводах Q0–Q7 установятся соответствующие
логические уровни.
8. Инициализация системы прерываний состоит в сбросе флага в реги-
стре T0IR и сбросе в ноль регистра VICVectAddr.
3.11.5 Реализация движения строки
Ниже рассматривается вариант получения анимированного изображе-
ния — эффекта «бегущей» строки. За основу принимается та же программа.
Потребуются следующие константы и переменные:
а) строковая константа хранит движущиеся символы;
б) целочисленная константа — ширина индикатора (число точек);
в) целочисленная константа — число кадров, в течение которых
строка остается неподвижной;
г) целочисленная константа — длина строки (число символов);
Процедура обработки
прерывания от таймера 8
Инкремент K
Начало
1
9 Да
I=T+k%L K = LM
Нет 10
2 Да K=0
I >= 6N
3 11
I = I - 6N Инкремент T
Нет
4 Да 12
Формирование кода C T = 6N
для K % L и I
Нет
5
Передача по SPI С 13
T=0
6 Да 14
Передача ? Инициализация
системы прерываний
Нет
7 Возврат
Строб на P0.15
202
3.12 Управление матричным жидкокристаллическим дисплеем
3.12.1 Управление дисплеем на основе контроллера PCF8833
На плате EA-EDU-011 установлен цветной матричный ЖК дисплей,
аналог Nokia 6100. Управление дисплеем осуществляется контроллером,
совместимым с Philips PCF8833. Дисплей имеет разрешение 130×130 точек и
65536 цветов. Взаимодействие с контролером осуществляется через последо-
вательный интерфейс SPI.
Сводка основных команд контроллера PCF8833, необходимых для
управления индикатором, дана в таблице 3.12.1
Каждое управляющее слово, передаваемое по SPI, состоит из девяти
бит (рисунок 3.12.1). Старший бит обозначает команду (0) или данные (1).
Остальные 8 бит содержат код команды или данных.
8 7 0 8 7 0 8 7
0 Код команды 1 Байт 1 1 Байт 2 ...
MY = 0 MY = 0 MY = 1 MY = 1
MX = 0 MX = 1 MX = 0 MX = 1
RGB
MADCTL 0x36
MY
MX
1 V x x x x
V = 0/1 — инкремент адреса в гориз./верт. направлении
RGB = 0/1 — порядок кодирования цвета: BGR/RGB
0 0 0 1 1 1 0 1 0 Кодирование цвета
P0–P2 = 010 (2) — 8-разрядное
COLMOD 0x3A
1 x x x x x P2 P1 P0 P0–P2 = 011 (3) — 12-разрядное
P0–P2 = 101 (5) — 16-разрядное
0 0 0 1 0 0 1 0 1 Настройка контрастности
SETCON 0x25
1 x V6 V5 V4 V3 V2 V1 V0 V0–V6 — уровень контрастности от 0 до 127
0 0 0 1 0 1 0 1 0 Выбор диапазона столбцов
CASET 0x2A 1 XE0 – XE7 XE0–XE7 — «левая» граница (1–130)
1 XS0 – XS7 XS–XS7 — «правая» граница (1–130)
0 0 0 1 0 1 0 1 1 Выбор диапазона столбцов
PASET 0x2B 1 YE0 – YE7 YE0–YE7 — «нижняя» граница (1–130)
1 YS0 – YS7 YS0–YS7 — «верхняя» граница (1–130)
0 0 0 1 0 1 1 0 0 Запись в память дисплея
RAMWR 0x2C 1 R R R R R G G G Последовательность 16-разрядных слов, обозначающих
1 G G G B B B B B цвета пикселей. (Для 16-разрядного кодирования цвета.)
204
Таким образом, рекомендуемый параметр команды MADCTL кодиру-
ется шестнадцатеричным числом 0x48 или, с учетом предшествующей еди-
ницы — 0x148.
Команда COLMOD управляет разрядностью кодирования цветов.
Поддерживается три варианта разрядности: 8, 12 и 16 бит. Снижение разряд-
ности сокращает время передачи данных, но сокращает число цветовых от-
тенков. Отметим, что при максимальной скорости передачи данных 7,5 МГц
и 16 битах на точку заполнить весь дисплей можно чуть больше, чем за 40 мс
( ). Для 16-разрядного кодирования параметр
команды равен 0x105.
Команду SETCON задает контрастность дисплея. По умолчанию
установлен слишком высокий уровень контрастности. Диапазон значений,
рекомендуемый авторами, — от 30 до 45 (десятичные числа).
Вывод точек на дисплей осуществляется в два этапа: создание прямо-
угольного окна и заполнение окна цветными точками.
Окно создается двумя командами CASET и PASET. Первая задает
границы окна по оси абсцисс, вторая — по оси ординат. Каждая команда
имеет по два параметра (для определения границ с двух сторон). Например,
для создания окна во весь экран следует дать команду CASET с параметрами
1 и 130 (шестнадцатеричные коды 0x101 и 0x182), а затем команду PASET с
теми же параметрами. При выводе очередной точки курсор смещается на од-
ну позицию по горизонтали или по вертикали в зависимости от состояния
бита V. При достижении границы окна курсор переходит на начало следую-
щей строки или столбца.
(1, 1) (1, 1)
205
3.12.2 Построение простейших геометрических фигур
Приведем формулы, применяемые для построения простейших гео-
метрических фигур: линии и окружности.
Линия, заданная координаторами начала ( , ), а также проекциями
на оси координат ( , ), строится по следующим формулам.
Если
,
где — целое, изменяющееся через 1 от до .
Если
,
где — целое, изменяющееся через 1 от до .
Окружность, заданная координатами центра ( , ) и радиусом
строится, как множество точек с координатами
;
;
;
;
,
206
Считывание результата, преобразование в строку символов и обновление ин-
дикатора будет осуществляться в процедуре обработки прерывания от АЦП.
3.13.3 Алгоритм основной программы
Программа должна содержать директивы подключения библиотек
функций ввода-вывода и функций управления ЖКИ.
#include <LPC214x.h>
#include <STDIO.h>
#include "LCD.C"
Процедура обработки прерываний будет описана ниже. Алгоритм ос-
новной программы показан на рисунке 3.13.1.
1. Перевести линию P0.28 в режим входа АЦП (регистр PINSEL1).
2. Вызвать функцию инициализации ЖКИ LCDInit (из библиотеки).
3. Настроить таймер. Задать пороговое значение (регистр T0MR1), со-
ответствующее временной задержке 0,4 с (1.13.3). Разрешить сброс таймера
по совпадению 1 (регистр T0MCR). Разрешить установку внешнего сигнала
совпадения 1 (регистр T0EMR). Включить таймер (регистр T0TCR).
4. Настроить АЦП (регистр AD0CR):
а) включить запуск АЦП нарастающим сигналом MAT0.1 (биты
START и EDGE).
б) включить АЦП (бит PDN);
в) непрерывное преобразование не использовать (биты BURST и
CLKS);
Основная программа Процедура обработки
прерывания от АЦП
Начало
Начало
1
Настройка режима 1
линии P0.28 Сохранение и
масштабирование
2 результата
Инициализация
ЖКИ 2
Формирование
3 строки символов
Настройка таймера и
схемы совпадения, 3
включение таймера Вывод строки на ЖКИ
4 4
Настройка АЦП Инициализация
системы прерываний
5
Настройка системы
прерываний Возврат
6
Пустая команда
207
г) установить делитель частоты (биты CLKDIV), так чтобы тактовая
частота АЦП не превышала 4,5 МГц (1.15.1); напомним, что по умолча-
нию тактовая частота периферийных устройств МГц;
д) выбрать канал 1 (биты SEL).
5. Настроить систему прерываний, разрешив прерывание по заверше-
нии АЦП через VICVectAddr0, VICVectCntl0 и VICIntEnable (раздел 1.11.5).
6. Записать конструкцию вечного цикла.
3.13.4 Алгоритм процедуры обработки прерывания от АЦП
В процедуре обработки прерываний потребуется объявить две пере-
менные: вещественного типа N для хранения результата преобразования в
вольтах и строку символов из восьми символов S.
float N;
char S[10];
Поясним размерность массива S. Для отображения результата предла-
гается отвести 9 позиций:
U=1.234 V
Десятый элемент массива необходим для хранения пустого символа (код
0x00), обозначающего конец строки.
1. Считать результат АЦП из регистра AD0DR1 в переменную N (см.
пример в разделе 1.15.9). Опорное напряжение задается резисторным делите-
лем кОм, и кОм. Что дает В.
2. Вызвать стандартную функцию форматирования строк sprintf из
библиотеки STDIO.h (раздел 2.2.19).
snprintf(S,10,"U=%4.3f V",N);
При строке S получит значение в соответствии с предложенным форматом.
3. Вывести на дисплей строку S c помощью функции PrintSymbol.
4. Сбросить в ноль сигнал EMС1, приведший к запуску АЦП, напри-
мер, так:
T0EMR&=0xFFFFFFFD;
Как всегда, последней командой процедуры обработки прерывания загрузить
нулевое значение в регистр VICVectAddr.
3.13.5 АЦП с циклическим опросом нескольких каналов
Дополнительно предлагается разработать модификацию программы,
которая проводит измерения двух сигналов, отображая результаты измерения
на разных строках индикатора. Теперь запуск АЦП будет выполняться в ре-
жиме непрерывного преобразования с автоматическим опросом каналов.
За основу берется прежний алгоритм, в который необходимо внести
ряд изменой.
1. Кроме портовой линии P0.28 перевести в режим аналогового ввода
линию P0.29 (блок 1).
2. Исключить из основной программы команды, отвечающие за
настройку таймера (блок 3), а из процедуры обработки прерывания —
команды сброса сигнала EM0 в регистре T0EMR (блок 4).
208
3. Изменить настройку АЦП:
а) сбросить в нули биты START; установить в единицу бит BURST;
б) в разрядах SEL установить единицы, соответствующие каналам
AIN0.1 и AIN0.2.
4. В процедуре обработки прерываний от АЦП повторить команды
блоков 1–3 для второго канала. Результаты считывать из регистров AD0DR1
и AD0DR2.
3.13.6 Автоматический выбор пределов измерения
Для расширения динамического диапазона измерительные приборы
делают многопредельными. Это значит, что чувствительность прибора и
диапазон (предел) измерения может меняться. С этой целью в структуру ка-
нала обработки измерительного сигнала вводятся специальные масштабиру-
ющие устройства, коэффициент передачи которых меняется с помощью ком-
мутирующей аппаратуры. Весьма популярны, например, интегральные опе-
рационные усилители или микросхемы АЦП с программируемым коэффици-
ентом передачи.
Ряд пределов измерения определяется возможностями аппаратной ча-
сти прибора. Часто это десятикратное изменение предела (например, 0,01;
0,1; 1, 10, 100). Встречается вариант удвоения (0,25; 0,5; 1; 2; 4), а также схе-
ма 1-2-5 (0,1; 0,2; 0,5; 1; 2). Количество пределов может быть от двух до не-
скольких десятков.
С точки зрения программиста коэффициент передачи внешних элек-
трических цепей управляется параллельным или последовательным двоич-
ным кодом, формируемым непосредственно на портовых линиях или переда-
ваемый через интерфейс SPI или I2C.
Здесь обсудим логику автоматического переключения пределов изме-
рения. Программа микроконтроллера должна распознавать необходимость
повышения чувствительности (то есть перехода на меньший предел) и пони-
жения чувствительности (перехода на больший предел).
Выбор предела с меньшей чувствительностью выполняется, если код
АЦП превышает значение, соответствующее текущему верхнему пределу
измерения, и, разумеется, если код АЦП содержит все единицы (насыщение).
Выбор предела измерения с большей чувствительностью выполняется
при условии, что измеряемая величина не превышает 90–95% этого нового
предела.
Отметим, что повышение и понижение чувствительности осуществля-
ется при разных уровнях измерительного сигнала. Такой гистерезис необхо-
дим во избежание циклического переключения, когда сигнал близок к грани-
це пределов
Условие понижения чувствительности имеет вид
.
Для десятиразрядного АЦП обычно выбирают или .
Условие понижения чувствительности
.
209
Для десятиразрядного АЦП и десятичного ряда пределов или
в зависимости от того является предельным код
или (см. раздел 1.15.9). Для двоичного ряда
или .
Рассмотренный алгоритм позволяет как повышать, так и понижать
предел измерения и при плавном изменении измерительного сигнала обеспе-
чивает выбор за один шаг.
Возможен и другой способ, а именно в каждом цикле измерения пере-
бирать по очереди все пределы, начиная с самого грубого. Останавливать пе-
ребор нужно как только код окажется достаточно велик. А именно: для деся-
тичного ряда не менее 100 ( ) или 103 ( ); для двоич-
ного — не менее 500 ( ) или 512 ( ). Пороги переклю-
чения здесь не занижаются на 5–10%, так как нет гистерезиса (переключение
осуществляется всегда только в направлении повышения чувствительности).
Стоит обсудить выбор пределов при цифровом измерении параметров
переменного сигнала (см. раздел 3.14). При этом результат вычисляется на
основе последовательности нескольких мгновенных значений (от единиц до
тысяч). Можно рекомендовать понижать чувствительность, если хотя бы од-
но мгновенное значение выходит за верхнюю границу, а понижать, если все
мгновенные значения в последовательности оказались ниже нижней границы.
Если выявлено, что предел измерения выбран неверно, то следует не-
медленно дать команду на его смену. Перед повторным измерением обычно
следует выдержать некоторое время для прекращения переходного процесса,
из-за коммутаций в электрических цепях. Что касается результата измерения,
то он ошибочный и может быть отброшен. Причем из-за одного мгновенного
значения ошибочной может оказаться вся серия измерений, например при
вычислении действующего значения напряжения.
Переключение пределов требуется учитывать при программном мас-
штабировании. В формуле (1.15.5) величина окажется зависимой от теку-
щего предела. Можно создать в памяти массив значений для каждого пре-
дела или же вычислять по номеру предела.
210
В данном случае в качестве фильтра может быть рекомендован нере-
курсивный фильтр на основе окна Кайзера [5]. Тогда действующее значение
вычисляется по формуле
, (3.14.1)
211
Основная программа Процедура обработки
прерывания от АЦП
Начало
Начало
1
Выбор режима линии 1
P0.28, P0.29 Сохранение и
масштабирование
2 результата в u[С][k]
Инициализация
ЖКИ 2
k = k+1
3
Настройка таймера и
схемы совпадения, Нет 3
включение таймера k > 999
4 Да
Настройка АЦП
4
5 k=0
Настройка системы
прерываний 5
С = !С
6
Переключение
Нет 6
ReadyFlag=1 канала АЦП
7
Да ReadyFlag = 1
7
U=0
8
Инициализация
8 системы прерываний
Нет Да
i=0; i<999; i++
Возврат
10 1/2
U=U Vref/1024
11 9
Формирование U=U+u[!C][i]2·w[i]
строки символов
12
Вывод строки на ЖКИ
13
ReadyFlag=0
212
рого измерения завершены, таблица результата заполнена. Для этого опера-
ция !C изменяет номер канала с нуля на единицу и наоборот.
10. Далее необходимо завершить вычисления действующего значения
командой
U=sqrt(U)*2.2/1024.0;
Здесь 2,2 — значение опорного напряжения (В); 1024 — коэффициент по
формуле (1.15.3).
11. Пункт оставим без комментариев.
12. Вывод строки производится в вычисляемую позицию
PrintSymbol(S,!C*0x40+3);
Результат для нулевого канала отображается на верхней строке ЖКИ, для
первого — на нижней.
13. Сброс флага готовности.
3.14.4 Алгоритм процедуры обработки прерывания
1. При сохранении результата АЦП предлагается выполнить его
сдвиг. Это необходимо для уменьшения требуемого диапазона представления
чисел. Считывание может проводить командой
u[C][k]=(AD0GDR & 0xFFC0) >> 6;
2. Блоки 3–6 выполняются только при заполнении таблицы (условие
k>999).
3–4. Необходимо обнуление счетчика и смена номера канала. Послед-
нее проще всего может быть достигнуто операцией логического отрицания.
C=!C;
5. Смена канала производится путем наложения маски на регистр
управления АЦП (AD0CR) с последующим прибавлением дешифрированно-
го номера канала:
AD0CR=AD0CR & 0xFFFFFF00 | 2 << C;
6. Флаг готовности установить в единицу.
7–8. Блоки идентичны предыдущей задаче.
214
Процедура обработки Основная программа
прерывания от таймера
Начало 6 Нет
Начало Совпадение 0
1
1 Выбор режима линии
Да
T=(T1CR2-T1CR3) P0.17, P0.18
7
2 2 Сброс флага
Инициализация Инициализация совпадения
системы прерываний ЖКИ
8
3 Формирование строки
Возврат Настройка таймера 0 и для T/(60·103)
схемы совпадения,
включение таймера 0 9
Вывод строки
4
Настройка таймера 1 и
схемы захвата,
включение таймера 1
5
Настройка системы
прерываний
216
Измерение интервала времени связано еще c одной составляющей по-
грешности. Микроконтроллер реагирует на логические уровни, не соответ-
ствующие серединам фронтов импульсов (раздел 1.9.2). Это неизбежно при-
ведет к систематическому завышению измеряемого интервала времени, если
он ограничен разными (нарастающим и спадающим) фронтами. Погрешность
тем больше, чем меньше скорость изменения сигнала. При сравнительно вы-
сокой скорости изменения (порядка нескольких сотен В/мкс) этот эффект да-
ет аддитивную абсолютную погрешность примерно нс.
217
3.17.2 Основные рекомендации
Схема, отражающая принцип способ измерения частоты с помощью
двух таймеров-счетчиков, показана на рисунке 3.17.1. Для формирования ин-
тервала счета 1 с используется таймер T0TC и устройство сравнения 2. Соот-
ветственно, интервал счета задается пороговым регистром T0MR2. Начало и
конец интервала обозначаются перепадами логического уровня (инверсией)
на выходе MAT0.2.
CAP1.3
ux T1TC T1CR2 fx
CAP1.2
MAT0.2
218
Рисунок 3.17.2 – Осциллограммы сигналов при измерении частоты
(время счета 1 с; частота сигнала 5 Гц)
Схема процедуры обработки прерываний показана на рисунке 3.17.3.
1. Процедура начинается со считывания последнего захваченного со-
стояния таймера из T1CR2 в переменную NewCAP.
2. Значение частоты в килогерцах вычисляется по очевидной формуле
f=(NewCAP-OldCAP)/1000.0;
3. Заменить предыдущее состояние таймера текущим.
4. Установить в единицу флаг готовности результата Refresh.
Возврат 5
Настройка системы
прерываний
219
5. Инициализация системы прерываний состоит в записи единицы в
бит CR2I регистра T1IR.
Схема основной программы приведена на том же рисунке 3.17.3
1. С помощью регистра PINSEL1 перевести портовые линии P0.16–
P0.18 в режимы MAT0.2, CAP1.2 и CAP1.3 соответственно.
2. Выполнить инициализацию ЖКИ, вызвав функцию LCDInit().
3. Настроить таймер 0. Для этого:
а) разрешить сброс таймера по совпадению MAT2 (регистр T0MCR);
б) разрешить формирование внешнего электрического сигнала CAP2
при совпадении (регистр T0EMR); выбрать инверсию сигнала;
в) установить порог устройства совпадения равным , что при
тактовой частоте МГц даст совпадение через 1 с;
г) включить таймер 0 (регистр T0TCR).
4. Настроить таймер 1. Для этого:
а) выбрать режим счетчика с инкрементом по обоим фронтам им-
пульсов на счетном входе CAP1.3 (регистр T1CTCR);
б) включить захват по обоим фронтам сигнала CAP1.2, разрешить
прерывание по захвату (регистр T1CCR);
в) включить таймер (регистр T1TCR).
5. Включить прерывание от таймера 1 через регистры VICVectAddr0,
VICVectCntl0, VICIntEnable (раздел 1.11.5).
6. С помощью конструкций цикла while и ветвления if организовать
циклическое ожидание появления единицы в флаге готовности результата
Refresh.
7. Сбросить флаг готовности в ноль.
8. Создать строку символов для индикации S командой
snprintf(S,17,"f=%10.4f kHz",f);
Получим формат
f=xxxxx.xxxx kHz
9. Вывести строку функцией PrintSymbol.
3.17.4 Повышение точности измерений
При измерении высоких частот основным источником погрешности
является погрешность образцовой меры (кварцевого резонатора). Об умень-
шении этой составляющей погрешности путем введения поправочного коэф-
фициента сказано в разделе 3.16.6. Случайная составляющая, связанная с
неизбежной дискретизацией времени уменьшается выбором большего интер-
вала счета, например 10 с. Для этого потребуется задать пороговое значение
в регистре T0MR2 (при 60 МГц), и разделить результат на 10.
/W
R
Адрес Указатель регистра Целая часть Неопределенное значение
Направление передачи Дробная часть
Рисунок 3.18.1 – Схема основных регистров управления цифрового датчика температуры LM75
S S P
Адрес R/W A Указатель A Адрес R/W A Целая часть A Дробная часть A
Рисунок 3.18.2 – Временные диаграммы сигналов на лини SDA (вверху) SCL (внизу) при считывании результат измерения
Рисунок 3.18.3 – Осциллограммы сигналов интерфейса I2C при считывании результата измерения температуры
с цифрового датчика LM75. Скорость передачи данных 50 кбит/с. Осциллограммы приведены для температуры T = 31,5º.
222
3.18.3 Алгоритм программы
Как правило, температура меняется медленно и строгая периодич-
ность в ее измерении не требуется. Поэтому предлагается команды опроса
датчика и индикации результата поместить в основную программу, не прибе-
гая к механизму прерываний. Блок схема алгоритма программы показана на
рисунке 3.18.4.
К программе потребуется подключить файлы STDIO.h и LCD.c дирек-
тивой #include.
Программа использует следующие данные:
0x08
Начало
6
1 Сброс START,
Инициализация
передача адреса и W
ЖКИ
2 0x18
Настройка режима
линий P0.2 и P0.3 7
Передача указателя
3 регистра t˚ (0x00)
Настройка I2C
0x28
8
Нет 4 Повторный Start
Готовность I2C
0x10
Да
9
5 Сброс START,
Состояние I2C передача адреса и R,
разр. подтверждение
0x50
Нет 14
10
BusyFlag=0? Сохранить байт в TH,
запрет подтверждения
Да
15 0x58
Формирование
строки символов на 11
Сохранить байт в TL,
основе байтов TH и TL
установить STOP
16
Обновление ЖКИ 12
BusyFlag=0
17
Установка START Иначе
18 13
BusyFlag=1 Сбросить флаг
готовности I2C
223
а) целочисленные переменные TH и TL для хранения старшего и
младшего байтов температуры;
б) строка S (ее длина будет определена ниже);
в) целочисленный флаг занятости BusyFlag (0 — выполняется обмен
2
по I C, 1 — результат получен и готов к индикации).
1. Инициализация ЖКИ производится вызовом функции LCDInit().
2. Перевести портовые линии P0.2, P0.3 в режимы SCL0 и SDA0 (ре-
гистр PINSEL0).
3. Настроить модуль I2C:
а) выбрать скорость передачи данных в соответствии с выражениями
(1.18.1, 1.18.2) (регистры I2C0SCLH, I2C0SCLL);
б) включить приемопередатчик установкой бита EN в регистре
I2C0CONSET.
4. Записать конструкцию проверки готовности приемопередатчика
(разряд SI регистра I2C0CONSET). Далее блоки 5–13 выполняются, если
.
5. Записать конструкцию множественного ветвления по значению со-
стояния I2C (регистр I2C0STAT). Рекомендуется использовать следующий
шаблон
switch (I2C0STAT)
{
case Состояние 1 :
Команды 1 ;
break;
case Состояние 2 :
Команды 2 ;
break;
...
case Состояние N :
Команды N;
}
Взаимодействие с микросхемой подробно рассмотрено в предыдущем
разделе. Состояния, которые необходимо проверять указаны на блок-схеме
алгоритма (см. также таблицу 1.18.2). Команды, отдаваемые приемопередат-
чику I2C также ясны из алгоритма. Здесь приведем выборочно описания бло-
ка 6
I2C0CONCLR=0x20; // Сбросить состояние START (бит STA)
I2C0DAT=0x90; // Передать адрес 1001000R (R/W = 0)
break;
блока 9
I2C0CONCLR=0x20; // Сбросить состояние START (бит STA)
I2C0CONSET=0x04; // Разрешить подтверждение (Бит AA)
I2C0DAT=0x91; // Передать адрес 1001000R (R/W = 1)
break;
224
и блока 11
TL=I2C0DAT; // Считать и сохранить старший байт
I2C0CONSET=0x10; // Сбросить состояние STOP (бит STO)
break;
12. В последнем блоке множественного ветвления сбросить в ноль
флаг занятости BusyFlag.
13. Сбросить флаг готовности I2C (SI) в регистре I2C0CONCLR. Это
необходимо для выполнения следующей операции передачи данных.
14. Условие обеспечивает выполнение остальных блоков, связанных с
индикацией результата, только после окончания обмена по I2C.
15. При формировании строк символов предлагается представить ре-
зультат в формате с плавающей точкой. Учитывается, что целая часть совпа-
дает со старшим байтом результата TH, а дробная часть состоит всего из од-
ного старшего разряда байта TL. Предлагается следующее решение.
snprintf(S,9,"t=%2.1f\xDF""C",TH+(TL & 0x80)/256.0);
Формат строки таков:
t=31.5°C
Теперь ясно, что длина строки S — 9 символов.
16. Обновить изображение на ЖКИ, вызвав функцию PrintSymbol с
параметром S и номером позиции индикатора.
17. Сгенерировать состояние START I2C, чтобы начать новый цикл
измерений (бит STA в регистре I2C0CONSET).
18. Установить флаг занятости в единицу.
226
S
SDA Адр. и № стр. R/W A Адрес ячейки (1–2 байта) A
S
SDA Адр. и № стр. R/W A Байт 0 A
P
SDA A Байт N – 1 A ― Генерируется ведущим
― Генерируется ведомым
P
SDA Байт 0 A A Байт N – 1 A
227
б) N — число байт, читаемых из памяти.
Значения констант устанавливаются определяют диапазон адресов
памяти и назначаются преподавателем.
К программе требуется подключить файлы STDIO.h и LCD.c.
Алгоритм программы показан на рисунке 3.20.3 Структура програм-
мы напоминает рассмотренную в предыдущем разделе, так как основное ме-
сто отводится опросу готовности шины I2C, анализу текущего состояния и
формирования нового.
1–3. Назначение блоков подробно рассмотрено в разделе 3.18.
4. Сформировать состояние START путем записи кода 0x20 в регистр
I2C0CONSET. Операция идентична блоку 17 в предыдущем разделе.
5–7. Реализовать циклическую проверку готовности шины I2C (бит SI
регистра I2C0CONSET) до тех пор, пока флаг завершения чтения Finish не
установится в единицу. При обнаружении готовности ( ) проанализиро-
вать текущее состояние через конструкцию множественного ветвления. Об-
щая форма блоков 5–7 предлагается такой:
while (!Finished)
if (I2C0CONSET & 0x08)
{
switch (I2C0STAT)
{
... // Блоки 8–17
}
... // Блок 18
}
Взаимодействие с модулем I2C рассмотрено в предыдущем разделе.
Здесь прокомментируем выборочно несколько блоков.
8. Снять состояние START. Передать адрес устройства и флаг записи.
I2C0CONCLR=0x20; // Снять START (бит STA)
I2C0DAT=0xA0; // Адрес 1010000; R/W = 0
break;
9. Передать адрес ячейки памяти, записав константу Addr в регистр
I2C0DAT.
11. Сбросить состояние START, снова передать адрес устройства и
флаг чтения, разрешить подтверждение.
I2C0CONCLR=0x20; // Снять START (бит STA)
I2C0CONSET=0x04; // Разрешить подтверждение (бит АA)
I2C0DAT=0xA1; // Адрес 1010000; R/W = 1
break;
12–13. Блоки можно реализовать одной командой
Data[n++]=I2C0DAT;
14–15. Запретить подтверждение (бит AA в регистре I2C0CONCLR),
если принимается предпоследний байт, то есть . Заметим, что к
228
этому моменту инкремент счетчика n уже прошел (в блоке 13), поэтому при
приеме предпоследнего байта действительно .
16. Сохранить последний байт из I2CDAT в массив Data, установить
состояние STOP.
0x08
Начало
8
1 Сброс START,
Инициализация
передача адреса и W
ЖКИ
2 0x18
Настройка режима
линий P0.2 и P0.3 9
Передача адреса байта
3
Настройка I2C 0x28
4 10
Установка START Повторный Start
0x10
Нет 5
11
Finish = 0? Сброс START,
передача адреса и R,
Да разр. подтверждение
6 Нет 0x50
Готовность I2C
12
Сохранить байт
Да
в Data[n]
7
13
Состояние I2C n=n+1
14 Нет
19 n=N–1?
Индикация
Да
20 15
Пустая команда Запретить
подтверждение
0x58
16
Иначе Сохранить байт
в Data[n];
18 установка STOP
Сбросить флаг
готовности I2C 17
Finish = 1
229
17. Установить флаг готовности Finish в единицу. Это приведет к пре-
кращению выполнения цикла (блок 5).
18. Сбросить флаг готовности I2C, записав единицу в блок SI регистра
I2C0CONCLR. Сброс SI активирует изменение состояния I2C или передачу
очередного байта данных.
19. Выполнить индикацию одного или нескольких байт в целях про-
верки работоспособности программы. Ниже приведен пример индикации 10-
го 5-го элемента массива в 16-ричном коде.
snprintf(s,11,"Data[5]=%2X",Data[5]);
PrintSymbol(s,1);
Формат индицируемого изображения таков:
Data[5]=5F
Размер индикатора позволит отображать не более 10 шестнадцатерич-
ных чисел, поэтому для полноценной проверки рекомендуется воспользо-
ваться окном Watch среды Keil uVision, остановив программу на выполнение
вечного цикла (блок 20).
3.20.7 Разработка функции записи блока данных в EEPROM
Как было показано в разделе 3.20.5, запись данных в EEPROM жела-
тельно производить блоками по несколько байт. Размер блока зависит от ти-
па микросхемы памяти. Для CAT1025 он составляет 16 байт. После передачи
каждого блока необходимо выдержать паузу не менее 5 мс.
Рекомендуется оформить функцию записи блока. Схема такой функ-
ции показана на рисунке 3.20.4
Функция должна содержать объявление двух локальных переменных
целого типа: счетчика n и флага готовности Finished, которому здесь же
необходимо присвоить нулевое начальное значение.
1. Функция имеет несколько параметров: массив байтов Data (на схе-
ме показан в блоке 6); N — число байт, которые требуется записать; Addr —
адрес первого байта для записи. Объявление функции может выглядеть так:
EEPROM_Write(unsigned char *Data,
unsigned int N, unsigned char Addr);
2. Функция начинается с установки состояния START на шине I2C
(бит STA в регистре I2C0CONSET).
3–5. Блоки абсолютно идентичны блокам 5–7 предыдущей програм-
мы. Здесь их не комментируем, также как и некоторые последующие.
9. Записать конструкцию проверки неравенства счетчика n и числа за-
писываемых байт N.
10–11. Если , выполнить передачу очередного байта и инкре-
ментировать счетчик
I2C0DAT=Data[n++];
12–13. Иначе сформировать условие STOP и установить флаг завер-
шения записи Finish.
230
Начало
0x08
1
Ввод N, Addr 7
Сброс START,
2 передача адреса и W
Установка START
0x18
8
Нет 3 Передача адреса байта
Finish = 0?
0x28
Да
9 Да
4 Нет n<N?
Готовность I2C
Нет
Да 10
12 Сохранить
5 Сформировать STOP байт в Data[n]
Состояние I2C
13 11
Finish = 1 n=n+1
6 Иначе
Возврат Data
14
Сбросить флаг
Конец готовности I2C
231
проверяет неравенство и возвращает значение ; если оно
справедливо и число 16 иначе.
Третий параметр функции 0x80 + k представляет собой сумму базово-
го адреса и смещения. Смещением служит счетчик байтов k, которому дается
приращение 16.
Функция Delay, рассмотренная в разделе 3.1.5 обеспечит задержку
5 мс, необходимую для завершения записи каждого блока.
1 «r»
Настройка портовых
линий на вывод 7
Зажечь красный
2 светодиод;
Настройка режима
передать «!»
линий P0.0 и P0.1
3 «g»
Настройка UART
8
Зажечь зеленый
светодиод;
Нет 4 передать «!»
Байт принят?
«b»
Да
9
5 Зажечь синий
Принять байт;
светодиод;
поместить в Byte
передать «!»
6 Иначе
Байт
10
Передать «E»
232
1. Перевести в режим вывода (регистр IO0DIR) портовые линии P0.7–
P0.9, к которым подключен трехцветный светодиод.
2. Выбрать режим TxD и RxD для портовых линий P0.0, P0.1 (регистр
PINSEL0).
3. Выполнить настройку UART:
а) установить бит DLAB в регистре U0LCR (присвоить U0LCR значе-
ние 0x80). 1. Перевести в режим вывода (регистр IO0DIR) портовые линии
P0.7–P0.8, к которым подключен трехцветный светодиод.
2. Выбрать режим TxD и RxD для портовых линий P0.0, P0.1 (регистр
PINSEL0).
3. Выполнить настройку UART:
а) установить бит DLAB в регистре U0LCR (присвоить U0LCR значение
0x80).
б) выбрать одну из стандартных скоростей (например, 9600 бит/с) че-
рез регистры U0DLM, U0DLL, U0FDR. При этом руководствоваться табли-
цей 1.19.1. Напомним, что по умолчанию тактовая частота периферийных
устройств МГц.
г) сбросить в ноль бит DLAB регистра U0LCR; в том же регистре вы-
брать восьмибитный режим с одним стоповым битом без контроля четности.
д) включить буферы установкой в единицу бита FIFO EN в регистре
U0FCR.
Блоки 4–10 поместить в вечный цикл.
4. Дождаться наличия данных в буфере приемника путем циклическо-
го тестирования бита RDR регистра U0LSR
while ((U0LSR & 0x1)==0) ;
5. Считать байт из регистра U0RBR в переменную Byte.
6. Проанализировать результат через конструкцию switch…case.
switch (Byte)
{
case 'r': ... ; break;
case 'g': ... ; break;
case 'b': ... ; break;
default: ... ;
}
7–10. Каждая ветвь содержит команду записи в порт для включения
соответствующего светодиода и команду передачи ответа. Передача выпол-
няется путем записи символьной константы в регистр U0THR, например,
U0THR='!';
Для проверки программы следует воспользоваться утилитой
232Analyzer (см. раздел 2.6.4).
233
3.21.3 Автоматическая настройка скорости
Для проверки работы UART в режиме автоматического определения
скорости следует исключить команды выбора скорости. Вместо этого после
настройки UART0 включить команду
U0ACR=1;
После запуска программы и установки связи через терминал передать
символ «a». Если скорость определена верно, этот символ будет правильно
распознан программой, как недопустимая команда, на что она ответит симво-
лам «E». Если скорость не определится, скорее всего, получим «мусор». Что-
бы повторить попытку необходимо сбросить программу микроконтроллера.
Начало Начало
1 1
i=0 Настройка режимов
P0.0 и P0.1
2
Считать 2
идентификатор Настройка UART
прерывания в IntID
3
Настройка прерываний
3
IntID
4
Пустая команда
Иначе 0x04, 0x0C
4 Принят Да
символ «t»
5
Нет Передача Data[0]
0x02 6
n=1
7 i < 16 Да
n<N
8
Нет i=i+1
9
11 Передача Data[n]
Инициализация
системы прерываний 10
n = n +1
Конец
235
3. Записать конструкцию множественного ветвления (switch…case).
Создать три ветви: 0x04 — буфер приемника заполнен; — 0x02; 0x0C — в
буфер приемника поступил, по крайней мере, один байт; 0x02 — буфер пере-
датчика пуст.
4. Если прерывающим событием является получение байта, проверить
байт в U0RBR на равенство символу «t».
5–6. Если условие выполнено, передать нулевой элемент массива, за-
писав его в регистр U0THR и присвоить счетчику единицу, так чтобы пере-
дача была продолжена с первого элемента массива. Теперь завершение пере-
дачи элемента Data[0] приведет к новому прерыванию с идентификатором
0x02.
7. Записать цикл с предусловием для передачи 16 байт подряд. Усло-
вие прекращает передачу, когда отправлен последний элемент.
8–10. Тело цикла содержит инкремент счетчика i, а также передачу
очередного элемента массива и инкремент счетчика байтов n.
11. Процедура обработки прерывания завершается обнулением реги-
стра VICVectAddr.
0x7F80A1A2 unsigned int N float D[0] float D[1] ... float D[N-1]
Заголовок Число слов Слово 0 Слово 1 Слово N-1
236
3.23.3 Алгоритм программы
Приема и расшифровка кадра расположены в основной программе,
поскольку процесс приема протекает достаточно медленно.
К программе подключаются файлы STDIO.h и "LCD.c".
В программе объявлены следующие константы:
а) S — строка из трех символов для индикации;
б) N — беззнаковая целочисленная переменная (число полей в кадре);
в) i — целочисленный счетчик;
г) k — целочисленный счетчик байтов в кадре (начальное значение 0)
д) Frame — структура объединяющего типа следующей структуры:
union
{
unsigned char Bytes[400];
unsigned int Words[100];
float Floats[100];
} Frame;
Это позволит обращаться к кадру как побайтно, так и в режиме четы-
рехбайтных слов, причем в целочисленном формате или в формате с плава-
ющей точкой.
1. Инициализация ЖКИ производится функцией LCDInit(), разрабо-
танной ранее.
2. Портовые линии P0.0 и P0.1 необходимо перевести в режим TxD0 и
RxD0.
3. Настройка UART0 состоит в следующем:
а) Разрешить доступ к настройке скорости (бит DLAB регистра
U0LCR);
б) Рассчитать необходимые величины, задающие частоту UART по
формулам (1.19.1, 1.19.2). Или воспользоваться таблицей 1.19.1 Результаты
занести в регистры U0DLM, U0DLL, U0FDR.
в) включить передачу восьми бит и запретить доступ к защелкам де-
лителя скорости (регистр U0LCR).
г) включить буфер приемопередатчика (младший бит регистра
U0FCR).
4. Организовать ожидание принятого байта, опрашивая в цикле флаг
готовности в регистре состояния линии U0LSR. Все остальные блоки выпол-
няются только в случае появления принятого байта.
237
Начало
Нет 9
1 k=8
Инициализация
ЖКИ
Да
2 10
Настройка режима Сохранить длину
линий P0.0 и P0.1 N=Words[1]=Bytes[7:4]
3
Настройка UART
Нет 11
k>7+4N
Нет 4
Байт принят? Да
12
Да k=0
5
Сохранение байта 13
Очистить дисплей
в Bytes[k]
Да 6 Нет 14 Да
Заг. не
совпал и k=3 i=0; i<N; i++
Нет
15
8 Формирование строки
Инкремент k
на основе Floats[i+2]
7
Сдвиг 16
Индикация строки в
Words[0]=Bytes[3:0]
позиции 4i
с потерей мл. байта
238
8. Когда кадровая синхронизация будет достигнута, счетчик кадров
начнет увеличиваться.
9–10. Когда счетчик достигнет значения 8, последнее слово нужно со-
хранить, как длину кадра.
if (k==8) N=Frame.Words[1];
11. Упаковка байтов в кадр продолжается до тех пор, пока счетчик не
достигнет предела 7+4N. Выполнение этого условия свидетельствует о за-
вершении приема кадра и готовности данных к использованию. Остальные
блоки относятся к использованию принятых данных.
12. Обнуление счетчика байт необходимо для подготовки приема сле-
дующего кадра.
14–16. В цикле формируются и индицируются первые четыре числа из
кадра. Подробно рассмотрим только 15-ый блок
snprintf(S,4,"%3.1f",Frame.Floats[i+2]);
Укажем также, что позиция на индикаторе для каждого числа равна 4i. По-
втор в цикле таких команд даст верхнюю строку индикатора в формате
x.x x.x x.x x.x
3.24 Обмен данными с картой памяти Secure Digital
3.24.1 Задание
Разработать библиотеку функций взаимодействия с картами памяти
типа SD/MMC. Проверить подпрограммы путем записи и считывания блока
объемом 512 байт.
3.24.2 Общие сведения о карах FLASH-памяти SD/MMC
Карты FLASH-памяти SD (Secure Digital) и MMC (MultiMedia Card)
чрезвычайно распространены в компьютерной технике. Они служат накопи-
телями информации в цифровых фотоаппаратах и других мобильных устрой-
ствах. Запоминающие устройства SD/MMC отличаются малыми габаритами,
высокой надежностью хранения данных, сравнительно низкой ценой и высо-
кой емкостью (емкость может превышать 8 Гбайт). Эти достоинства делают
их удобным для применения и в средствах промышленной автоматики. Сего-
дня MMC встречается редко, а SD часто применяются в модификации mi-
croSD и miniSD. Использование простого переходника делает их абсолютно
совместимыми с SD/MMC.
Карты памяти SD/MMC поддерживают два интерфейса: специальный
интерфейс MultiMedia Card, использующий шесть проводников, не считая
контактов питания, и интерфейс SPI (4 проводника). Применение последнего
предоставляет меньше возможностей, однако позволяет решать все необхо-
димые задачи чтения и записи данных. Здесь ограничимся описанием только
интерфейса SPI. Более того, будут подробно рассмотрены лишь основные,
совершенно необходимые команды. Остальные предлагается изучить само-
стоятельно по многочисленным инструкциям. Реализация функций взаимо-
действия с картами памяти оказывается громоздкой. Поэтому кроме алго-
ритмов будет приведен полный листинг программы.
239
При составлении данного описания руководствовались в основном
документацией фирмы Sandisk, примером, предложенным фирмой NXP, а
также интернет-ресурсом [http://www.dharmanitech.com/]
3.24.3 Команды SD/MMC
Каждый цикл обмена с картой памяти должен начинаться с установки
активного низкого уровня на линии CS. Высокий уровень может быть уста-
новлен после завершения одной команды, а может удерживаться неизменно
активным в течение нескольких команд.
Воздействие на карту выполняется командами одинакового формата
(см. рисунок 3.24.1 вверху). Каждая команда имеет длину 6 байт. Первый
байт состоит из битов 01 и шестиразрядного кода команды, далее следует 32-
разрядный аргумент, уточняющий действие команды, затем циклический код
контроля ошибок CRC7, дополненный в конце единичным битом. Основные
команды сведены в таблицу 3.24.1.
На большинство команд контроллер карты отвечает одним байтом,
обозначенным на рисунке 3.24.1, как «ответ на команду». Ответ чаще всего
приходит с некоторой задержкой, поэтому требуется организовать цикличе-
ский опрос карты в ожидании ответа. Байт ответа имеет ненулевой старший
разряд и содержит коды ошибок. В большинстве случаев он должен быть ра-
вен нулю.
Напомним, что в отличие от I2С, при обмене по SPI только ведущий
может генерировать тактовые сигналы. Причем во время приема на линии
передатчика MOSI (контакт DI карты) должен быть установлен высокий уро-
вень. Поэтому для получения ответа необходимо повторять отправку байта
0xFF с одновременным приемом байта.
Внимание! После получения ответа и до формирования очередной
команды необходимо выполнить холостую передачу байта 0xFF (восемь так-
товых сигналов при ).
3.24.4 Процедура инициализации карты
При выполнении процедуры инициализации тактовая частота прие-
мопередатчика SPI не должна превышать 400 кГц.
После включения питания карта находится в режиме интерфейса Mul-
timedia Card. Для перевода в режим SPI требуется установить высокий уро-
вень на линии CS и подать не менее 74 тактов на линии CLK (то есть не ме-
нее десяти переданных байт). Далее выполнить программный сброс, подав
команду CMD0 с кодом (0x40 0x00 0x00 0x00 0x00 0x95). Здесь 0x95 —
циклический код CRC7, рассчитанный заранее (см. приложение). Дождаться
ответа 0x01, показывающего, что карта находится в режиме ожидания.
Инициализация карты начинается с команды CMD1 с кодом (0x41
0x00 0x00 0x00 0x00 0xFF). В режиме SPI по умолчанию контроль CRC7 кар-
той не производится (хотя при необходимости может быть включен), поэто-
му здесь и далее вычислять код CRC7 нет необходимости. Можно передавать
произвольный байт, заканчивающийся единицей (здесь 0xFF).
240
Формат команды
47 46 45 40 39 8 7 1 0
0 1 Код команды 2S 2R
Аргумент Аргумент CRC7 1
R R
M M
CLK
DI
0x58 Аргумент CRC7 Маркер Данные Данные CRC16 Повторяется при пакетной записи
DO Занят Готов
CLK
CS
Рисунок 3.24.2 – Временные диаграммы обмена данными с картой памяти SD/MMC (вверху — чтение, внизу — запись)
241
Таблица 3.24.1 – Основные команды карты памяти MMC/SD
Код с Ответ при
Выполняемая Длина
Обознач. учетом Аргумент отсутствии
операция пакета, байт
ст. битов ошибок
Режим
CMD0 0x40 — 0x01 —
ожидания
Инициализа-
CMD1 0x41 — 0x00 —
ция
Прервать
CMD12 0x4C — 0x00 —
чтение
Установка Размер
CMD16 0x50 0x00 —
размера блока блока
1…512 +
CMD17 Чтение блока 0x51 Адрес 0x00
+ 2 (CRC16)
Чтение
Не
CMD18 нескольких 0x58 Адрес 0x00
ограничена
блоков
512 +
CMD24 Запись блока 0x58 Адрес 0x00
+2 (CRC16)
Запись Адрес
Не
CMD25 нескольких 0x59 первого 0x00
ограничена
секторов сектора
Так как инициализация занимает около 150 мс, команду CMD1 с по-
следующим ожиданием ответа необходимо повторять несколько раз. Причем
здесь идет речь не просто о циклической передаче байта 0xFF, сопровожда-
ющейся приемом ответа, а о периодическом повторе самой команды. Реко-
мендуется после подачи команды опрашивать карту примерно 250 раз (как
раз примерно 150 мс при кГц), после чего повторить команду и
опрос. И так до тех пор, пока, наконец, не поступит ответ 0x00. Ответ, скорее
всего, будет получен со второй попытки.
Когда инициализация завершена, рекомендуется увеличить скорость
передачи данных до максимальной, что для LPC2148 составляет 7,5 Мбит/с.
3.24.5 Чтение и запись данных
Чтение и запись информации осуществляется блоками. При чтении
размер блока может быть произвольным от 1 до 512 байт. При записи он
фиксированный и составляет 512 байт, что соответствует одному сектору в
логической организации накопителя. Размер блока устанавливается коман-
дой CMD16 (код с учетом старших бит 0x50). Собственно размер задается
младшими байтами аргумента (шестнадцатеричные значения 0x0001–
0x0200). Как обычно после команды выполняется опрос (передача байта
0xFF) и ожидание ответа 0x00. Цикл чтения и записи показан на временных
диаграммах (рисунки 3.24.1, 3.24.2).
242
Команда чтения обозначается CMD17 (код 0x51), команда записи —
CMD24 (код 0x58). Четырехбайтным аргументом команд служит адрес нача-
ла блока. Блок целиком должен помещаться в пределы сектора 512 байт. Зна-
чит, например, нельзя считывать более одного байта с адреса 0x1FF (511),
потому что граница секторов окажется «накрыта» блоком. По той же при-
чине при записи адрес должен быть кратным 512.
Разумеется, необходимо учитывать и объем карты памяти. Установка
адреса, превышающего физический объем, приведет к ошибке. Следует при-
нимать во внимание, что реальная емкость меньше заявленной. Так, напри-
мер, карта microSD фирмы Transcend c маркировкой «2GB» содержит ровно
1886 мегабайт.
Очевидно, что 32-х разрядная адресация позволяет работать с объе-
мом до 4 Гбайт. В картах большей емкости используется не побайтная, а по-
секторная адресация. В адресной части передается номер сектора, размер ко-
торого всегда равен 512 байтам.
После ответа на команду по шине SPI передается пакет данных зара-
нее оговоренной длины (установленной CMD16). Пакет начинается с маркера
0xFE, последовательности байтов данных и двух байт циклического кода
CRC16. Формат пакета одинаков независимо от того, в каком направлении он
передается. Если пакет направлен карте памяти, она подтвердит прием бай-
том в формате, обозначенном как «подтверждение пакета» (рисунок 3.24.1).
Безошибочная передача сопровождается кодом подтверждения 0x05. Пакет,
принятый от карты ни в каком подтверждении не нуждается.
Процедура чтения на этом завершается; но для завершения записи по-
требуется еще некоторое время. При этом на линии MISO (контакт DO кар-
ты) будет удерживаться низкий уровень (рисунок 3.24.2), что при чтении
байта с шины SPI даст код 0x00. После завершения записи установится высо-
кий логический уровень, соответственно, будут считываться коды 0xFF. От-
метим, что активный уровень сигнала CS может быть снят, не дожидаясь
окончания записи. Сигнал «занят» в этом случае также снимается картой и
устанавливается снова только при появлении активного уровня выбора ведо-
мого (CS).
3.24.6 Обработка ошибок
До сих пор считалось, что взаимодействие с картой памяти выполня-
ется без ошибок и ответ равен 0x00. Коротко рассмотрим диагностику воз-
можных ошибок.
Прежде всего, необходимо всякий раз при вызове функции WaitFor
задать маску 0x80. Тогда за удовлетворительный ответ будет приниматься
любой байт с нулем в старшем разряде. Далее потребуется проанализировать
значение, возвращаемое функцией. Нулевой результат говорит об отсутствии
ошибки, ненулевой требует соответствующей обработки. Если же старший
байт результата оказался не равен нулю, значит, ответ вообще не был принят
в течение отведенного времени.
243
Далее, в процедуре записи блока следует изменить ожидаемый байт
подтверждения пакета с 0x05 на 0x01 и задать маску 0x11. Под это правило
попадают все три возможные значения кода подтверждения (см. рисунок
3.24.1 в центре).
Если в процессе чтения данных с карты возникает ошибка, то вместо
маркера пакета 0xFE высылается сообщение об ошибке (см. рисунок 3.24.1
справа). Маркер не имеет ни одного общего бита с сообщением об ошибке,
поэтому простого наложения маски здесь недостаточно. Потребуется отдель-
ная функция ожидания пакета, которая принимала бы как ответ 0xFE, так и
0x00 с маской 0x1F.
do { ... } while ((B!=0xFE)&&(B&0x1F>0)&&(N>0));
Отметим, что картами поддерживается команда CMD13, которая мо-
жет использоваться для выявления ошибок, возникших в процессе записи.
Карта высылает обычный ответ, за которым следует еще один байт, содер-
жащий в основном те же флаги, что и «Сообщение об ошибке».
В ответственных случаях можно гарантировать успешное завершение
сравнения каждого записанного блока.
Для проверки программы можно рекомендовать использовать устрой-
ство для чтения Flash-карт персонального компьютера и программу
DMDE 2.0
3.24.7 Комментарии к алгоритму и программе
Схемы алгоритмов подпрограмм и основной программы показаны на
рисунках 3.24.3–3.24.5. Поскольку ниже приведен полный листинг програм-
мы, подробные комментарии излишни. Разъясним лишь назначение отдель-
ных подпрограмм.
В состав программы входят шесть три функции низкоуровневого
управлении и три высокоуровневого.
Функция SPIByte выполняет передачу одного байта с ожиданием
окончания и прием байта, который одновременно передавался ведомым.
Функция MMCCommand передает по шине SPI 6-байтную команду
карты. Функция имеет три параметра: код команды, 4-байтный аргумент и
код CRC7. Каждый байт передается с помощью SPIByte. Аргумент разделя-
ется на байты операциями сдвига.
Функция WaitFor предназначена для циклического опроса шины SPI и
ожидания определенного байта (передается через параметр функции). На
принятый байт накладывается маска операцией «И», результат сравнивается
с байтом-параметром. Операция повторяется до тех пор, пока не зафиксиро-
вано совпадение, но не более N раз. Число возможных повторов тоже переда-
ется через параметр. Функция возвращает значение принятого байта. Если
выход функции не совпадает с ожидаемым значением, значит, оно так и не
было принято за N попыток.
Высокоуровневая функция MMCInit выполняет весь набор действий
по настройке портовых линий, приемопередатчика SPI и инициализации кар-
ты. После ее завершения карта полностью готова к работе.
244
Начало Начало
1 1
Ввод Byte Ввод Byte, Mask, N
2
Передача по SPI Byte 2
N=N–1
3
3 Да Прием по SPI B
Передача ?
4 N>0и Да
Нет
Byte ≠ B & Mask
4
Прием по SPI Byte
Нет
5 5
Возврат Byte Возврат B
Конец Конец
Начало 8
Линия CS = 1
1
Перевод порта 0 в 9
высокоскор. режим Команда
(0x40, 0x00, 0x95)
2
Настройка режима 10
линий P0.4–P0.6 Ожидание 0x01
10 попыток
3
Режим вывода 11
для линии P0.11 Передача 0xFF
4
Включить SPI; 12
уст. частоту 300 кГц Команда
(0x41, 0x00, 0xFF)
5
Линия CS = 0 13
Ожидание 0x00
250 попыток
Да 6 Нет
k =0; k < 10; k++
14
Ответ 0x00 Нет
принят?
7
Передача 0xFF
Да
15
Линия CS = 0
16
Частота 7,5 МГц
Конец
1 1
Ввод Bytes, Addr, N Ввод Addr
2 2
Линия CS = 0 Линия CS = 0
3 3
Передача 0xFF Передача 0xFF
4 4
Команда Команда
(0x50, N, 0xFF) (0x50, 0x200, 0xFF)
5 5
Ожидание 0x00 Ожидание 0x00
10 попыток 10 попыток
6 6
Передача 0xFF Передача 0xFF
7 7
Команда Команда
(0x51, Addr, 0xFF) (0x58, Addr, 0xFF)
8 8
Ожидание 0x00 Ожидание 0x00
10 попыток 10 попыток
9
9 Передача 0xFE
Ожидание 0xFE
5000 попыток
Нет 10 Да
k = 0; k < 513; k++
Нет 10 Да 11
k =0; k < N+2; k++ Передача Bytes[k]
12
11 Ожидание 0xX5
Прием Bytes[k]
10 попыток
12
Линия CS = 1 13
Ожидание 0xFF
5000 попыток
Конец
14
Линия CS = 1
15
Ввод Bytes
Конец
246
Укажем, что в большинстве случаев ответ будет получен со второй
попытки. Поэтому параметр N в процедуре WaitFor с запасом принят равным
десяти. Около 500 попыток требуется при чтении и записи карты. Там N уве-
личено до 5000. Подбор этих параметров осуществлялся экспериментально.
Время окончания записи одного блока (для карт Transcend) составляет
около 2 мс. При этом оно случайно колеблется, иногда увеличивается до
10 мс и редко может достигать 250 мс.
Время, в течение которого карта занята, существенно сокращается при
записи при пакетной записи. Порядок записи нескольких последовательно
расположенных секторов аналогичен записи одного отдельного сектора. Код
команды при этом 0x59, маркер кадра 0xFC. Если все сектора записаны,
необходимо вместо маркера кадра передать маркер завершения записи 0xFD.
Последовательное чтение выполняется командой с кодом 0x52. Мар-
кер кадра 0xFE будет передаваться картой в начале каждого блока. Останов-
ка чтения выполняется командой 0x4C.
#include <LPC214x.h>
247
/***** Передача команды ******************************/
// Byte - ожидаемый байт
// Mask - маска принятого байта (через лог. умножение)
// N - число попыток приема
unsigned int WaitFor(unsigned char Byte,
unsigned char Mask,
unsigned int N)
{ // Ждать требуемого байта
do N--; while ((Byte!=(SPIByte(0xFF)&Mask))&&(N>0));
return N; // Вернуть число оставшихся повторов
} // Если N=0, значит байт не был принят
FIO0SET=0x00000800; // CS=1
// Не менее 74 тактов...
for (k=0;k<10;k++) SPIByte(0xFF); //... пока CS=1
FIO0CLR=0x00000800; // CS=0 - активный уровень
FIO0SET=0x00000800; // CS=1
S0SPCCR=8; // Макс. скорость
}
FIO0CLR=0x00000800; // CS=0
SPIByte(0xFF); // Холостой байт
MMCCommand(0x50,N,0xFF); // Установка размера блока
WaitFor(0x00,0xFF,10); // Ждать ответа 0x00
FIO0CLR=0x00000800; // CS=0
SPIByte(0xFF); // Холостой байт
MMCCommand(0x50,0x0200,0xFF);// Размер блока = 512
WaitFor(0x00,0xFF,10); // Ждать ответа 0x00
int main(void)
{
int k;
MMCInit();
for (k=0;k<512;k++) Bytes[k]=0x80 | (k>>4);
MMCWrite(Bytes,0);
for (k=0;k<512;k++) Bytes[k]=0x88;
MMCRead(Bytes,0,512);
while (1) ;
}
250
Алфавитный указатель управляющих регистров
IOxCLR ....................................................40
ADGSR ..................................................... 66 IOxDIR .....................................................39
ADxCR...................................................... 64 IOxPIN ......................................................39
ADxGDR ............................................ 66, 67 IOxSET .....................................................40
ADxINTEN ............................................... 67
ADxSTAT ................................................. 67 MIN ...........................................................90
ALDOM .................................................... 90 MONTH ....................................................90
ALDOW.................................................... 90
ALDOY ..................................................... 90 PCON ........................................................94
ALHOUR.................................................. 90 PCONP .....................................................95
ALMIN ..................................................... 90 PINSEL0 ...................................................34
ALMONTH .............................................. 90 PINSEL1 ...................................................34
ALSEC ...................................................... 90 PINSEL2 ...................................................34
ALYEAR .................................................. 90 PLL0CON.................................................28
AMR.......................................................... 93 PLL1CON.................................................28
APBDIV .................................................... 29 PREFRAC ................................................93
PREINT ....................................................93
CCR .......................................................... 92 PWMIR.....................................................60
CIIR .......................................................... 92 PWMLER .................................................60
CPSR ......................................................... 10 PWMMCR ...............................................59
CTCR ........................................................ 92 PWMPC ....................................................59
CTIME0–CTIME2 .................................. 90 PWMPCR .................................................59
PWMPR ....................................................59
DACR........................................................ 71 PWMTC ...................................................59
DOM ......................................................... 90 PWMTCR.................................................59
DOW ......................................................... 90
DOY .......................................................... 90 R0–R12 .....................................................10
R13 (SP) ....................................................10
EXTINT .................................................... 48 R13_xxx ....................................................10
EXTMODE .............................................. 49 R14 (LR) ...................................................10
EXTPOLAR ............................................. 49 R14_xxx ....................................................10
R15 (PC) ...................................................10
FIOxCLR.................................................. 41 RSIR ..........................................................95
FIOxDIR ................................................... 41
FIOxMASK .............................................. 41 S0SPCCR ..................................................74
FIOxPIN ................................................... 41 S0SPCR.....................................................72
FIOxPIN0–3 ............................................. 41 S0SPDR.....................................................74
FIOxPINL ................................................ 41 S0SPINT ...................................................74
FIOxPINU ................................................ 41 S0SPSR .....................................................74
FIOxSET .................................................. 41 SCS ............................................................40
SEC ...........................................................90
HOUR ....................................................... 90 SPSR_xxx .................................................10
I2CxCONCLR ......................................... 77 TxCCR ......................................................53
I2CxCONSET .......................................... 77 TxCRx .......................................................53
I2CxDAT .................................................. 78 TxCTCR ...................................................51
I2CxSCLH .......................................... 78, 79 TxEMR .....................................................53
I2CxSCLL .......................................... 78, 79 TxIR ..........................................................51
I2CxSTAT ................................................ 78 TxMCR .....................................................52
ILR ............................................................ 92 TxMRx ......................................................52
INTWAKE ............................................... 48 TxPR .........................................................52
251
TxPС ......................................................... 52
TxTC ......................................................... 52 VICDefVectAddr .....................................45
TxTCR ...................................................... 51 VICFIQStatus ..........................................43
VICIntEnable ...........................................43
U0ACR...................................................... 85 VICIntEnClear ........................................44
U0DLL ...................................................... 82 VICIntSelect .............................................44
U0DLM ..................................................... 82 VICIRQStatus ..........................................43
U0FCR ...................................................... 83 VICProtection ..........................................45
U0FDR ...................................................... 82 VICRAWStatus .......................................43
U0IER ....................................................... 86 VICSoftInt ................................................44
U0IIR ........................................................ 86 VICSoftIntClear ......................................44
U0LCR ...................................................... 84 VICVectAddr ...........................................45
U0LSR ...................................................... 84 VICVectAddr0–15 ...................................45
U0RBR ...................................................... 81 VICVectCntl0–15.....................................44
U0TER ...................................................... 85
U0THR...................................................... 81 YEAR ........................................................90
252
Список литературы
1. Редькин П. П. Микроконтроллеры ARM7 семейства LPC2000; руководство
пользователя. М.: Издательский дом «Додэка-XXI», 2007. 560 с.
2. Мартин Т. Микроконтроллеры ARM7. Семейство LPC2000 компании
Philips. Вводный курс / Пер с англ. М.: Издательский дом «Додэка-XXI»,
2006. 240 с.
3. Подбельский В. В., Фомин С. С. Программирование на языке Си: учеб. по-
собие. 2-е доп. изд. М.: Финансы и статистика, 2007. 600 с.
4. Климова Л. М. С++. Практическое программирование. Решение типовых
задач. М.: Кудиц-Образ, 2001. 592 с.
5. Рабинер Л., Гоулд Б. Теория и применение цифровой обработки сигналов.
М.: Мир, 1978. 848 c.
253
Содержание
Перечень сокращений ....................................................................................................................3
Предисловие ...................................................................................................................................4
Введение ..........................................................................................................................................6
Часть 1. Архитектура и аппаратные средства микроконтроллера LPC214x......................8
1.1 Общие сведения о микроконтроллерах LPC214x.............................................................8
1.2 Программистская модель процессорного ядра ARM7TDMI ..........................................9
1.2.1 Режимы работы ядра ARM7 ................................................................................................................... 9
1.2.2 Система регистров ................................................................................................................................ 10
1.2.3 Слово состояния программы ................................................................................................................. 10
1.2.4 Организация памяти .............................................................................................................................. 13
1.3 Система команд .................................................................................................................14
1.3.1 Команды арифметической и логической обработки .......................................................................... 15
1.3.2 Команды умножения .............................................................................................................................. 15
1.3.3 Команды регистровой пересылки ......................................................................................................... 15
1.3.4 Команды загрузки и сохранения регистров .......................................................................................... 19
1.3.5 Команды пакетного обмена с памятью ............................................................................................... 19
1.3.6 Команды передачи управления .............................................................................................................. 20
1.3.7 Команды обращения к слову состояния программы ........................................................................... 20
1.4 Методы адресации .............................................................................................................20
1.4.1 Непосредственная адресация ................................................................................................................ 21
1.4.2 Регистровая адресация .......................................................................................................................... 21
1.4.3 Косвенная адресация .............................................................................................................................. 22
1.4.4 Индексная адресация .............................................................................................................................. 22
1.5 Процедура начальной загрузки и режимы отображения памяти ..................................24
1.6 Обработка исключительных ситуаций ............................................................................25
1.7 Система тактирования.......................................................................................................27
1.7.1 Выбор тактовой частоты микроконтроллера ................................................................................... 27
1.7.2 Настройка тактирования периферийных устройств ........................................................................ 28
1.8 Модуль ускорения памяти ................................................................................................29
1.9 Внешние выводы микроконтроллера ..............................................................................30
1.9.1 Служебные контакты ........................................................................................................................... 30
1.9.2 Программно-управляемые линии ввода-вывода ................................................................................... 30
1.9.3 Альтернативные функции линий ввода вывода ................................................................................... 31
1.10 Цифровые порты ввода-вывода .....................................................................................37
1.10.1 Управление портом через низкоскоростную шину ............................................................................ 38
1.10.2 Управление портом через высокоскоростную шину ......................................................................... 40
1.11 Система прерываний .......................................................................................................41
1.11.1 Назначение системы прерываний ....................................................................................................... 41
1.11.2 Процесс обработки прерываний IRQ .................................................................................................. 42
1.11.3 Процесс обработки быстрых прерываний FIQ ................................................................................. 43
1.11.4 Регистры управления системой прерываний ..................................................................................... 43
1.11.5 Порядок настройки прерывания IRQ .................................................................................................. 45
1.11.6 Порядок настройки быстрого прерывания FIQ ................................................................................ 46
1.11.7 Процедура обработки прерывания ..................................................................................................... 46
1.11.8 Задержка обработки прерывания....................................................................................................... 46
1.12 Внешние прерывания ......................................................................................................48
1.12.1 Регистры управления блоком внешних прерываний .......................................................................... 48
1.12.2 Порядок настройки блока внешних прерываний ................................................................................ 49
1.13 Таймеры-счетчики ...........................................................................................................50
1.13.1 Режим таймера и схема совпадения .................................................................................................. 50
1.13.2 Режим счетчика ................................................................................................................................... 51
1.13.3 Схема захвата ....................................................................................................................................... 51
1.13.4 Управляющие регистры ....................................................................................................................... 51
1.13.5 Формирование интервалов времени через систему прерываний ..................................................... 53
1.13.6 Измерение периода и длительности импульса с помощью устройства захвата .......................... 54
1.13.7 Подсчет числа импульсов в единицу времени ..................................................................................... 55
1.14 Широтно-импульсный модулятор .................................................................................55
254
1.14.1 Основы функционирования................................................................................................................... 56
1.14.2 Дополнительные возможности ........................................................................................................... 58
1.14.3 Регистры управления ШИМ ................................................................................................................ 59
1.14.4 Порядок настройки ШИМ ................................................................................................................... 61
1.15 Аналого-цифровые преобразователи.............................................................................61
1.15.1 Краткие сведения о встроенных АЦП ................................................................................................ 61
1.15.2 Общие рекомендации по использованию АЦП .................................................................................... 62
1.15.3 Управляющие регистры ....................................................................................................................... 64
1.15.4 Порядок настройки АЦП ..................................................................................................................... 67
1.15.5 Программный запуск аналого-цифрового преобразователя ............................................................. 68
1.15.6 Запуск аналого-цифрового преобразователя по таймеру ................................................................. 68
1.15.7 Программный опрос готовности АЦП ............................................................................................... 68
1.15.8 Опрос готовности АЦП по прерыванию ............................................................................................ 69
1.15.9 Считывание и масштабирование результата АЦП ......................................................................... 69
1.16 Цифро-аналоговый преобразователь .............................................................................70
1.16.1 Регистр управления ЦАП ..................................................................................................................... 71
1.16.2 Рекомендации по применению ЦАП .................................................................................................... 71
1.17 Последовательный синхронный приемо-передатчик SPI ...........................................72
1.17.1 Назначение и основы функционирования интерфейса SPI ............................................................... 72
1.17.2 Управляющие регистры ....................................................................................................................... 72
1.17.3 Передача и прием данных в режиме ведущего................................................................................... 74
1.17.4 Передача и прием данных в режиме ведомого................................................................................... 75
1.18 Последовательный синхронный приемо-передатчик I2С ............................................75
1.18.1 Назначение и основы функционирования интерфейса I2С................................................................ 75
1.18.2 Управляющие регистры ....................................................................................................................... 77
1.18.3 Настройка модуля I2C .......................................................................................................................... 79
1.18.4 Типовые циклы обмена данными по шине I2C .................................................................................... 79
1.19 Последовательный асинхронный приемопередатчик UART ......................................80
1.19.1 Назначение и основы функционирования порта UART ..................................................................... 80
1.19.2 Управляющие регистры ....................................................................................................................... 81
1.19.3 Настройка порта UART ...................................................................................................................... 87
1.19.4 Прием байта с опросом флага ............................................................................................................ 87
1.19.5 Передача байта с опросом флага ....................................................................................................... 88
1.19.6 Прием и передача данных с использованием прерываний ................................................................. 88
1.19.7 Прием и передача пакетов данных ..................................................................................................... 89
1.19.8 Диагностика ошибок ............................................................................................................................ 89
1.19.9 Автоматическая настройка скорости .............................................................................................. 89
1.20 Часы реального времени .................................................................................................90
1.20.1 Основные возможности часов реального времени ............................................................................ 90
1.20.2 Управляющие регистры ....................................................................................................................... 90
1.20.3 Рекомендации по применению ............................................................................................................. 93
1.21 Управление питанием и идентификация источников сброса .....................................93
1.21.1 Краткие сведения о мониторе питания ............................................................................................. 93
1.21.2 Управляющие регистры ....................................................................................................................... 94
Часть 2. Разработка и отладка программ с помощью современных инструментальных
средств .........................................................................................................................................96
2.1 Форматы представления чисел.........................................................................................96
2.1.1 Основные коды представления целых чисел ......................................................................................... 96
2.1.2 Форматы представление целых чисел, приятные в языке Си ............................................................ 98
2.1.3 Форматы чисел c плавающей точкой стандарта IEEE754 ............................................................... 99
2.2 Основы программирования на языке Си .......................................................................101
2.2.1 Структура программы ........................................................................................................................ 102
2.2.2 Числовые константы ........................................................................................................................... 102
2.2.3 Переменные и именованные константы ............................................................................................ 103
2.2.4 Оператор присваивания, выражения и операции .............................................................................. 104
2.2.5 Условный оператор .............................................................................................................................. 104
2.2.6 Приведение и преобразование типов .................................................................................................. 104
2.2.7 Массивы ................................................................................................................................................. 107
2.2.8 Строки символов................................................................................................................................... 107
2.2.9 Структуры ............................................................................................................................................ 108
2.2.10 Объединения ........................................................................................................................................ 108
255
2.2.11 Указатели ............................................................................................................................................ 109
2.2.12 Ветвление ............................................................................................................................................ 109
2.2.13 Множественное ветвление................................................................................................................ 110
2.2.14 Цикл со счетчиком.............................................................................................................................. 111
2.2.15 Циклы с предусловием и постусловием ............................................................................................. 111
2.2.16 Функции................................................................................................................................................ 112
2.2.17 Некоторые директивы компилятора ............................................................................................... 113
2.2.18 Библиотека математических функций MATH.h ............................................................................. 113
2.2.19 Функция создания форматированных строк SNPRINTF ................................................................ 116
2.2.20 Ассемблер в Си-программах ............................................................................................................... 118
2.3 Интегрированная среда разработки Keil µVision 4 ......................................................119
2.3.1 Создание проекта ................................................................................................................................. 119
2.3.2 Создание файла программы ................................................................................................................. 119
2.3.3 Настройка проекта.............................................................................................................................. 120
2.3.4 Набор текста программы ................................................................................................................... 122
2.3.5 Компиляция программы ........................................................................................................................ 123
2.3.6 Отладка программы ............................................................................................................................. 124
2.3.7 Основные отладочные инструменты среды Keil µVision 4 ............................................................. 127
2.3.8 Управление распределением памяти ................................................................................................... 129
2.4 Методика отладки программ ..........................................................................................131
2.4.1 Быстрый поиск ошибок........................................................................................................................ 132
2.4.2 Ввод и вывод дискретных сигналов ..................................................................................................... 137
2.4.3 Таймер-счетчик. Формирование интервалов времени ...................................................................... 138
2.4.4 Таймер-счетчик. Формирование внешних сигналов совпадения ....................................................... 139
2.4.5 Таймер-счетчик. Счетчик внешних событий .................................................................................... 139
2.4.6 Таймер-счетчик. Устройство захвата .............................................................................................. 140
2.4.7 Широтно-импульсный модулятор ...................................................................................................... 140
2.4.8 Аналого-цифровой преобразователь ................................................................................................... 141
2.4.9 Цифро-аналоговый преобразователь .................................................................................................. 142
2.4.10 Приемопередатчик SPI ...................................................................................................................... 142
2.4.11 Приемопередатчик I2C ....................................................................................................................... 143
2.4.12 Приемопередатчик UART .................................................................................................................. 144
2.4.13 Часы реального времени ..................................................................................................................... 145
2.5 О программировании ARM7 на ассемблере .................................................................146
2.5.1 Основные правила записи программ на ассемблере .......................................................................... 146
2.5.2 Псевдокоманды ..................................................................................................................................... 147
2.5.3 Директивы ассемблера ......................................................................................................................... 147
2.5.4 Макросы ................................................................................................................................................. 149
2.5.5 Пример простой программы ............................................................................................................... 150
2.6 Распространенные средства разработки и отладки ......................................................153
2.6.1 Демонстрационные платы EA-EDU-001 и EA-EDU-011 .................................................................. 153
2.6.2 Внутрисхемный отладчик J-Link ........................................................................................................ 156
2.6.3 Утилиты программирования ПЗУ LPC Flash Utility и FlashMagic ................................................. 157
2.6.4 Программа-терминал 232Analyzer ...................................................................................................... 158
2.6.5 Низкоуровневый редактор диска DMDE ............................................................................................ 159
Часть 3. Решение типовых задач локального управления ....................................................160
3.1 Формирование временной задержки с помощью цикла ..............................................160
3.1.1 Задание ................................................................................................................................................... 160
3.1.2 Общие рекомендации ............................................................................................................................ 160
3.1.3 Алгоритм программы ........................................................................................................................... 160
3.1.4 Отладка ................................................................................................................................................. 161
3.1.5 Дополнительные сведения о формировании временной задержки .................................................. 161
3.2 Формирование дискретного сигнала с помощью таймера ..........................................163
3.2.1 Задание ................................................................................................................................................... 163
3.2.2 Общие рекомендации ............................................................................................................................ 163
3.2.3 Алгоритм программы ........................................................................................................................... 164
3.3 Опрос дискретного датчика или кнопки .......................................................................165
3.3.1 Задание ................................................................................................................................................... 165
3.3.2 Общие рекомендации ............................................................................................................................ 165
3.3.3 Алгоритм программы ........................................................................................................................... 165
3.3.4 Отладка ................................................................................................................................................. 166
256
3.4 Опрос состояния механических контактов с подавлением дребезга .........................166
3.4.1 Задание ................................................................................................................................................... 166
3.4.2 Общие рекомендации ............................................................................................................................ 167
3.4.3 Алгоритм программы ........................................................................................................................... 169
3.4.4 Отладка ................................................................................................................................................. 170
3.5 Опрос клавиатуры с автоповтором ................................................................................170
3.5.1 Задание ................................................................................................................................................... 170
3.5.2 Общие рекомендации ............................................................................................................................ 171
3.5.3 Алгоритм программы ........................................................................................................................... 171
3.5.4 Отладка ................................................................................................................................................. 173
3.6 Формирование импульсного управляющего сигнала с помощью модуля ШИМ .....174
3.6.1 Задание ................................................................................................................................................... 174
3.6.2 Общие сведения ..................................................................................................................................... 174
3.6.3 Алгоритм программы ........................................................................................................................... 175
3.6.4 Отладка ................................................................................................................................................. 176
3.6.5 Синхронизация внешним сигналом ...................................................................................................... 176
3.7 Формирование сигналов специальной формы с помощью ЦАП ................................177
3.7.1 Задание ................................................................................................................................................... 177
3.7.2 Основы ................................................................................................................................................... 177
3.7.3 Алгоритм программы ........................................................................................................................... 179
3.7.4 Повышение точности генерирования частоты ................................................................................ 180
3.7.5 Выбор числа дискрет ............................................................................................................................ 181
3.8 Управление двухфазным шаговым двигателем............................................................182
3.8.1 Задание ................................................................................................................................................... 182
3.8.2 Общие сведения ..................................................................................................................................... 182
3.8.3 Алгоритм программы ........................................................................................................................... 183
3.9 Применение ШИМ для формирования низкочастотных аналоговых сигналов .......185
3.9.1 Задание ................................................................................................................................................... 185
3.9.2 Основные сведения ................................................................................................................................ 185
3.9.3 Алгоритм основной программы ........................................................................................................... 187
3.9.4 Алгоритм процедуры обработки прерывания.................................................................................... 188
3.10 Управление символьным жидкокристаллическим индикатором ...............................189
3.10.1 Задание ................................................................................................................................................. 189
3.10.2 Управление модулем жидкокристаллической индикации ............................................................... 189
3.10.3 Разработка функции управления ЖКИ с ожиданием готовности .................................................. 191
3.10.4 Функция вывода строки символов ..................................................................................................... 193
3.10.5 Разработка функции инициализации модуля ЖКИ ......................................................................... 193
3.10.6 Разработка тестовой программы .................................................................................................... 194
3.10.7 Управление ЖКИ с опросом флага готовности .............................................................................. 194
3.10.8 Программирование произвольных символов ..................................................................................... 194
3.11 Управление матричным светодиодным индикатором ...............................................196
3.11.1 Задание ................................................................................................................................................. 196
3.11.2 Основные рекомендации ..................................................................................................................... 196
3.11.3 Алгоритм основной программы ......................................................................................................... 197
3.11.4 Алгоритм процедуры обработки прерывания .................................................................................. 200
3.11.5 Реализация движения строки ............................................................................................................ 201
3.12 Управление матричным жидкокристаллическим дисплеем .....................................203
3.12.1 Управление дисплеем на основе контроллера PCF8833 .................................................................. 203
3.12.2 Построение простейших геометрических фигур ............................................................................ 206
3.13 Измерение постоянного напряжения...........................................................................206
3.13.1 Задание ................................................................................................................................................. 206
3.13.2 Основные рекомендации ..................................................................................................................... 206
3.13.3 Алгоритм основной программы ......................................................................................................... 207
3.13.4 Алгоритм процедуры обработки прерывания от АЦП ................................................................... 208
3.13.5 АЦП с циклическим опросом нескольких каналов ............................................................................ 208
3.13.6 Автоматический выбор пределов измерения ................................................................................... 209
3.14 Измерение параметров уровня переменного напряжения.........................................210
3.14.1 Задание ................................................................................................................................................. 210
3.14.2 Основные рекомендации ..................................................................................................................... 210
3.14.3 Алгоритм основной программы ......................................................................................................... 211
3.14.4 Алгоритм процедуры обработки прерывания .................................................................................. 213
257
3.15 Измерение ускорения с помощью трехосевого акселерометра ................................213
3.16 Измерение интервалов времени с помощью таймера ................................................214
3.16.1 Задание ................................................................................................................................................. 214
3.16.2 Общие рекомендации .......................................................................................................................... 214
3.16.3 Алгоритм основной программы ......................................................................................................... 214
3.16.4 Алгоритм процедуры обработки прерывания .................................................................................. 216
3.16.5 Повышение разрешающей способности путем усреднения ........................................................... 216
3.16.6 Введение поправок .............................................................................................................................. 216
3.17 Измерение частоты с помощью счетчика ...................................................................217
3.17.1 Задание ................................................................................................................................................. 217
3.17.2 Основные рекомендации ..................................................................................................................... 218
3.17.3 Алгоритм программы ......................................................................................................................... 218
3.17.4 Повышение точности измерений ...................................................................................................... 220
3.18 Опрос цифрового датчика температуры. Интерфейс I2C ..........................................220
3.18.1 Задание ................................................................................................................................................. 220
3.18.2 Общие рекомендации .......................................................................................................................... 221
3.18.3 Алгоритм программы ......................................................................................................................... 223
3.19 Управление внешним портом дискретного ввода-вывода ........................................225
3.20 Обмен данными с электрически перепрограммируемым ПЗУ .................................225
3.20.1 Задание ................................................................................................................................................. 225
3.20.2 Общие сведения о микросхемах EEPROM ........................................................................................ 225
3.20.3 Адресация в микросхемах EEPROM .................................................................................................. 226
3.20.4 Порядок чтения EEPROM .................................................................................................................. 226
3.20.5 Порядок записи EEPROM ................................................................................................................... 227
3.20.6 Разработка программы чтения EEPROM ....................................................................................... 227
3.20.7 Разработка функции записи блока данных в EEPROM ................................................................... 230
3.21 Интерфейс RS-232. Прием и передача простых команд............................................232
3.21.1 Задание ................................................................................................................................................. 232
3.21.2 Алгоритм программы ......................................................................................................................... 232
3.21.3 Автоматическая настройка скорости ............................................................................................ 234
3.22 Интерфейс RS-232. Передача пакета с использованием прерываний ......................234
3.22.1 Задание ................................................................................................................................................. 234
3.22.2 Основные рекомендации ..................................................................................................................... 234
3.22.3 Алгоритм программы ......................................................................................................................... 234
3.23 Интерфейс RS-232. Прием пакета переменной длины ..............................................236
3.23.1 Задание ................................................................................................................................................. 236
3.23.2 Основы реализации ............................................................................................................................. 236
3.23.3 Алгоритм программы ......................................................................................................................... 237
3.24 Обмен данными с картой памяти Secure Digital .........................................................239
3.24.1 Задание ................................................................................................................................................. 239
3.24.2 Общие сведения о карах FLASH-памяти SD/MMC .......................................................................... 239
3.24.3 Команды SD/MMC .............................................................................................................................. 240
3.24.4 Процедура инициализации карты...................................................................................................... 240
3.24.5 Чтение и запись данных ..................................................................................................................... 242
3.24.6 Обработка ошибок ............................................................................................................................. 243
3.24.7 Комментарии к алгоритму и программе .......................................................................................... 244
Алфавитный указатель управляющих регистров ..................................................................251
Список литературы ..................................................................................................................253
Содержание ...............................................................................................................................254
258