Ленинградский государственный
электротехнический университет «ЛЭТИ» им. Ленина
Микроконтроллер ARM LPC2148 - первые шаги.
Методические указания
для выполнения лабораторных работ
по дисциплине “Микропроцессорные системы”
Читайте:
Оглавление.
Введение.
Данные методические указания предназначены для проведения курса лабораторных работ по дисциплине “Микропроцессорные системы на тему “Изучение внутренних периферийных устройств микроконтроллеров, построенных на базе ARM-ядра”.
Для проведения курса лабораторных работ необходимо обеспечить полный состав рабочего места. Он в себя включает:
Персональный компьютер с установленным инструментальным комплексом Keil uVision 3 и драйверами для J-Link.
Отладочная платформа Embedded Artists на основе микроконтроллера Philips LPC2148 (с сентября 2006 г. - NXP LPC2148).
Кабель питания, подключаемый к USB порту компьютера.
COM кабель, подключаемый к COM порту компьютера.
J-Link, соединяемый с отладочной платой 20-контактным проводом и с компьютером через USB кабель.
Схема подключения отладочной платы к компьютеру представлена на рисунке 0.1. Основные элементы отладочной платы приведены на рисунке 0.2. Внешний вид отладочной платы приведен на рисунке 0.3.
Рис. 0.1. Схема подключения отладочной платы к компьютеру.
Рис. 0.2. Основные элементы отладочной платы.
Рис. 0.3. Внешний вид отладочной платы.
Установка и настройка программного обеспечения на рабочем месте:
Установить среду разработки Keil uVision 3 (дистрибутив находися в папке Keil_uVision). Процесс установки прост и интуитивно понятен. Keil uVision является бесплатной программой для проектов, конечный исполняемый код которых менее 16 Кб. Однако, для работы с отладчиком необходима регистрация данного программного продукта. Регистрация производится введением правильного ключа в меню File->License Management. Правильный ключ может быть получен при помощи прграммы Keil_lic_v3.exe, находящейся в папке с дистрибутивом Keil.
Установить RDI драйверы для отладчика J-LINK из папки RDI_Driver. В процессе работы при появлении окна, представленного на рисунке 0.4. ввести корректный ключ для драйвера RDI. Эта операция должна быть сделана для каждого из устройств J-LINK, подключаемых к данному компьютеру, т.к. ключ основан на его серийном номере. Корректный ключ может быть получен при помощи программы keygen.exe, находящейся в папке с дистрибутивом драйвера.
Рис. 0.4. Окно запроса корректного ключа.
Правила настройки проекта приведены в практическом занятии N1.
Практическое занятие №1. Изучение среды разработки Keil uVision.
Среда разработки Keil uVision включает в себя менеджер проектов, редактор исходных кодов, компилятор, средства отладки и утилиты для полной симуляции микроконтроллера.
Цели работы:
Ознакомиться с пользовательским интерфейсом среды разработки.
Научиться создавать новый проект и редактировать его настройки.
Научиться вносить изменения в стартовый код.
Запустить простое приложение на отладочной плате.
Порядок выполнения работы:
Запустить Keil.
Ознакомиться с элементами управления. Среда разработки Keil представляет собой типовое приложение Windows. Ее вид c основными элементами управления изображен на рисунке 1.1.
Рис.1.1. Пользовательский интерфейс среды Keil uVision.
Создать новый проект (см. рис. 1.2).
Рис 1.2. Создание нового проекта.
Сохранить проект на диске. Выбрать требуемый тип микроконтроллера (см. рис. 1.3). Vendor: Philips, Device: LPC2148. Ознакомиться со списком периферийных устройств.
Рис. 1.3. Выбор типа микроконтроллера.
Открыть вкладку просмотра содержимого проекта (рис. 1.4) и выбрать startup.s.
Рис 1.4.
Выбрать вкладку “Configuration Wizard” и ознакомиться со списком настроек, которые можно редактировать при помощи среды Keil (рис. 1.5).
Рис. 1.5. Мастер настройки стартового кода.
Выполнить настройку проекта:
Выбрать Project -> Options for target `…'.
Во вкладке “Utilities” выбрать “Use: RDI Interface Driver” и выбрать “Run to main()”. Нажать “Settings” (рис. 1.6).
Рис. 1.6. Настройка проекта.
Выбрать путь к драйверам JTAG (рис. 1.7.):
C:\Program Files\Segger\JLinkARM_V324e\JLinkRDI.dll
Рис. 1.7. Выбор драйвера JTAG.
Нажать кнопку “Configure RDI Driver” (рис. 17). Выбрать вкладку Flash и указать настройки, отмеченные на рисунке 1.8: “Enable flash programming”, “Cache flash contents”, “Allow flash download”.
Рис. 1.8. Настройки RDI драйвера.
Сохранить настройки - OK - OK.
При отсутствии аппаратной платформы можно использовать симулятор микроконтроллера. Для этого в настройках проекта можно выбрать “Use simulator” во вкладке “Debug”.
Создать новый файл (File -> New …) и сохранить его в текущей папке под названием main.c. Добавить этот файл в проект (двойное нажатие на “Source Group 1”) - см. рис. 1.9. Написать текст программы и сохранить файл (см. Листинг 1.1).
Рис. 1.9. Добавление кода в проект.
|
main.c |
Листинг 1.1. |
01 02 03 04 05 06 07 08 09
|
#include <lpc214x.h>
int main (void) { IODIR0 = 0xFF << 8; IOSET0 = 0xAA << 8; while (1); return 0; } |
Скомпилировать программу. Для этого нажать F7. В случае наличия ошибок, их список будет отображен в окне “Output”.
Запустить программу для отладки (Ctrl+F5). Освоить использование стандартных функций отладчика (Step In, Step Out, Step Over, Run, Stop) - см. рис. 1.10.
Запустить программу на выполнение и наблюдать результаты работы программы на отладочной плате.
Рис. 1.10. Отладка программы.
Практическое занятие №2. Порты ввода/вывода общего назначения.
1. Общие сведения.
Порты ввода/вывода общего назначения (General Purpose Input Output - GPIO) предназначены для обмена данными, либо для управления внешними устройствами. Каждый из портов может быть настроен как на передачу, так и на прием информации. По наличию сигнала (или фронта сигнала) на некоторых портах можно установить прерывание.
Порты ввода/вывода микроконтроллера NXP LPC2148 могут быть подключены к шине периферийных устройств или к локальной шине. Во втором случае частота переключения портов может быть заметно увеличена.
На отладочной плате порты ввода/вывода выполняют несколько функций:
Управление светодиодами.
Управление символьным дисплеем.
Разрешение работы двигателя.
Управление регистрами, соединенными со светодиодной матрицей.
Рассмотрим применение портов ввода/вывода с целью управления светодиодами.
Схема подключения светодиодов на отладочной плате приведена на рисунке 2.1. Чтобы зажечь светодиод, необходимо сконфигурировать соответствующий порт на выход и подать на него нулевой уровень сигнала.
Из схемы видно, что светодиоды подключены к выводам 8-15 порта 0.
Рис. 2.1. Схема подключения светодиодов.
2. Краткое описание регистров GPIO / FIO.
IOPINx FIOxPIN |
Регистр, из которого можно получить информацию о текущем состоянии портов ввода/вывода, независимо от направления ввода/вывода и назначения пинов. Нулевой бит соответствует порту Px.0 …. 31й - Px.31. Используется только для чтения. |
IOSETx FIOxSET |
Регистр вывода. Этот регистр контролирует состояние вывода пинов совместно с регистром IOCLR. Запись 1 дает высокий уровень на соответствующем пине. Запись 0 не имеет эффекта. Нулевой бит соответствует порту Px.0 …. 31й - Px.31. Используется для записи и чтения. |
IODIRx FIOxDIR |
Управляющий регистр портов ввода/вывода. Этот регистр указывает направление ввода/вывода. Нулевой бит соответствует порту Px.0 …. 31й - Px.31. Используется для записи и чтения. |
IOCLRx FIOxCLR |
Очищающий регистр вывода. Этот регистр контролирует состояние вывода пинов. Запись 1 дает низкий уровень на выходе и очищает соответствующий бит в регистре IOхSET. Запись 0 не имеет эффекта. Нулевой бит соответствует порту Px.0 …. 31й - Px.31. Используется только для записи. |
3. Цели работы.
Ознакомиться с методами работы с портами общего назначения (GPIO).
Ознакомиться с методами работы с быстрыми портами (FIO).
4. Порядок выполнения работы.
Запустить проект 01_GPIO.
Понять логику и последовательность работы программы.
Запустить программу на отладочной плате. Сравнить скорости работы обычных и быстрых портов ввода/вывода (результаты отображены на LCD экране - количество переключений портов ввода/вывода за 0.1 сек.).
5. Комментарии к программе.
Логическая последовательность программы приведена в листинге 2.1.
|
main.c |
Листинг 2.1. |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
int main (void) { int GPIO, FIO; unsigned char result1 [30]; unsigned char result2 [30];
/***************************************************/ /* Write Hands On number to LCD */ /***************************************************/
InitLCD (); SetBacklight (1); LCDTextOut (" Hands On 2 ", " GPIO/FIO ");
/***************************************************/ /* Hands On code */ /***************************************************/
GPIO = GPIOPerformanceCheck (); sprintf (result1, "GPIO %d ticks", GPIO); FIO = FIOPerformanceCheck (); sprintf (result2, "FIO %d ticks", FIO); LCDTextOut (result1, result2);
while (1);
return 0; }
|
Строчки 11-13 предназначены для вывода на символьный дисплей номера и названия практической работы. Аналогичные строки будут встречаться во всех последующих практических занятиях и дополнительно комментироваться не будут.
В строках 19 и 21 производится измерение производительности портов ввода/вывода, подключенных к периферийной шине и к локальной шине (подробнее см. листинги 2.2 и 2.3). Строка 23 выводит результаты на символьный дисплей.
|
gpio.c |
Листинг 2.2. |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
int GPIOPerformanceCheck (void) { int count = 0; int prev_SCS = SCS;
SCS = 0x00; // Use GPIO (instead of FIO) IODIR0 |= 0x0000FF00; // Set P0.8 - P0.15 as outputs IOSET0 |= 0x0000FF00; // Clear P0.8 - P0.15
InitTimer0 (); // Start timer
while (!TimerIsUp) { IOSET0 |= (1 << 12); // Pull up P0.12 while (!(IOPIN0 & (1 << 12))); // Wait until P0.12 is up IOCLR0 |= (1 << 12); // Pull down P0.12 while (IOPIN0 & (1 << 12)); // Wait until P0.12 is down count ++; }
SCS = prev_SCS; // Restore previous SCS state
return count; } |
|
|
|
|
gpio.c |
Листинг 2.3. |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
int FIOPerformanceCheck (void) { int count = 0; int prev_SCS = SCS;
SCS = 0x01; // Use FIO (instead of GPIO) FIO0DIR |= 0x0000FF00; // Set P0.8 - P0.15 as outputs FIO0SET |= 0x0000FF00; // Clear P0.8 - P0.15
InitTimer0 (); // Start timer
while (!TimerIsUp) { FIO0SET |= (1 << 11); while (!(FIO0PIN & (1 << 11))); // Wait until P0.11 is up FIO0CLR |= (1 << 11); while (FIO0PIN & (1 << 11)); // Wait until P0.11 is down count ++; }
SCS = prev_SCS; // Restore previous SCS state
return count; } |
Функции измерения производительности переключения портов ввода/вывода запускают таймер и за время его работы переключают состояния портов из 1 в 0 и из 0 в 1 последовательно.
В строке 6 обеих функций происходит установка регистра System Control Status, чтобы подключить порты ввода/вывода либо к периферийной, либо к локальной шине.
Строки 7 и 8 настраивают выводы 8-15 порта 0 на выход и устанавливают их в начальное единичное состояние.
Строки 14 и 16 подают на один из выводов сигнал логической 1 или логического 0 соответственно. В строках 15 и 17 осуществляется ожидание переключения.
Работа с таймером, его инициализация и вызов прерывания являются предметом следующего практического занятия.
6. Литература.
1. LPC2148 User Manual. Часть 8.
Практическое занятие №3. Исследование контроллера прерываний.
1. Общие сведения.
В системе ARM доступны 32 линии прерываний. Прерывания программно назначаются тремя категориями:
Быстрое прерывание (FIQ) для быстрой обработки прерывания.
Векторное прерывание (vectored IRQ) для общих прерываний.
Безвекторное прерывание (non-vectored IRQ.)
Быстрое прерывание может срабатывать всего за 12 машинных циклов (200 нс при 60 МГц) в отличие от обычного векторного прерывания, которое срабатывает за 25 циклов (416 нс при 60 МГц). Это достигается за счет того, что обработчик FIQ располагается сразу после таблицы векторов прерываний, поэтому нет необходимости делать лишние переходы.
Существует 16 векторных прерываний. Эти прерывания могут произвести только IRQ прерывание. Векторные и невекторные IRQ прерывания вызывают обработчик прерывания (ISR). Чтение из векторного регистра адреса прерывания VICVectAddr дает адрес ISR, и обновляет настройки контроллера, который маскирует любые запросы на прерывание, имеющие такой же или более низкий приоритет. Запись в регистр VICVectAddr указывает контроллеру, что текущее прерывание обслужено, что позволяет прерываниям с более низким приоритетом активизироваться.
Прерывание FIQ имеет самый высокий приоритет. Невекторные IRQ прерывания имеют самый низкий приоритет.
Обобщенная структура контроллера прерываний приведена на рисунке 3.1.
Рис 3.1. Структура векторного контроллера прерываний.
2. Краткое описание регистров контролера прерываний.
Название |
Описание |
Доступ |
VICIRQStatus |
Показывает состояние запросов прерываний, которые активизированы и классифицированы как IRQ. Высокий бит указывает, на то, что прерывание активно, и производится передача прерывания процессору. |
RO |
VICFIQStatus |
Показывает состояние запросов прерываний, которые активизированы и классифицированы как FIQ. Высокий бит указывает, на то, что прерывание активно, и производится передача прерывания процессору. |
RO |
VICRawIntr |
Показывает состояние 32 линий запроса прерываний (в том числе и программных), независимо от активации и классификации прерывания. Высокий бит указывает, на то, что прерывание активно, и производится передача прерывания процессору |
RO |
VICIntSelect |
Указывает контроллеру прерываний, какой тип прерывания (FIQ или IRQ) запрашивает источник прерывания. 1 = FIQ прерывание 0 = IRQ прерывание. |
R/W |
VICIntEnable |
Включает линии запроса прерываний, маскируя источники прерываний для прерываний IRQ 1 = Прерывание разрешено. 0 = Прерывание запрещено. Запись 1 в соответствующий бит разрешает прерывание. Запись 0 не имеет никакого эффекта.(см. VICIntEnClr ) |
R/W |
VICIntEnClr |
Очищает биты в регистре VICIntEnable. Запись 1 в соответствующий бит очищает соответствующий бит в регистре VICIntEnable. Запись 0 не имеет никакого эффекта |
W |
VICSoftInt |
Используется для того, чтобы произвести программное прерывание Установка бита в 1 генерирует программное прерывание для установленного источника прерывания, до маскирования. Высокий бит устанавливает соответствующий бит в регистре VICIntEnable. Низкий бит не имеет никакого эффекта. |
R/W |
VICSoftIntClear |
Очищает биты в регистре VICSoftInt. Высокий бит очищает соответствующий бит в регистре VICSoftInt. Низкий бит не имеет никакого эффекта |
W |
VICProtection |
Позволяет или запрещает защищенный доступ к регистрам. Когда он включен, возможны только привилегированные способы доступа (чтение и запись) регистров контроллера прерываний. Когда выключен, возможны привилегированные и пользовательские способы доступа (чтение и запись) к регистрам контроллера прерываний. |
R/W |
VICVectAddr |
Содержит адрес обработчика (ISR) активного прерывания. Любые записи в регистр очищают прерывание. |
R/W |
VICDefVectAddr |
Содержит адрес ISR для безвекторных IRQ прерываний. |
R/W |
VICVectAddr0-15 |
Cодержит адреса вектора ISR. для i-го прерывания. |
R/W |
VICVectCntl0-15 |
Выбирают источник прерывания для i-го векторного прерывания 0-4: Выбор источника прерываний. Можно выбрать любой из 32 источников прерываний 5: разрешает векторные прерывание |
R/W |
3. Цели работы.
Ознакомиться с понятием векторного прерывания.
Ознакомиться с контроллером векторных прерываний.
4. Порядок выполнения работы.
Запустить проект 01_GPIO.
Исследовать логику и последовательность работы части программы, относящуюся к работе с прерыванием по таймеру.
Скомпилировать проект и запустить программу на отладочной плате.
5. Комментарии к коду программы.
Код, отвечающий за инициализацию контроллера прерываний и таймера приведен в листинге 3.1.
|
gpio.c |
Листинг 3.1. |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
int TimerIsUp = 0;
__irq void Timer0ISR (void) //Timer0 ISR { TimerIsUp = 1; //set Flag T0IR = 0x01; //reset interrupt flag VICVectAddr = 0; //reset VIC return; }
void InitTimer0 (void) { /***************************************************/ /* Init VIC */ /***************************************************/ VICDefVectAddr = (unsigned int) &Timer0ISR; VICIntEnable = 0x10; // Channel#4 is the Timer0 VICIntSelect = 0x00; // all interrupts are IRQs
/***************************************************/ /* Init Timer0 */ /***************************************************/ T0MR0 = 1500000; // Timer match (~ 0.1 second) T0MCR = 0x03; // Interrupt on Match0, reset timer on match T0PC = 0x01; // Prescaler to 2 T0TC = 0x00; // reset Timer counter T0TCR = 0x01; // enable Timer
/***************************************************/ /* Set flag to zero */ /***************************************************/ TimerIsUp = 0;
return; } |
|
|
|
В строке 1 задается флаг, который примет значение 1 в момент срабатывания таймера. Любая функция может отслеживать состояние этого флага. Это стандартный прием для обработки прерывания, т.к. сам обработчик не должен выполнять каких-либо действий, а только сигнализировать о наличии прерывания.
В данном случае обработчик прерывания - это функция Timer0ISR(). Она вызывается в момент возникновения прерывания, выставляет флаг наличия прерывания для других функций (строка 5), сбрасывает флаг прерывания таймера (строка 6) и сбрасывает контроллер прерываний (строка 7). Строка 6 и 7 нужны для того, чтобы обработчик прерываний вызвался единожды при появлении запроса на прерывание.
Рассмотрим функцию инициализации таймера и установки обработчика прерывания.
В строке 16 задается адрес функции, которая является обработчиком прерывания по 4-ому каналу (строка 17). В строке 18 указывается, что все прерывания являются обычными, а не быстрыми.
Строки 23-27 настраивают таймер на срабатывание через 0.1 секунду после запуска (строка 23), вызов прерывания и сброс таймера в 0 (строка 24) и запуск таймера (строка 27). Подробнее работа таймера будет рассмотрена в работе, посвященной модулю широтно-импульсной модуляции.
Пример работы с таким источником прерывания приведен в листинге 3.2.
|
gpio.c |
Листинг 3.1. |
01 02 03 04 05 06
|
InitTimer0 (); // Start timer
while (!TimerIsUp) { // Waiting for timer }
|
|
|
|
Вместо строки 5 могут выполняться любые действия при ожидании срабатывания таймера.
6. Литература.
LPC2148 User Manual (часть 5).
Практическое занятие №4. Модуль ШИМ (PWM).
1. Общие сведения.
Широтно-импульсный модулятор (ШИМ) - это модуль, по сути похожий на таймер общего назначения, но с дополнительной возможностью периодически генерировать импульсы определенной длины. При помощи ШИМ можно, например, управлять яркостью светодиода, подавая на его вход питание в определенные моменты времени. В данной работе модуль ШИМ управляет яркостью трех разноцветных светодиодов, создавая при этом свечение определенного цвета, а также скоростью вращения электродвигателя.
Схема работы модуля ШИМ приведена на рисунке 4.1. Временные диаграммы приведены на рисунке 4.2.
Рис. 4.1. Схема работы модуля ШИМ.
Рис. 4.2. Временные диаграммы работы модуля ШИМ.
Схема подключения цветных светодиодов приведена на рисунке 4.3. Как видно, они подключены к выводам 7-9 порта 0, соединенным с модулем ШИМ внутри микроконтроллера.
Рис. 4.3. Схема подключения цветных светодиодов.
Схема подключения двигателя приведена на рисунке 4.4. При этом P0.10 - это сигнал включения двигателя, а P0.8 и P0.9 - сигналы вращения двигателя в разные стороны, подключенные к модулю ШИМ.
Рис. 4.4. Схема подключения двигателя.
2. Описание регистров модуля ШИМ.
PWM_TC
Описание |
Доступ |
Сброшенное значение |
Адрес |
PWM счетчик-хронометр. 32 битный контроллер передачи данных (TC) увеличивается с каждым PR+1 циклом клоков. TC управляется через TCR. |
RW |
0 |
0 |
32 битный PWM счетчик-хронометр увеличивается, когда масштабируемый счётчик достигает своего конечного отсчета. Пока он не сброситься при достижении верхнего предела, PWMTC будет считать в прямом направлении величины 0
FFFFFFFF, а затем автоматически перейдет обратно к величине 0
00000000. Это событие не вызывает прерывания, а регистр совпадения может быть использован для определения переполнения, когда это необходимо.
PWM_TCR
Описание |
Доступ |
Сброшенное значение |
Адрес |
PWM временной регистр управления. TCR используется для управления функциями счетчика-хронометра. С помощью TCR счетчик-хронометр может быть заблокирован или установлен в состояние ''0''. |
R/W |
0 |
0 |
PWM временной регистр управления (PWMTCR) используется для управления действиями PWM регистра-хронометра. Функция каждого из бит указана в таблице:
PWMTCR |
Функции |
Описание |
Сброшенное значение |
0 |
Разрешение |
Когда 1, и PWM регистру-хронометру, и PWM масштабируемому счётчику разрешен отсчет. Когда 0, счетчики заблокированы. |
0 |
1 |
Сброс |
Когда 1, PWM регистр-хронометр, и PWM масштабируемый счётчик синхронно сбрасываются в следующий положительный фронт. Счетчики остаются сброшенными пока TCR[1] не возвратиться в ''0''. |
0 |
2 |
Зарезервировано |
Программные средства пользователя не должны записывать единицы в резервированные биты. |
NA |
3 |
PWM разрешение |
Когда 1, режим PWM разрешен. Режим PWM заставляет теневой регистр работать вместе с регистром совпадения. Программа не позволяет регистру совпадения действовать, до тех пор, пока не будет установлен соответствующий бит в PWMLER. Заметим, что PWM регистр совпадения, который определяет скорость PWM, должен быть настроен до того, как режим PWM будет разрешен. |
0 |
PWM_PR
Описание |
Доступ |
Сброшенное значение |
Адрес |
PWM масштабируемый регистр. TC увеличивается с каждым PR+1 циклом клоков. |
R/W |
0 |
0 |
32 битный PWM масштабируемый регистр указывает максимальное значение для PWM масштабируемого счетчика.
PWM_PC
Описание |
Доступ |
Сброшенное значение |
Адрес |
PWM масштабируемый счетчик. 32 битный счетчик команд (PC) - счетчик, который увеличивается до значения, хранимого в PR. |
R/W |
0 |
0 |
32 битный PWM масштабируемый счетчик управляет делением клоков, с помощью некоторого постоянного значения, до того как оно будет использовано в PWM счетчике-хронометре. Это позволяет управлять связью разрешения таймера и максимального времени, до того как таймер переполниться. PWM масштабируемый счетчик увеличивается с каждым клоком. Когда он достигает значения, хранимого в PWM масштабируемом регистре, PWM счетчик-хронограф увеличивается и PWM масштабируемый счетчик сбрасывается в следующий клок. Это позволяет PWM TC увеличиваться на каждый клок, когда PWMPR=0, на 2 клока, когда PWMPR=1 и т.д.
PWM_PCR
Описание |
Доступ |
Сброшенное значение |
Адрес |
PWM регистр управления. Разрешает PWM выходные данные и выбирает PWM канальные типы или как единичный контролируемый фронт, или как двойной контролируемый фронт. |
R/W |
0 |
0
|
PWM регистр управления используется для разрешения и выбора каждого PWM канала. Функция каждой из бит, указана в таблице:
PWMPCR |
Функции |
Описание |
Сброшенное значение |
1:0 |
Зарезервировано |
Программные средства пользователя не должны записывать единицы в резервированные биты. Значения, прочитанные из резервированных бит, не определены |
NA |
2 |
PWMSEL2 |
При нуле, выбирается единичный фронт, управляемый режимом для PWM2. При 1, выбирается двойной фронт, управляемый режимом для PWM2 выходных данных . |
0 |
3 |
PWMSEL3 |
При нуле, выбирается единичный фронт, управляемый режимом для PWM3. При 1, выбирается двойной фронт, управляемый режимом для PWM3 выходных данных . |
0 |
4 |
PWMSEL4 |
При нуле, выбирается единичный фронт, управляемый режимом для PWM4. При 1, выбирается двойной фронт, управляемый режимом для PWM4 выходных данных . |
0 |
5 |
PWMSEL5 |
При нуле, выбирается единичный фронт, управляемый режимом для PWM5. При 1, выбирается двойной фронт, управляемый режимом для PWM5 выходных данных . |
0 |
6 |
PWMSEL6 |
При нуле, выбирается единичный фронт, управляемый режимом для PWM6. При 1, выбирается двойной фронт, управляемый режимом для PWM6 выходных данных . |
0 |
8:7 |
Зарезервировано |
Программные средства пользователя не должны записывать единицы в резервированные биты. Значения, прочитанные из резервированных бит, не определены |
NA |
9 |
PWMENA1 |
При 1, разрешаются PWM1 выходные данные. При 0, блокируются PWM1 выходные данные. |
0 |
10 |
PWMENA2 |
При 1, разрешаются PWM2 выходные данные. При 0, блокируются PWM2 выходные данные. |
0 |
11 |
PWMENA3 |
При 1, разрешаются PWM3 выходные данные. При 0, блокируются PWM3 выходные данные. |
0 |
12 |
PWMENA4 |
При 1, разрешаются PWM4 выходные данные. При 0, блокируются PWM4 выходные данные. |
0 |
13 |
PWMENA5 |
При 1, разрешаются PWM5 выходные данные. При 0, блокируются PWM5 выходные данные. |
0 |
14 |
PWMENA6 |
При 1, разрешаются PWM6 выходные данные. При 0, блокируются PWM6 выходные данные. |
0 |
15 |
Зарезервировано |
Программные средства пользователя не должны записывать единицы в резервированные биты. Значения, прочитанные из резервированных бит, не определены |
NA |
PWM_MCR
Описание |
Доступ |
Сброшенное значение |
Адрес |
PWM регистр управления совпадения. MCR используется для управления, когда происходит совпадение при генерации прерываний и установке TC в ''0''. |
R/W |
0 |
0 |
PWM регистр управления совпадения используется для контролирования того, что действия происходят тогда, когда один из PWM регистров совпадения совпадает со счетчиком-хронометром. Функции, каждой из бит, указаны в таблице:
PWMMCR |
Функции |
Описание |
Сброшенное значение |
0 |
Прерывание в PWMMCR0 |
При 1, прерывание генерируется, когда PWMMR0 приводит в соответствие значение в PWMTC. При 0, прерывания заблокированы. |
0 |
1 |
Сброс в PWMMCR0 |
При 1, PWMTC сброситься, если PWMMCR0 приведет его в соответствие. При 0, сброс заблокируется. |
0 |
2 |
Остановка в PWMMCR0 |
При 1, PWMTC и PWMPC будут остановлены и PWMTCR[0] ,будет установлен в 0, если PWMRR0 приведет в соответствие PWMTC. При 0, это действие заблокируется. |
0 |
3 |
Прерывание в PWMMCR1 |
При 1, прерывание генерируется, когда PWMMR1 приводит в соответствие значение в PWMTC. При 0, прерывания заблокированы. |
0 |
4 |
Сброс в PWMMCR1 |
При 1, PWMTC сброситься, если PWMMCR1 приведет его в соответствие. При 0, сброс заблокируется. |
0 |
5 |
Остановка в PWMMCR1 |
При 1, PWMTC и PWMPC будут остановлены и PWMTCR[0] ,будет установлен в 0, если PWMRR0 приведет в соответствие PWMTC. При 0, это действие заблокируется. |
0 |
6 |
Прерывание в PWMMCR2 |
При 1, прерывание генерируется, когда PWMMR2 приводит в соответствие значение в PWMTC. При 0, прерывания заблокированы. |
0 |
7 |
Сброс в PWMMCR2 |
При 1, PWMTC сброситься, если PWMMCR1 приведет его в соответствие. При 0, сброс заблокируется. |
0 |
8 |
Остановка в PWMMCR2 |
При 1, PWMTC и PWMPC будут остановлены и PWMTCR[0] ,будет установлен в 0, если PWMRR0 приведет в соответствие PWMTC. При 0, это действие заблокируется. |
0 |
9 |
Прерывание в PWMMCR3 |
При 1, прерывание генерируется, когда PWMMR3 приводит в соответствие значение в PWMTC. При 0, прерывания заблокированы. |
0 |
10 |
Сброс в PWMMCR3 |
При 1, PWMTC сброситься, если PWMMCR1 приведет его в соответствие. При 0, сброс заблокируется. |
0 |
11 |
Остановка в PWMMCR3 |
При 1, PWMTC и PWMPC будут остановлены и PWMTCR[0] ,будет установлен в 0, если PWMRR0 приведет в соответствие PWMTC. При 0, это действие заблокируется. |
0 |
12 |
Прерывание в PWMMCR4 |
При 1, прерывание генерируется, когда PWMMR4 приводит в соответствие значение в PWMTC. При 0, прерывания заблокированы. |
0 |
13 |
Сброс в PWMMCR4 |
При 1, PWMTC сброситься, если PWMMCR1 приведет его в соответствие. При 0, сброс заблокируется. |
0 |
14 |
Остановка в PWMMCR4 |
При 1, PWMTC и PWMPC будут остановлены и PWMTCR[0] ,будет установлен в 0, если PWMRR0 приведет в соответствие PWMTC. При 0, это действие заблокируется. |
0 |
15 |
Прерывание в PWMMCR5 |
При 1, прерывание генерируется, когда PWMMR5 приводит в соответствие значение в PWMTC. При 0, прерывания заблокированы. |
0 |
16 |
Сброс в PWMMCR5 |
При 1, PWMTC сброситься, если PWMMCR1 приведет его в соответствие. При 0, сброс заблокируется. |
0 |
17 |
Остановка в PWMMCR5 |
При 1, PWMTC и PWMPC будут остановлены и PWMTCR[0] ,будет установлен в 0, если PWMRR0 приведет в соответствие PWMTC. При 0, это действие заблокируется. |
0 |
18 |
Прерывание в PWMMCR6 |
При 1, прерывание генерируется, когда PWMMR6 приводит в соответствие значение в PWMTC. При 0, прерывания заблокированы. |
0 |
19 |
Сброс в PWMMCR6 |
При 1, PWMTC сброситься, если PWMMCR1 приведет его в соответствие. При 0, сброс заблокируется. |
0 |
20 |
Остановка в PWMMCR5 |
При 1, PWMTC и PWMPC будут остановлены и PWMTCR[0] ,будет установлен в 0, если PWMRR0 приведет в соответствие PWMTC. При 0, это действие заблокируется. |
0 |
PWM_LER
Описание |
Доступ |
Сброшенное значение |
Адрес |
PWM регистр-защелка. Разрешает использование новых PWM совпавших значений |
R/W |
0 |
0 |
PWM разрешающий регистр-защелка используется для контролирования обновления PWM регистров совпадений, когда они используются для создания PWM.
Функции, каждой из бит в PWMLER , указаны в таблице:
PWMLER |
Функции |
Описание |
Сброшенное значение |
0 |
Разрешение PWM Совпадение 0 регистра |
Запись 1 для этого бита позволяет последнему значению, записанному в PWM 0 регистре совпадения, становиться действующим, когда таймер сбрасывается с помощью PWM события совпадения. |
0 |
1 |
Разрешение PWM Совпадение 1 регистра |
Запись 1 для этого бита позволяет последнему значению, записанному в PWM 1 регистре совпадения, становиться действующим, когда таймер сбрасывается с помощью PWM события совпадения. |
0 |
2 |
Разрешение PWM Совпадение 2 регистра |
Запись 1 для этого бита позволяет последнему значению, записанному в PWM 2 регистре совпадения, становиться действующим, когда таймер сбрасывается с помощью PWM события совпадения. |
0 |
3 |
Разрешение PWM Совпадение 3 регистра |
Запись 1 для этого бита позволяет последнему значению, записанному в PWM 3 регистре совпадения, становиться действующим, когда таймер сбрасывается с помощью PWM события совпадения. |
0 |
4 |
Разрешение PWM Совпадение 4 регистра |
Запись 1 для этого бита позволяет последнему значению, записанному в PWM 4 регистре совпадения, становиться действующим, когда таймер сбрасывается с помощью PWM события совпадения. |
0 |
5 |
Разрешение PWM Совпадение 5 регистра |
Запись 1 для этого бита позволяет последнему значению, записанному в PWM 5 регистре совпадения, становиться действующим, когда таймер сбрасывается с помощью PWM события совпадения. |
0 |
6 |
Разрешение PWM Совпадение 6 регистра |
Запись 1 для этого бита позволяет последнему значению, записанному в PWM 6 регистре совпадения, становиться действующим, когда таймер сбрасывается с помощью PWM события совпадения. |
0 |
7 |
Зарезервирование |
Программные средства пользователя не должны записывать единицы в резервированные биты. Значения, прочитанные из зарезервированных бит, не определены. |
NA |
PWM_MR0
Описание |
Доступ |
Сброшенное значение |
Адрес |
PWM 0 регистр совпадения. MR0 может быть разблокирован через MCR, чтобы сбросить TC, остановить TC, PC и/или генерировать прерывание, когда оно соответствует TC. При условии совпадения MR0 и TC, устанавливаются все PWM выходные данные в режиме единичного фронта или PWM1 в режиме двойного фронта |
R/W |
0 |
0 |
PWM_MR4
Описание |
Доступ |
Сброшенное значение |
Адрес |
PWM 4 регистр совпадения. MR4 может быть разблокирован через MCR, чтобы сбросить TC, остановить TC, PC и/или генерировать прерывание, когда оно соответствует TC. При условии совпадения MR4 и TC, очищает PWM4 или в режиме единичного фронта, или в режиме двойного фронта и устанавливает PWM5 в режиме двойного фронта |
R/W |
0 |
0 |
PWM_MR6
Описание |
Доступ |
Сброшенное значение |
Адрес |
PWM 6 регистр совпадения. MR6 может быть разблокирован через MCR, чтобы сбросить TC, остановить TC, PC и/или генерировать прерывание, когда оно соответствует TC. При условии совпадения MR6 и TC, очищает PWM6 в режиме единичного фронта, или в режиме двойного фронта. |
R/W |
0 |
0 |
3. Цели работы.
Освоить методы работы с модулем широтно-импульсной модуляции.
4. Порядок выполнения работы.
Запустить проект 02_PWM.
Проверить работу программы на отладочной плате.
Понять логику работы программы и настройку модуля ШИМ.
5. Комментарии к программе.
Программа выполняется в виде трех последовательных циклов изменения яркости цветных светодиодов и трех последовательных циклов изменения скорости и направления вращения двигателя.
Код, отвечающий за настройку и работу с модулем ШИМ приведен в листинге 4.1.
|
pwm.c |
Листинг 4.1. |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
void InitPWM (void) { /**********************************************************/ /* Connect PIN connect block to PWM */ /**********************************************************/ PINSEL0 |= (2 << 14); // GPIO 0.7 to PWM2 PINSEL0 |= (2 << 16); // GPIO 0.8 to PWM4 PINSEL0 |= (2 << 18); // GPIO 0.9 to PWM6
/**********************************************************/ /* Set match registers */ /**********************************************************/ PWMMR0 = 0x00000FFF; // Relative signal length PWMMR2 = 0x00000000; // Default set to zero PWMMR4 = 0x00000000; // Default set to zero PWMMR6 = 0x00000000; // Default set to zero
/**********************************************************/ /* Reset PWM counter on match */ /**********************************************************/ PWMMCR = (1 << 1);
/**********************************************************/ /* Copy match registers from shadow memory */ /**********************************************************/ PWMLER = (1) | (1 << 2) | (1 << 4) | (1 << 6);
/**********************************************************/ /* Set PWM2,4,6 enabled */ /**********************************************************/ PWMPCR |= (1 << 10); // Set PWM2 enabled PWMPCR |= (1 << 12); // Set PWM4 enabled PWMPCR |= (1 << 14); // Set PWM6 enabled
/**********************************************************/ /* Enable counter and PWM */ /**********************************************************/ PWMTCR = (1) | (1 << 3); }
void SetRGB (int Red, int Green, int Blue) { /**********************************************************/ /* Fill mach registers with values */ /**********************************************************/ PWMMR2 = Red; PWMMR4 = Blue; PWMMR6 = Green;
/**********************************************************/ /* Copy match registers from shadow memory */ /**********************************************************/ PWMLER = (1) | (1 << 2) | (1 << 4) | (1 << 6); }
void SetMotorSpeed (int Speed) { IODIR0 |= (1 << 10); // Set P0.10 as output (Motor enable pin)
if (Speed == 0) { IOCLR0 = (1 << 10); // Disable motor if speed is equal to zero } else { IOSET0 = (1 << 10); // Enable, if speed is not equal to zero
if (Speed > 0) { PWMMR4 = Speed; // Run motor controlled by PWM4 } else { PWMMR6 = -Speed; // Run to another direction (PWM6) } }
PWMLER = (1) | (1 << 2) | (1 << 4) | (1 << 6); } |
Рассмотрим инициализацию модуля ШИМ (функция InitPWM). Строки 6-8 отключают выводы от GPIO и подключают их к модулю ШИМ. Строка 13 устанавливает период генерируемого сигнала, а строки 14-16 устанавливают значение регистра совпадения в 0, т.е. фактически блокируют сигнал с ШИМ. Другие функции, использующие ШИМ, будут настраивать эти регистры на необходимые значения.
Строка 21 указывает на то, что счетчик модуля ШИМ должен сбросится его при равенстве регистру совпадения.
Строка 26 необходима для возможности одновременного включения всех каналов ШИМ, когда это необходимо.
Строка 38 включает счетчик модуля ШИМ.
Далее рассмотрим функцию SetRGB(), устанавливающую заданную яркость для цветных светодиодов. Тут все аналогично функции инициализации за исключением записи в регистры совпадения ненулевых заданных значений. Так, если, например, PWMMR0 = 0xFFF (= 4095) и задать PWMMR2 = 0x200 (= 512), то питание на светодиод будет подаваться в (512/4095)*100% = 12,5 % времени. Соответственно, его яркость будет равна 12,5 % от максимальной.
Рассмотрим функцию управления вращением двигателя. Тут все аналогично. Добавляется лишь логика анализа, какой из каналов PWM необходимо подключить к двигателю, и включение/выключение двигателя путем управления P0.10.
6. Литература.
LPC2148 User Manual (часть 16).
Education Board user manual.
Практическое занятие №5. Аналогово-цифровой преобразователь.
1. Общие сведения.
В микроконтроллерах семейства LCP2xxx АЦП имеет разрядность 10 бит и работает по принципу последовательного приближения. АЦП может иметь от 4 до 8 независимых каналов, в зависимости от конкретной модели.
Схема подключения аналоговых входов приведена на рисунке 5.1.
Рис. 5.1. Схема подключения аналоговых входов.
2. Краткое описание регистров АЦП.
Регистр. |
Описание. |
ADхCR |
Управляющий регистр АЦП х. |
ADхGDR |
Содержит признак окончания преобразования. |
ADхSTAT |
Содержит информацию о текущем состоянии АЦП. |
ADхINTEN |
Содержит информацию о прерываниях по сигналам от АЦП. |
ADхDR0 … ADхDR7 |
Содержат результаты преобразования по каждому из каналов. |
Настройка АЦП (регистр ADxCR)
Разряды. |
Значение. |
7:0 |
Выбор рабочих каналов АЦП. |
15:8 |
Делитель шины периферийных устройств. |
16 |
При 1 преобразование повторяется самостоятельно, при 0 - по запросу. |
19:17 |
Определяет разрядность преобразования. 000 - 10 бит … 111 - 3 бита |
20 |
Зарезервировано. |
21 |
1 - включение питания. |
23:22 |
Зарезервировано. |
26:24 |
Определяет момент начала преобразования при 16 бите равном 0. |
27 |
1 - преобразование по возрастающему фронту управляющего сигнала, 0 - по убывающему. |
31:28 |
Зарезервировано. |
Считывание значения с АЦП (регистр ADxGDR).
Разряды. |
Значение. |
15:6 |
Преобразованное значение. |
26:24 |
Канал АЦП, с которого получено значение. |
30 |
1, если хотя бы одно преобразование не было считано и поэтому перезаписано. |
31 |
1, когда преобразование закончено. |
3. Цель работы.
Ознакомиться с методами работы с встроенным аналогово-цифровым преобразователем.
4. Порядок выполнения работы.
Запустить проект 03_ADC.
Запустить программу на плате и наблюдать результаты ее работы.
5. Комментарии к программе.
Код управляющей программы приведен в листинге 5.1. Программа считывает значение с АЦП и зажигает один из светодиодов соответственно уровню входного сигнала.
|
main.c |
Листинг 5.1. |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
int main (void) { /***************************************************/ /* Write Hands On number to LCD */ /***************************************************/
InitLCD (); SetBacklight (1); LCDTextOut (" Hands On 3 ", " ADC Converter ");
/***************************************************/ /* Hands On code */ /***************************************************/
InitADC (); // see "adc.c"
IODIR0 |= (0xFF) << 8; // Set LEDs as outputs (for indication)
while (1) { IOSET0 = (0xFF) << 8; // Clear leds
// ADC is 10-bit width // values are stored in 0..1023 range
// Fill leds with ADC value IOCLR0 = (1 << (ADCReadValue () >> 7)) << 8; Sleep (100); }
return 0; } |
|
|
|
В строке 15 инициализируется АЦП (см. листинг 5.2). Строка 17 устанавливает как выходы выводы, к которым подключены светодиоды.
В строке 27 происходит считывание значения из АЦП (см. листинг 5.2). Сдвиг вправо на 7 необходим для приведения диапазона 0…1023 к диапазону 0…7, т.к. на плате всего 7 светодиодов. Сдвиг 1 на полученное значение влево выбирает номер зажигаемого светодиода. Сдвиг результата влево на 8 переносит полученный бит в разряды, соответствующие P0.8 - P0.15 для зажигания светодиодов.
|
adc.c |
Листинг 5.2. |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
void InitADC (void) { /**********************************************************/ /* Connect PIN connect block to ADC0.1 */ /**********************************************************/ PINSEL1 |= (1 << 24);
/**********************************************************/ /* Configure ADC */ /**********************************************************/ ADCR = (1 << 1) | // Select ADC0.1 channel is active (4 << 8) | // Set Clock divider (1 << 16) | // Set BURST (0 << 17) | // Set ADC resolution (1 << 21) | // Power on ADC (1 << 24); // Start conversion now }
int ADCReadValue (void) { int ADCValue;
/**********************************************************/ /* Read value from ADC */ /**********************************************************/ while (((ADCValue = ADDR) & 0x80000000) == 0);
/**********************************************************/ /* Separate ADC value from other information */ /**********************************************************/ return (ADCValue >> 6) & (0x3FF); } |
|
|
|
Рассмотрим инициализацию АЦП (InitADC). Строка 6 подключает вход к АЦП. Строки 11-16 выбирают режим работы АЦП: активный канал 1, делитель частоты = 4, режим автоматического повтора преобразования, разрешение АЦП - 10 бит.
Функция ADCReadValue ожидает признака окончания преобразования (строка 26) и выдает преобразованное значение (строка 31). Сдвиг вправо на 6 необходим, чтобы перенести преобразованное значение в младшие биты из разрядов 15:6. Логическое умножение на 0x3FFF удаляет всю прочую информацию, т.к. в этом случае она не нужна.
6. Литература.
LPC2148 User Manual (часть 17).
Education Board user manual.
Education board schematics.
Практическое занятие №6. Интерфейс UART.
1. Общие сведения.
UART является модулем последовательной передачи данных с поддержкой аппаратного контроля и поддержкой модемных функций.
Особенности:
16 битная очередь приема-передачи.
Регистр размещения соответствует 550 промышленному стандарту.
Приемный FIFO триггер показывает 1, 4, 8,14 бит.
Встроенный контролер скорости передачи
Описание портов:
Название порта |
Тип |
Описание |
RxD0 |
Ввод |
Последовательный вывод (данных). Получаемые последовательно данные. |
TxD0 |
Вывод |
Последовательный вывод (данных). Передаваемые последовательно данные. |
2. Описание регистров UART.
Карта регистров представлена в таблице:
UART0_RBR
Описание |
Доступ |
Сброшенное значение |
Адрес |
Принимающий буферный регистр. |
RO |
неопределенное |
0 |
UORBR является высшим байтом UART0 Rx FIFO. Высший байт из Rx FIFO содержит “самый старый” полученный символ и может быть прочитан через интерфейс шины. LSB (бит 0) представляет “самый старый” полученный бит. Если полученный символ меньше 8 бит, то неиспользуемые MSB заполняются нулями.
UART0_DLL
Описание |
Доступ |
Сброшенное значение |
Адрес |
Делитель регистра-защелки LSB. |
R/W |
0 |
0 |
U0DLL |
Функции |
Описание |
Сброшенное значение |
7:0
|
Делитель регистра-защелки LSB. |
UARTO делитель регистра-защелки LSB вместе с U0DLM регистром определяет скорость двоичной передачи в UART0. |
0 |
UART0_DLM
Описание |
Доступ |
Сброшенное значение |
Адрес |
Делитель регистра-защелки MSB |
R/W |
0 |
0 |
UART0 делитель регистра-защелки является частью UART0 генератора-контроллера скорости передачи и хранит значения, используемые для разделения VPB клоков, для того чтобы произвести скорость двоичной передачи клоков, которая должна быть равна 16
желаемая скорость передачи. Регистры U0DLL и U0DLM образуют 16 битный разделитель, где U0DLL содержит нижние 8 бит, а U0DLM верхние 8 бит делителя.
U0DLM |
Функции |
Описание |
Сброшенное значение |
7:0
|
Делитель регистра-защелки MSB. |
UARTO делитель регистра-защелки MSB вместе с U0DLL регистром определяет скорость двоичной передачи в UARTO. |
0 |
UART0_FCR
Описание |
Доступ |
Сброшенное значение |
Адрес |
FIFO регистр управления |
R/W |
0 |
0 |
U0FCR управляет действиями UART0 Rх и Tх FIFO.
U0FCR |
Функции |
Описание |
Сброшенное значение |
0
|
FIFO Разблокирование. |
Разрешает действия UART0 R |
0 |
1 |
R Сброс |
Запись логической 1 в U0FCR1, сбросит все биты в UART0 R |
0 |
2
|
T Сброс |
Запись логической 1 в U0FCR2, сбросит все биты в UART0 T |
0 |
5:3 |
Резервирование |
Программные средства пользователя не должны записывать единицы в резервированные биты. Значения, прочитанные из резервированных бит, не определены |
NA |
7:6 |
R |
00: Уровень переключения 0 (0
01: Уровень переключения 1 (0
10: Уровень переключения 2 (0
11: Уровень переключения 3 (0 Эти две биты определяют, сколько символов должно быть записано до того, как произойдет прерывание. Четыре уровня переключения указанные пользователем при компиляции позволяют ему отрегулировать выбранную глубину FIFO. |
0 |
UART0_LCR
Описание |
Доступ |
Сброшенное значение |
Адрес |
Линейный регистр управления. |
R/W |
0 |
0 |
U0LCR определяет формат информации символов, которые передаются или получаются.
UOLCR |
Функции |
Описание |
Сброшенное значение |
1:0
|
Выбор длины слова |
00: длина 5 битового символа 01: длина 6 битового символа 10: длина 7 битового символа 11: длина 8 битового символа |
0 |
2 |
Выбор остановки биты |
0: остановка 1 биты 0: остановка 2 бит |
0 |
3 |
Разрешение по четности |
0: Блокировка генерирования и проверки четности 1: Разрешение генерирования и проверки четности |
0 |
5:4
|
Выбор четности |
00: Проверка на нечетность 01: Проверка на четность 10: Forced “1” stick parity 11: Forced “0” stick parity |
0 |
6 |
Управление прерыванием |
0: Блокировка прерывания перехода 1: Разрешение прерывания перехода |
0 |
7 |
Доступ делителя регистра-защелки |
0: Блокировка доступа к делителю регистра - защелки 1: Разрешение доступа к делителю регистра - защелки |
0 |
UART0_LSR
Описание |
Доступ |
Сброшенное значение |
Адрес |
Линейный регистр состояния устройства. |
R0 |
0 |
0 |
UOLSR - регистр только для чтения, который обеспечивает информацию о состоянии UART0 Rx и Tx блоков.
UOLSR |
Функции |
Описание |
Сброшенное значение |
0
|
Приемник готовых данных (RDR) |
0: U0RBR незанят 1: U0RBR содержит правильные данные |
0 |
1 |
Ошибка переполнения (OE) |
0: Состояние переполнения неактивно 1: Состояние переполнения активно |
0 |
2 |
Ошибка четности (PE) |
0: Состояние ошибки четности неактивно 1: Состояние ошибки четности активно |
0 |
3 |
Ошибка кодирования (FE) |
0: Состояние ошибки кодировки неактивно 1: Состояние ошибки кодировки активно |
0 |
4 |
Остановка прерывания (BI) |
0: Состояние остановки прерывания неактивно 1: Состояние остановки прерывания активно |
0 |
5 |
Преобразователь блокировки незанятого регистра (THRE) |
0: U0THR незанят 1: U0THR содержит правильные данные |
1 |
6 |
Преобразователь (TEMT) |
0: U0THR и/или U0TSR содержат правильные данные 1: U0THR и U0TSR незаняты |
1 |
7 |
Ошибка в R |
0: U0RBR не содержит UART0 R
1: UART0 RBR содержит по крайне мере одну UART0 R |
0 |
3. Цель работы.
Научиться работать с последовательным интерфейсом передачи данных UART.
4. Порядок выполнения работы.
Запустить проект 04_UART.
Понять логику и последовательность работы программы.
Запустить программу на отладочной плате, удалив перемычки J5 и J7 (см. документацию на отладочную плату).
Запустить программу HyperTerminal, настроить ее на режим работы 19200 8-N-1 без аппаратного контроля.
Для этого выбрать пункт меню “Файл - Свойства” (рис. 6.1). Выбрать порт, к которому подключена отладочная плата и нажать кнопку «Настроить…».
Рис. 6.1. Настройка Hyper Terminal.
Выбрать следующие параметры:
Скорость: 19200
Биты данных: 8
Четность: нет
Стоповые биты: 1
Управление потоком: Нет
Замечание: эти настройки установлены в функции инициализации UART. В случае их изменения в коде программы, необходимо произвести соответствующие изменения и в настройках Hyper Terminal.
Рис. 6.2. Настройка параметров COM порта.
Убедиться в работоспособности программы, нажимая клавиши на клавиатуре (см. рис. 6.3.).
Рис. 6.3. Пример работы программы.
5. Комментарии к программе.
Основная программа приведена в листинге 6.1.
|
main.c |
Листинг 6.1. |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
int main (void) { char ch; char text [128];
/***************************************************/ /* Write Hands On number to LCD */ /***************************************************/
InitLCD (); SetBacklight (1); LCDTextOut (" Hands On 4 ", " UART ");
/***************************************************/ /* Hands On code */ /***************************************************/
InitUART (19200); UARTTextOut ("\r\nUART is running at 19200\r\n------------\r\n"); UARTTextOut ("Press any key...\r\n\r\n");
while (1) { ch = UARTReadChar (); sprintf(text, "You have pressed: %c (Code = %d)\r\n", ch, ch); UARTTextOut (text); }
return 0; } |
|
|
|
В строке 18 UART инициализируется на работу на скорости 19200 бод/с (подробнее - см. листинг 6.2.).
Цикл в строках 22-27 читает переданные с терминала компьютера данные и возвращает код нажатой клавиши.
|
main.c |
Листинг 6.2. |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
void InitUART (int baud_rate) { /**********************************************************/ /* Connect PIN connect block to UART */ /**********************************************************/ PINSEL0 = 0x05;
/**********************************************************/ /* Activate and clear FIFOs */ /**********************************************************/ U0FCR = 0x07;
/**********************************************************/ /* Set 8N1 mode, allow access to divider-latches */ /**********************************************************/ U0LCR = 0x83;
/**********************************************************/ /* Calculate baud rate */ /**********************************************************/ U0DLL = (12000000 * 5) / (baud_rate * 16 * 4);
/**********************************************************/ /* Set 8N1 mode, forbid access to divider-latches */ /**********************************************************/ U0DLM = 0x00; U0LCR = 0x03; }
void UARTPutchar(int buffer) { /**********************************************************/ /* Write char to Tx register */ /**********************************************************/ U0THR = buffer;
/**********************************************************/ /* Wait until the char is sent */ /**********************************************************/ while(!(U0LSR & 0x40)); }
void UARTTextOut (char * string) { int i, len = strlen (string);
for (i = 0; i < len; i++) UARTPutchar (string [i]); }
char UARTReadChar (void) { /**********************************************************/ /* Wait char from terminal */ /**********************************************************/ while(!( U0LSR & 0x1 )) {} return U0RBR; //Read character from input buffer } |
|
|
|
Функция инициализации (InitUART) подключает выводы микроконтроллера к модулю UART (строка 6), активирует и очищает очереди на прием и передачу (строка 11), устанавливает режим передачи и разрешает доступ к делителю-защелке (строка 16), рассчитывает необходимое значение U0DLL для работы на заданной скорости (строка 21) и запрещает доступ к делителю-защелке.
Формула, приведенная в строке 21 стандартна для всех контроллеров семейства LPC2xxx:
U0DLL = (CPU_Freq) / (baud_rate * 16 * 4),
где CPU_Freq = частота кварца * умножитель PLL,
baud_rate - необходимая скорость работы, бод/с.
Функция UARTPutChar пересылает один символ по интерфейсу UART. В строке 36 она записывает необходимый символ в соответствующий регистр, в строке 41 ожидает отправки данного символа.
Функция UARTReadChar ожидает появления символа во входном буфере, полученного из терминала компьютера (или любого другого устройства), читает этот символ и возвращает вызывающей подпрограмме (строки 57, 58).
6. Литература.
LPC2148 User Manual (часть 9).
Education Board user manual.
Education board schematics.
Практическое занятие №7. Интерфейс SPI.
1. Общие сведения.
SPI - интерфейс передачи данных, поддерживающий главные “master” и подчиненные “slave” устройства на шине. В микроконтроллерах семейства LPC2xxx интерфейс SPI может работать как главным так и подчиненным устройством.
Интерфейс SPI содержит 4 сигнала: SPI_SCK, SPI_SSEL - сигналы синхронизации, SPI_MISO (master input slave output), SPI_MOSI (master output slave input) - каналы передачи данных.
Временные диаграммы цикла передачи данных в различных режимах приведены на рисунке 7.1.
Рис. 7.1. Временные диаграммы цикла передачи данных.
На отладочной плате через интерфейс SPI данные передаются на два последовательно соединенных регистра, управляющих светодиодной матрицей. Первый регистр выбирает столбцы, подавая сигнал 1 на соответствующие выходы, второй - позволяет протекать току через светодиоды, выставляя сигнал 0 на соответствующие выходы.
Схема включения светодиодной матрицы приведена на рисунке 7.2.
Рис. 7.2. Схема включения светодиодной матрицы.
Перемещение светящейся точки на матрице осуществляется при помощи джойстика, схема которого приведена на рисунке 7.3.
Рис. 7.3. Схема подключения джойстика.
2. Описание регистров.
Регистр. |
Описание. |
S0SPCR |
Регистр управления SPI. |
S0SPSR |
Регистр состояния. |
S0SPDR |
Двунаправленный регистр данных. |
S0SPCCR |
Счетчик тактовых импульсов. |
S0SPINT |
Регистр прерывания. |
Описание регистра управления.
Биты. |
Описание. |
1:0 |
Зарезервировано. |
2 |
0 - все передачи по 8 бит, 1 - по столько бит, сколько указано в битах 11:8 |
3 |
CPHA. Определяет моменты выдачи данных. См. рис. 7.1. для пояснения. |
4 |
CPOL. Полярность. См. рис. 7.1. для пояснения. |
5 |
1 - режим “master”, 0 - режим “slave”. |
6 |
0 - данные передаются в режиме Big Endian, 1 - в режиме Little Endian. |
7 |
Режим прерывания. |
11:8 |
Количество бит за одну передачу при бите 2 равном 0. 1000 - 8 бит 1001 - 9 бит … 1111 - 15 бит 0000 - 16 бит |
15:12 |
Зарезервировано. |
3. Цель работы.
Исследовать методы работы с интерфейсом SPI.
4. Порядок выполнения работы.
Запустить проект 05_SPI.
Понять логику и последовательность работы программы.
Запустить программу на плате и наблюдать результаты ее работы (управлять работой интерфейса SPI можно при помощи находящегося на плате джойстика).
5. Комментарии к программе.
Код, описывающий логику работы программы, приведен в листинге 7.1.
|
main.c |
Листинг 7.1. |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
int main (void) { int X = 4, Y = 4;
/***************************************************/ /* Write Hands On number to LCD */ /***************************************************/ InitLCD (); SetBacklight (1); LCDTextOut (" Hands On 5 ", " SPI Usage ");
/***************************************************/ /* Hands On code */ /***************************************************/
InitSPI (); // see "spi.c"
while (1) { switch ((IOPIN0 & (0x1F << 16)) >> 16) // Read joystick { case 0x1D: if (Y < 8) Y++; break; // Up case 0x0F: if (Y > 1) Y--; break; // Down case 0x17: if (X > 1) X--; break; // Left case 0x1B: if (X < 8) X++; break; // Right default: break; }
SPIPutDot (X, Y); // put dot to LED matrix, see "spi.c" Sleep (300); }
return 0; } |
|
|
|
В строке 16 инициализируется модуль SPI (см. листинг 7.2).
В строке 20 происходит опрос джойстика. В соответствии с его положением, выбираются новые координаты точки на светодиодной матрице и передаются в модуль SPI (строка 29, см. листинг 7.2).
|
spi.c |
Листинг 7.2. |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
void InitSPI (void) { /***************************************************/ /* Pin Select to use SPI */ /***************************************************/ PINSEL0 |= (1 << 8) | (1 << 10) | (1 << 12);
/***************************************************/ /* Init SPI */ /***************************************************/ S0SPCR = (0 << 2) | // set bits per transfer (0-8bit, 1-defined) (1 << 3) | // CPHA mode (1 << 4) | // SCK is active high (1 << 5) | // Set SPI as master (0 << 8); // 16 bits per transfer
S0SPCCR = 64; // Set SPI speed }
void SPIPutDot (int x, int y) { IOSET0 = (1 << 15); // Pull up P0.15
/***************************************************/ /* Send value for first shift register */ /***************************************************/ S0SPDR = ~(1 << (y - 1)); while ((S0SPSR & (1 << 7)) == 0); // Wait until data is sent
/***************************************************/ /* Send value for second shift register */ /***************************************************/ S0SPDR = ~(1 << (8 - x)); while ((S0SPSR & (1 << 7)) == 0); // Wait until data is sent
IOCLR0 = (1 << 15); // Pull down P0.15 ("apply new settings") } |
Функция инициализации модуля SPI (InitSPI) подключает выводы микроконтроллера к SPI (строка 6), настраивает режим работы модуля (строки 11-15) и выбирает делитель скорости (строка 17).
Функция рисования точки (SPIPutDot) разрешает работу сдвиговых регистров (строка 23), отправляет на них значения (строки 28 и 34) и ждет отправки этих значений (строки 29 и 35). Строка 37 запрещает работу сдвиговых регистров.
6. Литература.
LPC2148 User Manual (часть 12).
Education Board user manual.
Education board schematics.
Практическое занятие №8. Интерфейс USB.
1. Общие сведения.
USB (Universal Serial Bus) - это широко распространенный 4-проводной интерфейс, поддерживающий связь между USB хостом и множеством периферийных устройств (макс. 127). Модуль USB на микроконтроллере LPC2148 является клиентским (“slave” - контроллером) и не содержит USB хоста. Это позволяет конструировать такие устройства как USB-мыши, клавиатуры, звуковые карты, накопители информации и многие другие. При этом данный микроконтроллер поддерживает стандарт USB 2.0 Full Speed и может работать с максимальной скоростью 12 Mb/s.
Модуль USB микроконтроллеров LPC2ххх имеют 8 Кб памяти, выделенной для DMA. Кроме того, это единственные микроконтроллеры из своей категории, поддерживающие 32 конечные точки, что позволяет реализовать практически любое USB устройство.
Архитектура контроллера USB приведена на рисунке 8.1.
Рис. 8.1. Архитектура контроллера USB.
Создание программного обеспечения для USB устройств - непростая задача, требующая глубокого понимания интерфейса USB. При необходимости, можно самостоятельно изучить спецификацию USB (прилагается) и порядок работы программы.
2. Цель работы.
Познакомиться с возможностями USB контроллера.
3. Порядок выполнения работы.
Открыть проект 06_USB.
Скомпилировать и запустить программу на отладочной плате.
При питании не от USB порта, соединить USB кабелем отладочную плату и компьютер.
Подождать, пока в компьютере не обнаружится новое устройство. Как правило, в операционных системах семейства Windows, начиная с Win2000, нет необходимости устанавливать дополнительные драйвера.
Изучить появившийся диск. Попробовать прочитать и записать на него информацию.
4. Литература.
Спецификация USB 2.0.
1
COM кабель от COM порта компьютера
USB кабель от USB порта компьютера
20-контактный кабель от J-LINK