- •Перечень сокращений
- •Предисловие
- •Введение
- •Часть 1. Архитектура и аппаратные средства микроконтроллера LPC214x
- •1.1 Общие сведения о микроконтроллерах LPC214x
- •1.2 Программистская модель процессорного ядра ARM7TDMI
- •1.2.1 Режимы работы ядра ARM7
- •1.2.2 Система регистров
- •1.2.3 Слово состояния программы
- •1.2.4 Организация памяти
- •1.3 Система команд
- •1.3.1 Команды арифметической и логической обработки
- •1.3.2 Команды умножения
- •1.3.3 Команды регистровой пересылки
- •1.3.4 Команды загрузки и сохранения регистров
- •1.3.5 Команды пакетного обмена с памятью
- •1.3.6 Команды передачи управления
- •1.3.7 Команды обращения к слову состояния программы
- •1.4 Методы адресации
- •1.4.1 Непосредственная адресация
- •1.4.2 Регистровая адресация
- •1.4.3 Косвенная адресация
- •1.4.4 Индексная адресация
- •1.5 Процедура начальной загрузки и режимы отображения памяти
- •1.6 Обработка исключительных ситуаций
- •1.7 Система тактирования
- •1.7.1 Выбор тактовой частоты микроконтроллера
- •1.7.2 Настройка тактирования периферийных устройств
- •1.8 Модуль ускорения памяти
- •1.9 Внешние выводы микроконтроллера
- •1.9.1 Служебные контакты
- •1.9.2 Программно-управляемые линии ввода-вывода
- •1.9.3 Альтернативные функции линий ввода вывода
- •1.10 Цифровые порты ввода-вывода
- •1.10.1 Управление портом через низкоскоростную шину
- •1.10.2 Управление портом через высокоскоростную шину
- •1.11 Система прерываний
- •1.11.1 Назначение системы прерываний
- •1.11.2 Процесс обработки прерываний IRQ
- •1.11.3 Процесс обработки быстрых прерываний FIQ
- •1.11.4 Регистры управления системой прерываний
- •1.11.5 Порядок настройки прерывания IRQ
- •1.11.6 Порядок настройки быстрого прерывания FIQ
- •1.11.7 Процедура обработки прерывания
- •1.11.8 Задержка обработки прерывания
- •1.12 Внешние прерывания
- •1.12.1 Регистры управления блоком внешних прерываний
- •1.12.2 Порядок настройки блока внешних прерываний
- •1.13 Таймеры-счетчики
- •1.13.1 Режим таймера и схема совпадения
- •1.13.2 Режим счетчика
- •1.13.3 Схема захвата
- •1.13.4 Управляющие регистры
- •1.13.5 Формирование интервалов времени через систему прерываний
- •1.13.6 Измерение периода и длительности импульса с помощью устройства захвата
- •1.13.7 Подсчет числа импульсов в единицу времени
- •1.14 Широтно-импульсный модулятор
- •1.14.1 Основы функционирования
- •1.14.2 Дополнительные возможности
- •1.14.3 Регистры управления ШИМ
- •1.14.4 Порядок настройки ШИМ
- •1.15 Аналого-цифровые преобразователи
- •1.15.1 Краткие сведения о встроенных АЦП
- •1.15.2 Общие рекомендации по использованию АЦП
- •1.15.3 Управляющие регистры
- •1.15.4 Порядок настройки АЦП
- •1.15.5 Программный запуск аналого-цифрового преобразователя
- •1.15.6 Запуск аналого-цифрового преобразователя по таймеру
- •1.15.7 Программный опрос готовности АЦП
- •1.15.8 Опрос готовности АЦП по прерыванию
- •1.15.9 Считывание и масштабирование результата АЦП
- •1.16 Цифро-аналоговый преобразователь
- •1.16.1 Регистр управления ЦАП
- •1.16.2 Рекомендации по применению ЦАП
- •1.17 Последовательный синхронный приемо-передатчик SPI
- •1.17.1 Назначение и основы функционирования интерфейса SPI
- •1.17.2 Управляющие регистры
- •1.17.3 Передача и прием данных в режиме ведущего
- •1.17.4 Передача и прием данных в режиме ведомого
- •1.18 Последовательный синхронный приемо-передатчик I2С
- •1.18.1 Назначение и основы функционирования интерфейса I2С
- •1.18.2 Управляющие регистры
- •1.18.3 Настройка модуля I2C
- •1.18.4 Типовые циклы обмена данными по шине I2C
- •1.19 Последовательный асинхронный приемопередатчик UART
- •1.19.1 Назначение и основы функционирования порта UART
- •1.19.2 Управляющие регистры
- •1.19.3 Настройка порта UART
- •1.19.4 Прием байта с опросом флага
- •1.19.5 Передача байта с опросом флага
- •1.19.6 Прием и передача данных с использованием прерываний
- •1.19.7 Прием и передача пакетов данных
- •1.19.8 Диагностика ошибок
- •1.19.9 Автоматическая настройка скорости
- •1.20 Часы реального времени
- •1.20.1 Основные возможности часов реального времени
- •1.20.2 Управляющие регистры
- •1.20.3 Рекомендации по применению
- •1.21 Управление питанием и идентификация источников сброса
- •1.21.1 Краткие сведения о мониторе питания
- •1.21.2 Управляющие регистры
- •Часть 2. Разработка и отладка программ с помощью современных инструментальных средств
- •2.1 Форматы представления чисел
- •2.1.1 Основные коды представления целых чисел
- •2.1.2 Форматы представление целых чисел, приятные в языке Си
- •2.1.3 Форматы чисел c плавающей точкой стандарта IEEE754
- •2.2 Основы программирования на языке Си
- •2.2.1 Структура программы
- •2.2.2 Числовые константы
- •2.2.3 Переменные и именованные константы
- •2.2.4 Оператор присваивания, выражения и операции
- •2.2.5 Условный оператор
- •2.2.6 Приведение и преобразование типов
- •2.2.7 Массивы
- •2.2.8 Строки символов
- •2.2.9 Структуры
- •2.2.10 Объединения
- •2.2.11 Указатели
- •2.2.12 Ветвление
- •2.2.13 Множественное ветвление
- •2.2.14 Цикл со счетчиком
- •2.2.15 Циклы с предусловием и постусловием
- •2.2.16 Функции
- •2.2.17 Некоторые директивы компилятора
- •2.2.18 Библиотека математических функций MATH.h
- •2.2.19 Функция создания форматированных строк SNPRINTF
- •2.2.20 Ассемблер в Си-программах
- •2.3 Интегрированная среда разработки Keil µVision 4
- •2.3.1 Создание проекта
- •2.3.2 Создание файла программы
- •2.3.3 Настройка проекта
- •2.3.4 Набор текста программы
- •2.3.5 Компиляция программы
- •2.3.6 Отладка программы
- •2.3.7 Основные отладочные инструменты среды Keil µVision 4
- •2.3.8 Управление распределением памяти
- •2.4 Методика отладки программ
- •2.4.1 Быстрый поиск ошибок
- •2.4.2 Ввод и вывод дискретных сигналов
- •2.4.3 Таймер-счетчик. Формирование интервалов времени
- •2.4.4 Таймер-счетчик. Формирование внешних сигналов совпадения
- •2.4.5 Таймер-счетчик. Счетчик внешних событий
- •2.4.6 Таймер-счетчик. Устройство захвата
- •2.4.7 Широтно-импульсный модулятор
- •2.4.8 Аналого-цифровой преобразователь
- •2.4.9 Цифро-аналоговый преобразователь
- •2.4.10 Приемопередатчик SPI
- •2.4.11 Приемопередатчик I2C
- •2.4.12 Приемопередатчик UART
- •2.4.13 Часы реального времени
- •2.5 О программировании ARM7 на ассемблере
- •2.5.1 Основные правила записи программ на ассемблере
- •2.5.2 Псевдокоманды
- •2.5.3 Директивы ассемблера
- •2.5.4 Макросы
- •2.5.5 Пример простой программы
- •2.6 Распространенные средства разработки и отладки
- •2.6.1 Демонстрационные платы EA-EDU-001 и EA-EDU-011
- •2.6.2 Внутрисхемный отладчик J-Link
- •2.6.3 Утилиты программирования ПЗУ LPC Flash Utility и FlashMagic
- •2.6.4 Программа-терминал 232Analyzer
- •2.6.5 Низкоуровневый редактор диска DMDE
- •Часть 3. Решение типовых задач локального управления
- •3.1 Формирование временной задержки с помощью цикла
- •3.1.1 Задание
- •3.1.2 Общие рекомендации
- •3.1.3 Алгоритм программы
- •3.1.4 Отладка
- •3.1.5 Дополнительные сведения о формировании временной задержки
- •3.2 Формирование дискретного сигнала с помощью таймера
- •3.2.1 Задание
- •3.2.2 Общие рекомендации
- •3.2.3 Алгоритм программы
- •3.3 Опрос дискретного датчика или кнопки
- •3.3.1 Задание
- •3.3.2 Общие рекомендации
- •3.3.3 Алгоритм программы
- •3.3.4 Отладка
- •3.4 Опрос состояния механических контактов с подавлением дребезга
- •3.4.1 Задание
- •3.4.2 Общие рекомендации
- •3.4.3 Алгоритм программы
- •3.4.4 Отладка
- •3.5 Опрос клавиатуры с автоповтором
- •3.5.1 Задание
- •3.5.2 Общие рекомендации
- •3.5.3 Алгоритм программы
- •3.5.4 Отладка
- •3.6 Формирование импульсного управляющего сигнала с помощью модуля ШИМ
- •3.6.1 Задание
- •3.6.2 Общие сведения
- •3.6.3 Алгоритм программы
- •3.6.4 Отладка
- •3.6.5 Синхронизация внешним сигналом
- •3.7 Формирование сигналов специальной формы с помощью ЦАП
- •3.7.1 Задание
- •3.7.2 Основы
- •3.7.3 Алгоритм программы
- •3.7.4 Повышение точности генерирования частоты
- •3.7.5 Выбор числа дискрет
- •3.8 Управление двухфазным шаговым двигателем
- •3.8.1 Задание
- •3.8.2 Общие сведения
- •3.8.3 Алгоритм программы
- •3.9 Применение ШИМ для формирования низкочастотных аналоговых сигналов
- •3.9.1 Задание
- •3.9.2 Основные сведения
- •3.9.3 Алгоритм основной программы
- •3.9.4 Алгоритм процедуры обработки прерывания
- •3.10 Управление символьным жидкокристаллическим индикатором
- •3.10.1 Задание
- •3.10.2 Управление модулем жидкокристаллической индикации
- •3.10.3 Разработка функции управления ЖКИ с ожиданием готовности
- •3.10.4 Функция вывода строки символов
- •3.10.5 Разработка функции инициализации модуля ЖКИ
- •3.10.6 Разработка тестовой программы
- •3.10.7 Управление ЖКИ с опросом флага готовности
- •3.10.8 Программирование произвольных символов
- •3.11 Управление матричным светодиодным индикатором
- •3.11.1 Задание
- •3.11.2 Основные рекомендации
- •3.11.3 Алгоритм основной программы
- •3.11.4 Алгоритм процедуры обработки прерывания
- •3.11.5 Реализация движения строки
- •3.12 Управление матричным жидкокристаллическим дисплеем
- •3.12.1 Управление дисплеем на основе контроллера PCF8833
- •3.12.2 Построение простейших геометрических фигур
- •3.13 Измерение постоянного напряжения
- •3.13.1 Задание
- •3.13.2 Основные рекомендации
- •3.13.3 Алгоритм основной программы
- •3.13.4 Алгоритм процедуры обработки прерывания от АЦП
- •3.13.5 АЦП с циклическим опросом нескольких каналов
- •3.13.6 Автоматический выбор пределов измерения
- •3.14 Измерение параметров уровня переменного напряжения
- •3.14.1 Задание
- •3.14.2 Основные рекомендации
- •3.14.3 Алгоритм основной программы
- •3.14.4 Алгоритм процедуры обработки прерывания
- •3.15 Измерение ускорения с помощью трехосевого акселерометра
- •3.16 Измерение интервалов времени с помощью таймера
- •3.16.1 Задание
- •3.16.2 Общие рекомендации
- •3.16.3 Алгоритм основной программы
- •3.16.4 Алгоритм процедуры обработки прерывания
- •3.16.5 Повышение разрешающей способности путем усреднения
- •3.16.6 Введение поправок
- •3.17 Измерение частоты с помощью счетчика
- •3.17.1 Задание
- •3.17.2 Основные рекомендации
- •3.17.3 Алгоритм программы
- •3.17.4 Повышение точности измерений
- •3.18 Опрос цифрового датчика температуры. Интерфейс I2C
- •3.18.1 Задание
- •3.18.2 Общие рекомендации
- •3.18.3 Алгоритм программы
- •3.20 Обмен данными с электрически перепрограммируемым ПЗУ
- •3.20.1 Задание
- •3.20.2 Общие сведения о микросхемах EEPROM
- •3.20.3 Адресация в микросхемах EEPROM
- •3.20.4 Порядок чтения EEPROM
- •3.20.5 Порядок записи EEPROM
- •3.20.6 Разработка программы чтения EEPROM
- •3.20.7 Разработка функции записи блока данных в EEPROM
- •3.21 Интерфейс RS-232. Прием и передача простых команд
- •3.21.1 Задание
- •3.21.2 Алгоритм программы
- •3.21.3 Автоматическая настройка скорости
- •3.22.1 Задание
- •3.22.2 Основные рекомендации
- •3.22.3 Алгоритм программы
- •3.23 Интерфейс RS-232. Прием пакета переменной длины
- •3.23.1 Задание
- •3.23.2 Основы реализации
- •3.23.3 Алгоритм программы
- •3.24 Обмен данными с картой памяти Secure Digital
- •3.24.1 Задание
- •3.24.2 Общие сведения о карах FLASH-памяти SD/MMC
- •3.24.3 Команды SD/MMC
- •3.24.4 Процедура инициализации карты
- •3.24.5 Чтение и запись данных
- •3.24.6 Обработка ошибок
- •3.24.7 Комментарии к алгоритму и программе
- •Алфавитный указатель управляющих регистров
- •Список литературы
- •Содержание
{
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