SDK 1.1: Методические указания по микропроцессорным системам

В.В. Ковалев
УЧЕБНЫЙ
МИКРОПРОЦЕССОРНЫЙ СТЕНД
SDK 1.1
Электронное текстовое издание
Методические указания к лабораторным работам 1-6
по курсу «Микропроцессорные системы»
Екатеринбург
2013
ОГЛАВЛЕНИЕ
Введение
3
Лабораторная работа 1. Изучение архитектуры стенда
4
1.1 Теоретический материал...................................................................................................................................... 4
1.2 Контрольные вопросы........................................................................................................................................ 20
1.3 Задание .................................................................................................................................................................. 21
1.4 Методические указания ..................................................................................................................................... 21
Лабораторная работа 2. Работа с последовательным каналом
22
2.1 Теоретический материал.................................................................................................................................... 22
2.2 Драйвер работы с последовательным каналом ............................................................................................. 23
2.3 Контрольные вопросы........................................................................................................................................ 25
2.4 Пример программы............................................................................................................................................. 25
Лабораторная работа 3. Работа с жидкокристаллическим индикатором
28
3.1 Теоретический материал.................................................................................................................................... 28
3.2 Драйвер работы с жидкокристаллическим индикатором ........................................................................... 33
3.3 Контрольные вопросы........................................................................................................................................ 37
3.4 Пример программы............................................................................................................................................. 37
3.5 Задание .................................................................................................................................................................. 39
3.6 Методические указания к выполнению задания ......................................................................................... 39
Лабораторная работа 4. Работа с матричной клавиатурой АК1604А-WWB
40
4.1 Теоретический материал.................................................................................................................................... 40
4.2 Драйвер работы с матричной клавиатурой ................................................................................................... 42
4.3 Контрольные вопросы........................................................................................................................................ 43
4.4 Задание .................................................................................................................................................................. 44
4.5 Методические указания ..................................................................................................................................... 44
Лабораторная работа 5. Программирование часов реального времени
45
5.1 Теоретический материал.................................................................................................................................... 45
5.2 Драйвер работы с часами реального времени ............................................................................................... 46
5.3 Контрольные вопросы........................................................................................................................................ 48
5.4 Пример программы............................................................................................................................................. 48
5.5 Задание .................................................................................................................................................................. 50
Лабораторная работа 6. Программирование микросхемы EEPROM
51
6.1 Теоретический материал.................................................................................................................................... 51
6.2 Драйвер работы с микросхемой EEPROM ..................................................................................................... 52
6.3 Контрольные вопросы........................................................................................................................................ 54
6.4 Пример программы............................................................................................................................................. 54
2
ВВЕДЕНИЕ
Предлагаемые методические материалы ориентированы на изучение
студентами
принципов
построения
и
структурно-функциональных
особенностей современных микропроцессоров (МП) и микроконтроллеров
(МК), их систем команд, способов адресации, областей применения и т.п., а
также на освоение методики составления управляющих программ для
микропроцессорных и микроконтроллерных систем, их использования и
практического
применения
в
автоматизированных
системах
обработки
информации и управления (АСОиУ).
Для
проведения
лабораторного
практикума
по
дисциплине
«Микропроцессорные системы» используется учебный микропроцессорный
стенд SDK-1.1.
Учебный
лабораторный
комплекс
SDK-1.1
представляет
собой
микропроцессорное устройство, подключенное к персональному компьютеру
через
интерфейс
RS232С
и
установленное
программное обеспечение.
3
на
ПК
инструментальное
ЛАБОРАТОРНАЯ РАБОТА 1
ИЗУЧЕНИЕ АРХИТЕКТУРЫ СТЕНДА
Цель работы: ознакомиться с архитектурой стенда SDK-1.1.
Ход работы:
– ознакомиться с теоретическим материалом;
– ответить на контрольные вопросы;
– выполнить задание, ознакомившись с методическими указаниями.
1.1 Теоретический материал
Учебный
микропроцессорный
стенд
SDK-1.1
построен
на
базе
однокристальной микро-ЭВМ ADuC812 (вычислительное ядро MCS51) и имеет
в своем составе разнообразные устройства, предназначенные для ввода,
обработки и вывода информации в цифровом и аналоговом виде.
На рисунке 1.1 представлено схематическое изображение лицевой панели
стенда SDK-1.1.
Рис. 1.1. Схематическое изображение стенда SDK-1.1
ADuC812 является первой микросхемой семейства ADuC8xx, запущенной
в серийное производство в мае 1999 года.
На рисунке 1.2 представлен внешний вид лицевой панели стенда SDK-1.1.
4
Отличительной особенностью семейства микросхем серии ADuC8xx
является сам принцип их построения. Эти микросхемы представляют собой
удачно скомбинированные АЦП и ЦАП, микроконтроллер и флэш-память. Их
основным достоинством является высокая точность аналого-цифрового и
цифро-аналогового преобразования, удачно сочетаемая с возможностью
непосредственной обработки получаемой информации.
Рис. 1.2. Внешний вид лицевой панели стенда SDK-1.1
Расшифровка обозначений на лицевой панели стенда SDK-1.1 дана в
таблице 1.1.
Таблица 1.1
Расшифровка обозначений на лицевой панели стенда SDK-1.1
Элемент
Описание
LCD
Жидкокристаллический индикатор WH1602B-YGK-CP .
KEYBOARD
Матричная клавиатура AK1604A-WWB.
Z1
Звуковой пьезокерамический излучатель.
SW2
Кнопка сброса RESET.
J4
Разъем питания стенда 10-14 В типа «JACK», полярность
безразлична.
5
Продолжение таблицы 1.1
Элемент
Описание
JDP1
Разъем последовательного порта стенда.
J1
Выводы каналов АЦП и ЦАП.
SW1
Переключатель, замыкающий каналы 0 и/или 1 ЦАП на входы
соответствующих (0, 1) каналов АЦП.
16 линий параллельного порта ПЛИС MAX и 4 линии
J3
параллельного порта P3 микроконтроллера ADuC812 (INT0/1, T0/1).
Набор переключателей, замыкающих соответствующие выводы
SW3
J3 на корпус (переключение в лог. «0»).
J2
Выводы JTAG-интерфейса ПЛИС MAX.
JP1
Перемычка,
замыкающая
вывод
PSEN
внешней
батареи
микроконтроллера
ADuC812 на корпус.
Разъемы
JP3
подключения
питания
часов
реального времени PCF8583.
D9-D16
Набор сигнальных светодиодов
Назначение разъемов и перемычек стенда SDK-1.1 приведено в таблице 1.2.
Таблица 1.2
Назначение разъемов и перемычек стенда SDK-1.1
Элемент Назначение
JP1
Перемычка
предназначена
для
замыкания
вывода
PSEN
микроконтроллера ADuC812 через резистор 1 Ком на корпус. По
сигналу RESET или при включении питания микроконтроллер
ADuC812 анализирует состояние вывода. Если перемычка замкнута
(лог. «0»), то запускается встроенная в микроконтроллер процедура
перезаписи внутренней Flash-памяти.
JP3
Разъем предназначен для подключения внешней батареи питания
+5В часов реального времени PCF8583. Если батарея не подключена,
питание часов осуществляется через ионистр емкостью 0.1 Ф.
6
Продолжение таблицы 1.2
Элемент
JDP1
Назначение
Разъем
предназначен
для
подключения
кабеля
асинхронного
последовательного интерфейса, связывающего стенд с COM-портом PC.
J2
Разъем предназначен для программирования ПЛИС MAX3064 через
интерфейс JTAG (IEEE1149).
J1
Разъем J1 представляет собой набор входов восьмиканального АЦП
и выводов двухканального ЦАП микроконтроллера ADuC812.
Замыкание каналов ЦАП на корпус при ненулевом напряжении на
них может привести к выходу микроконтроллера ADuC812 из строя.
J3
Разъем представляет собой выводы параллельного порта ПЛИС
MAX3064 и 4 линии порта Р3 микроконтроллера ADuC812. Прямое
замыкание линий параллельного порта ПЛИС или порта Р3 ADuC812
на корпус при ненулевом напряжении на них может привести к
выходу соответствующих микросхем из строя.
В состав учебного стенда SDK-1.1, структура аппаратной части которого
приведена на рисунке 1.3, входят:
– микроконтроллер ADuC812 (Analog Devices), 8 Кб FLASH, 256 байт
ОЗУ, 640 байт EEPROM;
– внешнее ОЗУ 128 Кб (с возможностью расширения до 512 Кб),
подключение к МК ADuC812 по системной шине; используется для хранения
пользовательских программ и данных;
– расширитель портов ввода–вывода – ПЛИС MAX3064 (Altera),
подключение к МК ADuC812 по системной шине;
– внешняя EEPROM–память 256 байт, подключение к МК ADuC812 по
интерфейсу I2C;
– часы реального времени – PCF8583 (Philips), подключение по
интерфейсу I2C;
7
– консоль оператора (подключение через ПЛИС к МК ADuC812)
содержит: символьный жидкокристаллический индикатор (ЖКИ) WH1602BYGK-CP (Winstar Display), матричную клавиатуру, звуковой излучатель,
управляемые светодиоды – 8 шт., ручные переключатели тестовых сигналов
для аналоговых и дискретных портов ввода (коммутатор аналоговых каналов –
подключен напрямую к МК ADuC812, стимулятор дискретных портов);
–
интерфейсы:
оптически
развязанный
приемопередатчик
инструментального канала RS–232C (для связи с персональным компьютером),
интерфейс JTAG (IEEE 1149.1) для контроля периферийной шины и портов,
реализованных в ПЛИС MAX3064.
Рис. 1.3. Структура аппаратной части учебного стенда SDK-1.1
Микроконтроллер ADuC812
Микроконтроллер ADuC812 является клоном Intel 8051 (8052) со
встроенной периферией и отвечает Гарвардской архитектуре.
8
Основные характеристики микроконтроллера ADuC812:
• рабочая частота 11.0592 МГц;
• 8 Кб Flash допускает 10000–50000 циклов доступа к памяти/стираниезапись-чтение для хранения программ (в стенде SDK-1.1 в этой памяти
располагается
резидентный
загрузчик
и
системная
таблица
векторов
прерываний);
• 256 байт ОЗУ данных;
• 640 байт программируемого EEPROM со страничной организацией
(160 страниц по 4 байта) допускает 10000–50000 циклов доступа к
памяти/стирание-запись-чтение
и
используется
для
хранения
данных
(например, различных настроек);
• адресное пространство памяти программ 64 Кб;
• адресное пространство внешней памяти данных 16 Мб;
• четыре 8-разрядных порта ввода-вывода (три двунаправленных, один
порт ввода);
• три 16-битных таймера/счетчика и таймер WatchDog;
• 8-канальный
12-битный
АЦП
(максимальная
частота
выборки-
дискретизации 200 КГц);
• 2-канальный 12-битный ЦАП;
• внутренний термодатчик;
• режим управления питанием;
• универсальный асинхронный приемопередатчик (UART);
• интерфейс I2C (используется в стенде SDK-1.1), интерфейс SPI (не
используется в стенде SDK-1.1).
Внешняя память программ и данных
Внешняя память программ и данных стенда SDK-1.1 представляет собой
статическое
ОЗУ
(SRAM),
имеющее
страничную
организацию
и
предназначенное для размещения пользовательских программ и данных. Размер
страницы – 64 Кб. Первая страница (страница 0) доступна для выборки команд
9
и данных микроконтроллером ADuC812. Остальные страницы доступны только
для размещения данных (логическое адресное пространство внешней памяти
данных составляет 16 Мб). Однако, реально для пользовательских программ
доступно не 64 Кб, а 52 Кб, т.к. в младшие адреса отображается 8 Кб Flash
памяти ADuC812 (адреса 0000h–1FFFh). Кроме того, 4 Кб зарезервировано
резидентным загрузчиком МК (адреса F000h–FFFFh).
Если в пользовательской программе используются прерывания, то ее
рекомендуется загружать с адреса 2100h, т.к. в пространстве адресов
2000h–2100h располагается пользовательская таблица векторов прерывания.
Физическое адресное пространство внешней памяти данных в стенде
SDK-1.1 ограничено 512 Кб (т.е. не может быть 16 Мб), потому что начиная с 8
страницы располагается адресное пространство ПЛИС (MAX 3064).
Внешняя память программ и данных подключается к МК ADuC812 по
системной шине, как и ПЛИС.
Распределение памяти
На рисунке 1.4 представлена карта памяти SDK-1.1.
Рис. 1.4. Карта памяти SDK-1.1
Стандартная для архитектуры 8051 структура внутренней памяти
представлена четырьмя банками по 8 регистров общего назначения (диапазоны
адресов 00h–07h, 08h–0Fh, 10h–17h,18h–1Fh), битовым сегментом (20h–2Fh),
свободным
участком
30h–7Fh,
областью
10
размещения
SFR
(регистров
специального назначения), 80h–FFh, доступной при прямой адресации и
свободной областью 80h–FFh, доступной при косвенной адресации. Внешняя
память разбита на следующие области: ADuC812 Flash/EE, SRAM, MAX.
Регистры специального назначения Special Function Registers (SFR)
занимают адреса внутренней памяти данных с 80h по FFh. SFR служат для
управления, конфигурирования и передачи/приема данных от периферийных
устройств, т.е. выполняют функцию интерфейса между процессором и
периферией на кристалле. Так как адреса SFR совпадают со старшими адресами
внутреннего ОЗУ данных, то имеются особенности при использовании этих
адресов внутренней памяти данных.
Система команд микроконтроллера позволяет обращаться к ячейкам
внутренней памяти данных при помощи прямой и косвенно-регистровой
адресации.
При
обращении
к
ячейкам
памяти
с
адресами
00h–7Fh
использование любого из этих видов адресации будет производить выборку
одной и той же ячейки памяти. При обращении к ячейкам ОЗУ с адресами
80h–FFh следует воспользоваться косвенно-регистровой адресацией. Учитывая,
что работа со стеком ведется при помощи косвенной адресации, то стек имеет
смысл размещать в этой области памяти. Если же требуется обратиться к
регистрам специальных функций, то нужно использовать прямую адресацию.
ADuC812 Flash/EE. Это область, в которой располагается таблица
векторов прерываний и резидентный загрузчик файлов в формате HEX в память
SRAM.
SRAM. Статическая память SRAM в SDK-1.1 имеет страничную
организацию (максимум 8 страниц по 64 К) и условно разделяется на две
области. Первая занимает младшие 64 Кбайт (страница 0) и доступна для
выборки команд микроконтроллером ADuC812. Таким образом программы
могут располагаться только в этих младших 64 К адресного пространства.
Остальные страницы доступны только для размещения данных. Для адресации
ячейки памяти определенной страницы необходимо записать номер страницы в
регистр специального назначения DPP ADuC812 (адрес 84h).
11
MAX. В младших адресах восьмой страницы адресного пространства
(080000h–0080007h)
располагается
8
ячеек
регистров
специального
назначения(SFR) ПЛИС MAX 8064 (MAX8128). Эта область предназначена для
взаимодействия
с периферийными устройствами
стенда
[4]. Регистры
включают в себя регистры управления, конфигурирования и регистры данных,
которые вместе обеспечивают интерфейс между SPU и внутренней периферией.
Процесс написания программ для SDK-1.1
На
рисунке
1.5
представлен
процесс
написания
программ
для
лабораторного стенда SDK-1.1.
Рис. 1.5. Процесс написания программ для SDK-1.1
Подготовка программ для микроконтроллера ADuC812 осуществляется
на языке программирования Си на ПК в обычном текстовом редакторе или
специальной среде программирования, предназначенной для разработки
программ под ядро MCS-51.
Далее
программа
компилируется
в
исполняемый
HEX-модуль,
доставляемый в стенд с помощью специально разработанного программного
обеспечения. Программы для стенда располагаются в ОЗУ объемом 128 Кб.
В данном пособии для написания и компиляции программ предлагается
использовать пакет фирмы Keil Software-Keil µVision4.
Пакет μVision объединяет все средства разработчика в одну мощную
среду разработки, что повышает производительность приложений для
встраиваемых систем (рисунок 1.6).
12
Рис 1.6. Структура пакета Keil µVision4
До 1995 года компиляторы, ассемблеры и компоновщики запускались под
DOS из командной строки. Командные файлы должны были вызывать эти
программы, а затем обрабатывать исходные файлы при помощи различных
контрольных инструкций. В командных файлах использовались элементы,
которые не были интуитивно понятны пользователю. Это усложняло процесс
разработки приложения и требовало больших временных затрат.
Когда компания Keil Software выпустила интегрированную среду
разработки
μVision
IDE
для
Windows-приложений,
стало
возможным
редактировать исходные файлы, устанавливать контрольные инструкции,
компилировать и отлаживать приложения – и все это с помощью нескольких
кликов мышки.
В 1998 году Keil Software выпустила интегрированную среду разработки
μVision2 с множеством новых функций. Во втором релизе μVision2 была
впервые представлена база данных устройств (Device Database), содержащая
список всех микроконтроллеров, которые поддерживаются μVision, что сделало
простым процесс создания кода для конкретного микроконтроллера. Эта база
также доступна на сайте компании Keil, где благодаря существующей форме
13
поиска можно подобрать контроллер, наилучшим образом подходящий под
требования приложения. Пользователю нужно всего лишь выбрать конечное
устройство
из
базы
данных,
и
μVision
автоматически
устанавливает
необходимые инструменты и мастер конфигурации. μVision позволяет
использовать только те инструменты и команды, которые возможно применять
к
выбранному
микроконтроллеру,
и
предотвращает
использование
несовместимых друг с другом инструкций.
Диалоговое окно опции проекта (Project Options) позволяет установить
необходимый набор настроек для всех файлов программы, группы файлов или
для отдельного файла. Опции включают в себя: выбор микроконтроллера и
адресного пространства, определение файлов, генерируемых ассемблером,
компилятором и компоновщиком, а также выбор средств отладки и
программирования.
При создании каждого нового проекта необходимо выполнять
действия, описанные ниже.
1. Выбрать тип микроконтроллера:
Project → Options for Target ‘Target1’ → Device → Analog Device →
ADuC812
2. На вкладке Project → Options for Target ‘Target1’ → Output поставить
галочку « Create HEX File».
Рис. 1.7. Настройка опций проекта
14
3. На вкладке Project → Options for Target ‘Target1’→ Target указать
размер памяти программ Off-chip Code memory – 0x2100 и данных Off-chip
Xdata-memory 0x4000 (рисунок 1.7).
4. Для записи программы на языке С необходимо создать и сохранить
новый текстовый файл.
В
появившемся
окне
«Save
As»
выбрать
папку
С:\Users\Имя_студента\Имя_работы и ввести имя файла с расширением «c».
Например «Имя_работы.c». Расширение вводится студентом самостоятельно.
Проект может содержать несколько файлов с исходными текстами
программ на языке С51 (*.с), ассемблера (*.asm), объектные файлы (*.obj),
объектные библиотеки(*.lib).
Чтобы включить созданный файл в проект нужно на вкладке Project→
Components, Environment, Books выбрать команду Add Files. Выбрать созданный
файл «Имя_работы.c» или другой нужный файл и нажать кнопку «Add».
В программе необходимо предусмотреть бесконечный цикл While (1).
Этот цикл играет роль оператора завершения программы. Так как SDK-1.1 не
находится под управлением операционной системы, то простой выход из
пользовательской программы приведет к неконтролируемой выборке команд
микроконтроллером из памяти, что может вызвать нежелательные последствия
и даже привести к выходу стенда из строя. Поэтому рекомендуется все
программы либо завершать бесконечным циклом, либо строить их таким
образом, что бы они работали по бесконечному алгоритму.
5. Включить файл STARTUP.A51(C:\Keil\C51\LIB\ STARTUP.A51) в свой
проект. Тип файла – Asm Sourse file.
6. Включить в свой проект необходимые для работы драйверы устройств.
Все драйверы устройств находятся в папке C:\Users\SDK1.1. Необходимо
скопировать нужный для задания драйвер в папку со своим проектом
С:\Users\Имя_студента\Имя_работы. Чтобы включить этот файл в проект нужно
на вкладке Project→ Components, Environment, Books выбрать команду Add Files.
Папки C:\Users\SDK1.1 на каждом компьютере в лаборатории содержат:
15
• ADuC812.h – заголовочный файл, содержащий определение всех
регистров специального назначения микроконтроллера ADuC812;
• buzz.h, buzz.c – заголовочный файл и файл с исходным кодом драйвера
для работы с звуковым излучателем;
• eeprom.h, eeprom.c – заголовочный файл и файл с исходным кодом
драйвера для работы с микросхемой EEPROM;
• I2C.h, I2C.c – заголовочный файл и файл с исходным кодом драйвера
для работы с последовательным интерфейсом I2C;
• kb.h, kb.c – заголовочный файл и файл с исходным кодом драйвера для
работы с матричной клавиатурой;
• lcd.h, lcd.c – заголовочный файл и файл с исходным кодом драйвера для
работы с жидкокристаллическим индикатором;
• max.h, max.c – заголовочный файл и файл с исходным кодом драйвера
для работы с регистрами специального назначения;
• rtc.c, rtc.h – заголовочный файл и файл с исходным кодом драйвера для
работы с часами реального времени;
• sio.h, sio.c – заголовочный файл и файл с исходным кодом драйвера для
работы с последовательным каналом;
• STARTUP.A51 – стартовый файл для программ на С; его код
выполняется
сразу
после
перезагрузки
устройства
и
обеспечивает
инициализацию различных параметров микроконтроллера, очистку внутренней
и внешней памяти данных, а также передачу управления методу main
программы на языке С;
• Т2.exe – инструментальная система для загрузки программ в память стенда.
Вид этой папки приведен на рисунке 1.8.
16
Рис. 1.8. Содержимое папки C:\Users\SDK1.1
В текстовом окне файла «Имя_работы.c» набрать текст программы на
языке С, используя пример, приведенный в теоретической части.
7.
Сохранить программу File →Save;
8.
Провести компиляцию Project→Build target. Если появились
сообщения об ошибках, то их необходимо исправить, а затем повторить
компиляцию.
В результате успешной компиляции в папке С:\users\Имя_студента\
Имя_работы будет создан загрузочный файл с расширением (*.hex). Например
Имя_работы.hex.
Загрузка программ в память стенда
Для загрузки программ в память стенда рекомендуется пользоваться
программой Т2.
Инструментальная система Т2 призвана решать следующие задачи:
• преобразование HEX-файлов;
• передача загрузочных модулей в лабораторный стенд;
• получение информации из лабораторного стенда;
• обеспечение элементарных операций с последовательным каналом
(прием и передача байта, эмуляция терминала, настройка скорости).
В таблице 1.3 приведен перечень основных команд инструментальной
системы Т2.
17
Таблица 1.3
Перечень основных команд системы Т2
Команда
OPENCHАNNEL
Действие
Пример применения, примечание
Открытие COM-порта 9600 openchannel com1
на заданной скорости
с установкой сигнала
RTS
OPENCOM1
Открытие
портов opencom1
OPENCOM2
COM1 или COM2 на
скорости 9600 бод с
установкой
сигнала
RTS.
CLOSECHANNEL Закрытие COM порта
HELP
Вывод
справки
closechannel com1
по help TERM
команде
N TERM
Включение эмулятора 0 term
терминала:
Все
байты
приходящие
по
0 – бинарный;
последовательному каналу отображаются
1 – HEX;
на экране монитора в двоичном N=0 или
2 – десятичный;
шестнадцатеричном N=1 коде, а все
байты набираемые на клавиатуре не
воспроизводятся на экране, а передаются
по
последовательному
каналу
в
лабораторный стенд. Выход из этого
режима
производится
по
нажатии
клавиши ESC на клавиатуре компьютера.
LOADHEX
Последовательная
loadhex
пересылка строк из <имя файла.hex>
HEX-файла в SDK-1.1
по
протоколу
загрузчика HEX202
18
Продолжение таблицы 1.3
Действие
Команда
LFILE
Пример применения, примечание
Интерпретация
lfile <имя файла>
командного файла.
Файл представляет собой набор команд
T2
в
том
виде,
в
котором
они
представлены в командной строке Т2
Включение
+ECHO
режима +echo <имя файла >
копирования
консольного вывода в
файл
Выключение режима -echo <имя файла >
-ECHO
копирования
консольного вывода в
файл
ADDHEXSTART
Добавление
0x2000 0x0 addhexstart <имя файла.hex>
стартового адреса в 0x0 – должна присутствовать , но при
конец HEX-файла
работе
со
стендом
SDK-1.1
и
может
иметь
SDK
1.1
используется
не
любое
значение.
Чтобы
загрузить
программу
в
стенд
при
помощи
инструментальной системы Т2 необходимо выполнить описанные ниже
действия.
1.
Скопировать программу Т2 в папку со своей работой.
2.
Включить стенд SDK-1.1 в режиме ожидания загрузки.
На жидкокристаллическом дисплее стенда должна появиться надпись
«HEX202 Ожидание…».
3.
Оформить скриптовый файл имя_файла.txt. Его содержимое:
9600 openchannel com1
0x2100
0x00
addhexstart
// открытие COM-порта на скорости 9600 бит/с
имя_файла.hex
//
//HEX-файла
19
добавление
стартового
адреса
в
конец
loadhex имя_файла.hex
//Последовательная пересылка строк из
HEX-файла в
//SDK-1.1 по протоколу загрузчика HEX202
0 term
4.
//Включение эмулятора терминала: 0-бинарный
Для вызова скрипт файла использовать команду lfile. Например для
вызова и выполнения файла lab1.txt в окно Т2 ввести строку «lfile lab1.txt».
5.
Чтобы прервать выполнение программы, можно нажать клавишу Esc.
Монитор Т2 использует ресурсы последовательного порта монопольно.
Это значит что на компьютере можно открывать только одно окно с монитором
Т2. При открытии двух и более окон с монитором Т2 возникает конфликт
доступа к последовательному порту и мониторы Т2 работать не будут.
Прием программы с ПК осуществляется через асинхронный интерфейс UART.
1.2 Контрольные вопросы
1. Какой микроконтроллер используется в лабораторном стенде SDK-1.1?
2. Где в лабораторном стенде хранятся пользовательские программы?
3. Где в стенде хранится системное ПО «HEX-202»?
4. Для чего служат регистры специального назначения?
5. В какой последовательности происходит подготовка программ для
SDK-1.1?
6. Что означает команда «0 term» инструментальной системы Т2?
7. По какому интерфейсу часы реального времени подключены к
микроконтроллеру?
8. Что включает в себя консоль оператора?
9. Для чего служит инструментальная система Т2?
10. Зачем в программе необходим цикл while (1)?
11. Чем должен завершаться код любой программы для стенда?
12. Какое расширение имеют файлы, загружаемые в стенд?
13. Находится ли стенд SDK-1.1 под управлением операционной системы?
14. Что расположено в младших адресах восьмой страницы адресного
пространства?
15. Через какой интерфейс стенд взаимодействует с компьютером?
16. С
помощью
какого
программного
трансляция программ в стенд?
20
обеспечения
происходит
1.3 Задание
Запустить демонстрационную программу для стенда SDK-1.1.
Запустить программу работы со светодиодами и увидеть, что все
светодиоды включаются по очереди до тех пор, пока не будет нажата любая
клавиша.
Запустить программу работы с часами и увидеть, что производится
отсчет времени с момента запуска программы.
1.4 Методические указания
В SDK-1.1 вместе с системным ПО во FLASH-памяти хранится также
демонстрационная программа, которая не выполняет системных функций,
однако поставляется вместе со стендом. Оформление этой программы отдельно
от системного ПО привело бы к тому, что ее нужно было бы загружать в ОЗУ
каждый раз для демонстрации возможностей стенда. Поэтому она хранится в
энергонезависимой памяти вместе с системным ПО.
При старте стенда анализируется состояние переключателя EP7(набор
переключателей SW3 на рисунке 1.1 на плате) и, если он находился в состоянии
«ON», вместо приема образа с ПК запускается демонстрационная программа,
которая предлагает пользователю ознакомиться с возможностями стенда через
диалог с помощью ЖКИ и клавиатуры. Если переключатель EP7 находится в
состоянии «OFF», то ожидается прием программы с ПК.
В демонстрационной программе при помощи кнопок клавиатуры «2» –
листать вверх и «8» – листать вниз, а также кнопки «#» – выбрать, можно
запустить программу работы с часами либо светодиодами. С помощью кнопки
«*» можно вернуться в главное меню.
21
ЛАБОРАТОРНАЯ РАБОТА 2
РАБОТА С ПОСЛЕДОВАТЕЛЬНЫМ КАНАЛОМ
Цель
работы:
научиться
осуществлять
взаимодействие
микроконтроллера с ПК при помощи последовательного канала.
Ход работы:
– ознакомиться с теоретическим материалом;
– ознакомиться с драйвером для работы с последовательным каналом;
– ответить на контрольные вопросы;
– запустить пример программы.
2.1 Теоретический материал
Последовательный порт в контроллерах MCS51 позволяет осуществлять
последовательный дуплексный ввод-вывод в синхронном и асинхронном
режимах с разными скоростями обмена. Помимо обычного ввода-вывода, в нем
предусмотрена
аппаратная
поддержка
взаимодействия
нескольких
микроконтроллеров. Схематически контроллер порта можно представить так,
как показано на рисунке 2.1.
Рис. 2.1. Схематическое изображение контроллера порта
Как видно из рисунка, регистр SBUF, доступный пользователю для
чтения и записи, на самом деле представлен двумя регистрами, в один из
которых можно только записывать, а из другого читать. Контроллер позволяет
дуплексный обмен данными, т.е. одновременно может передавать и принимать
информацию по линиям TxD и RxD соответственно. Передача инициируется
записью в SBUF байта данных. Этот байт переписывается в сдвиговый регистр
22
из которого пересылается бит за битом. Как только байт будет переслан
целиком, устанавливается флаг ТI , сигнализирующий о том, что контроллер
готов к передаче очередного байта.
Прием осуществляется в обратном порядке: после начала процесса
приема принятые биты данных последовательно сдвигаются в сдвиговом
регистре, пока не будет принято их установленное количество, затем
содержимое сдвигового регистра переписывается в SBUF и устанавливается
флаг RI. После этого возможен прием следующей последовательности бит.
Необходимо отметить, что запись принятого байта из сдвигового регистра в
SBUF происходит только при условии, что RI=0, поэтому при заборе
пользовательской программой очередного байта из SBUF ей необходимо
сбрасывать этот флаг, иначе принятый в сдвиговый регистр, но не записанный в
SBUF, следующий байт будет безвозвратно утерян.
2.2 Драйвер работы с последовательным каналом
Драйвер работы с последовательным каналом находится в файле sio.c и
написан на языке С.
#include "aduc812.h"
#include "sio.h"
/**---------------------------------------------------------------------------init_sio()
------------------------------------------------------------------------------Инициализирует последовательный канал на заданной скорости. Использует таймер 1
Вход:
char speed - скорость. Задается константами, описанными в
заголовочном файле sio.h
bit sdouble - дублирование скорости: 0 - не дублировать скорость,
заданную аргументом speed; 1 - дублировать.
----------------------------------------------------------------------------- */
void init_sio( unsigned char speed )
{
TH1
=
speed;
TMOD
|=
0x20; //Таймер 1 будет работать в режиме autoreload
TCON
|=
0x40; //Запуск таймера 1
SCON
=
0x50; //Настройки последовательного канала
ES
=
0;
//Запрещение прерываний от приемопередатчика
}
/**---------------------------------------------------------------------------RSioStat()
23
------------------------------------------------------------------------------Возвращает ненулевое значение, если буфер приема не пуст
Результат:
0 - буфер приема пуст;
1 - был принят символ
----------------------------------------------------------------------------- */
unsigned char rsiostat(void)
{
return RI;
}
/**---------------------------------------------------------------------------wsio
------------------------------------------------------------------------------Отправляет символ по последовательному каналу
Вход:
unsigned char c - символ, который нужно отправить
----------------------------------------------------------------------------- */
void wsio( unsigned char c )
{
SBUF = c;
TI
= 0;
while( !TI );
}
/**---------------------------------------------------------------------------rsio()
------------------------------------------------------------------------------Дожидается приема символа из последовательного канала и возвращает его.
Результат:
принятый символ
----------------------------------------------------------------------------- */
unsigned char rsio(void)
{
while( !RI );
RI = 0;
return SBUF;
}
/**---------------------------------------------------------------------------type()
------------------------------------------------------------------------------Выводит ASCIIZ-строку в последовательный канал
Вход:
char *str - указатель на строку
----------------------------------------------------------------------------- */
void type(char * str)
{
while( *str ) wsio( *str++ );
}
24
Файлы ADuC812.h и sio.h – заголовочные файлы. Заголовочный файл
(иногда головной файл, англ. header file), или подключаемый файл – в языках
программирования Си и C++ это файл, содержащий определения типов данных,
структуры, прототипы функций, перечисления, макросы препроцессора. Имеет
по умолчанию расширение .h; иногда для заголовочных файлов языка C++
используют расширение .hpp. Заголовочный файл используется путём
включения его текста в данный файл директивой препроцессора #include.
Файл
назначения.
ADuC812.h
содержит
объявления
регистров
специального
Файл
содержит
объявления
функций
и
sio.h
констант,
используемых в драйвере работы с последовательным каналом sio.c.
2.3 Контрольные вопросы
1. Зачем в процедуре rsio() происходит обнуление флага RI?
2. Что такое указатель и как работает процедура type()?
3. Когда устанавливается флаг TI=1?
2.4 Пример программы
Программа, приведенная ниже, последовательно передает из контроллера
в последовательный канал строку «SDK1.1». Благодаря тому что для
инструментальной среды Т2 установлена команда 0term, все символы,
принятые из последовательного канала будут отражаться на экране консоли.
Рис. 2.2. Окно программы для примера программы лабораторной работы 1
25
Таким образом, при правильной работе программы экран монитора после
запуска программы должен выглядеть так, как показано на рисунке 2.2.
Окно проекта в среде Keil µVision должно выглядеть так, как показано на
рисунке 2.3.
Рис. 2.3. Окно программы в среде Keil µVision для примера программы
лабораторной работы 2
Код программы представлен ниже.
#include "ADuC812.h" // Включение в текст регистров специального назначения ADuC812
void main(void)
{
TH1 = 0xFD;
//Скорость 9600 бит/с
TMOD = 0x20;
//Таймер 1 в режиме autoreload
TCON=0x40;
//Запуск таймера 1
SCON=0x50;
//8 bit UART, разрешение приема
PCON&=0x7F;
//Отключение дублирования скорости, установленной в TH1
EA=0;
//Только внешняя память программ
TI=0; // сбрасывается флаг ТI, готовность к приему
26
SBUF='S'; // Примем символа из последовательного канала
while(!TI); // Ожидается пока TI не будет установлен контроллером
TI=0;
SBUF='D';
while(!TI);
TI=0;
SBUF='K';
while(!TI);
TI=0;
SBUF='1';
while(!TI);
TI=0;
SBUF='.';
while(!TI);
TI=0;
SBUF='1';
while(!TI);
while(1);
}
// Завершение программы
27
ЛАБОРАТОРНАЯ РАБОТА 3
РАБОТА С ЖИДКОКРИСТАЛЛИЧЕСКИМ ИНДИКАТОРОМ
Цель работы: изучить принцип организации и порядок работы с
жидкокристаллическим индикатором.
Ход работы:
– ознакомиться с теоретическим материалом;
– ознакомиться с драйвером для работы с жидкокристаллическим
индикатором;
– ответить на контрольные вопросы;
– запустить пример программы;
– выполнить задание, ознакомившись с методическими указаниями.
3.1 Теоретический материал
ЖКИ
в
контроллере
SDK-1.1
подключен
не
напрямую
к
микроконтроллеру ADuC812, а через расширитель портов ввода-вывода,
выполненный на базе ПЛИС. В ЖКИ есть специальный контроллер,
формирующий
необходимые
напряжения
на
входах
матрицы
и
осуществляющий динамическую индикацию. Для работы с этим контроллером
реализован простейший интерфейс, описанный ниже (рисунок 3.1, таблица 3.1).
Матрица имеет 80 входов по горизонтали и 16 входов по вертикали.
Рис. 3.1. Схема подключения контроллера ЖКИ к МК ADuC812
28
Таблица 3.1
Описание интерфейса
Основными компонентами контроллера ЖКИ являются память DDRAM
(Data Display RAM), память CGRAM (Character Generator RAM), память
CGROM (Character Generator ROM), счетчик адреса, регистр команд IR
(Instruction Register), регистр данных DR (Data Register). Регистр команд
предназначен для записи в него таких операций, как очистка дисплея,
перемещение курсора, включение/выключение дисплея, а также установка
адреса памяти DDRAM и CGRAM для последующего их выполнения. Регистр
данных временно хранит данные, предназначенные для записи или чтения из
DDRAM или CGRAM (символы). Эти два регистра можно выбрать с помощью
регистрового переключателя RS (Register Select).
Работать с ЖКИ достаточно просто. За связь с ЖКИ в расширителе
портов ввода-вывода отвечают два регистра:
DATA_IND (адрес 0x080001) отвечает за выдачу информации на шину
данных (через этот регистр можно передавать команды контроллеру и данные);
C_IND (адрес 0x080006) отвечает за формирование сигналов E, R/W и RS,
позволяющих регулировать обмен на шине между расширителем портов и
контроллером ЖКИ.
На рисунке 3.2 регистры расширителя портов изображены слева,
регистры контроллера ЖКИ справа. Для доступа к регистрам контроллера ЖКИ
29
нужно сформировать на шине сигналы с помощью регистров расширителя
портов.
Рис. 3.2. Регистры, необходимые для работы с ЖКИ
Работа с индикатором сводится к нескольким шагам.
Записывается команда или данные (коды выводимых символов) в регистр
DATA_IND расширителя портов. После этого, содержимое этого регистра
появляется на шине данных контроллера ЖКИ (DB0-DB7). Контроллер на эти
данные, естественно, не реагирует, так как сигнал E (Еnable) еще не установлен
в активный уровень (логическая «1»);
Необходимо разрешить работу с шиной с помощью сигнала E
(логическая «1»), выставить сигнал записи (логический «0» на линии W) и
указать тип регистра, с которым требуется работать в контроллере ЖКИ на
линии RS. Если передаются данные, то на сигнал RS нужно подать «1», если
команду, то – «0».
Память DD RAM
Таблица 3.2
Соответствие адресов DD RAM позициям экрана
Позиция 1
2
3
4
5
6
7
8
9
10 11 12 13 14 15 16
экрана
Адреса
00 01 02 03 04 05 06 07 08 09 0А 0В 0С 0D 0E 0F
DD
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
RAM
30
Временные диаграммы интерфейса контроллера ЖКИ
Из диаграмм (рисунок 3.3) видно, что интервал между выставлением
строба Е и его последующим сбросом составляет 500 нс.
Чтение
Запись
Рисунок 3.3- Временные диаграммы интерфейса контроллера ЖКИ
Этот интервал гораздо меньше среднего времени выполнения инструкции
в процессоре стенда SDK-1.1, составляющем примерно 1000 нс. Исходя из
этого, запись и чтение в драйвере реализованы крайне просто:
WriteMax(0x1,ch); // запись в регистр данных
Strobe(c); // разрешающий сигнал
DATA_IND символа ch
R/W = 0, RS = 1
31
Список команд контроллера ЖКИ
Список
команд
контроллера
жидкокристаллического
индикатора
находится в таблице 3.2.
Таблица 3.2
Список команд контроллера ЖКИ
0
0
0 0 0 0 0 0 1
0
0
0 0 0 0 0 1 *
0
0
Вкл./выкл.
Настроек
дисплея
0
0
0
0 0 0 0 1 I S/
/ H
D
0 0 0 1 D C B
Передвиже
ние
курсора по
экрану
Запись
данных в
память
Чтение
данных из
памяти
Функции
установки
0
0
0
1
0
D D D D D D D D
7 6 5 4 3 2 1 0
Запись данных в память
DD RAM/ CG RAM
1
1
D D D D D D D D
7 6 5 4 3 2 1 0
Чтение данных из памяти
DD RAM/ CG RAM
0
0
0
DL – длина данных
(8-бит/4-бита);
N – кол-во строк на дисплее,
(2 или 1);
F – размер символа.
R/S
Очистка
0
экрана
Возврат в 0
начальную
позицию
Начальные 0
установки
DB6
DB5
DB4
DB3
DB2
DB1
DB0
Описание
DB7
Код инструкции
R/W
Название
0 0 1 S R * *
/ /
C L
0 1 D N F * *
L
32
Очистка всей DD RAM и возврат
курсора в начальную позицию
Возврат курсора в начальную
позицию без очистки дисплея
Установка
направления
движения курсора и разрешения
сдвига символов
Вкл./выкл
D – дисплея
С – курсора
В – мигания курсора
Сдвиг курсора без изменения DD
RAM и направления сдвига
Название
Чтение
флага
занятости
счетчика
адреса
Установка
адреса CG
RAM
Установка
адреса DD
RAM
Продолжение таблицы 3.2
Описание
Чтение флага занятости BF
и счетчика адреса АС
Код инструкции
0
1 BF
AC
Адрес в CG Установка адреса CG RAM в
RAM
счетчик адреса
0
0
0
1
0
0
1
Адрес
RAM
в
DD Установка адреса DD RAM в
счетчик адреса
3.2 Драйвер работы с жидкокристаллическим индикатором
Ниже
приведен
код
программы
драйвера
для
работы
жидкокристаллическим индикатором.
#include "lcd.h"
//Описания команд (константы)
#include "max.h"
//Описание портов ПЛИС MAX3064 (3128)
/*---------------------------------------------------------------------------Переменные и флаги
-----------------------------------------------------------------------------*/
static bit CurPosCtrl=1;
//Отслеживание драйвером текущей позиции курсора
//ЖКИ (1 - вкл., 0 - выкл.)
//Текущая позиция курсора. Имеют смысл, только если CurPosCtrl = 1.
//Переменные используются функциями LCD_Putch(), LCD_GotoXY()
static char cur_x=0;//0-15
static bit cur_y=0; //0/1
/*---------------------------------------------------------------------------Функции
-----------------------------------------------------------------------------*/
/**---------------------------------------------------------------------------SwitchCurPosControl()
------------------------------------------------------------------------------Включение/выключение отслеживания текущей позиции курсора. После включения
контроля желательно установить текущую позицию заново (LCD_GotoXY()), т.к.
значение переменных cur_x и cur_y могут содержать неправильные значения.
Вход:
bit o: o = 1 - включить контроль
o = 0 - выключить контроль
33
с
----------------------------------------------------------------------------- */
void SwitchCurPosControl(bit o)
{
CurPosCtrl=o;
}
/**---------------------------------------------------------------------------Strobe()
------------------------------------------------------------------------------Подача сигнала E интерфейса ПЛИС<->ЖКИ на время не менее 500 нс. Одновременно
подаются сигналы R/W и RS в заданном аргументом c значении.
Вход:
char c - биты 1,2 определяют значения сигналов R/W и RS:
бит 1: 1 - R/W = 1 (чтение)
0 - R/W = 0 (запись)
бит 2: 1 - RS = 1 (выбрать регистр данных ЖКИ)
0 - RS = 0 (выбрать регистр команд ЖКИ)
бит 3: должен быть равным 1!
Значения остальных бит не принимаются во внимание.
----------------------------------------------------------------------------- */
void Strobe(char c)
{
unsigned int i;
WriteMax(C_IND,c | 0x1);
//Установка строба E
WriteMax(C_IND,c & 0xFE); //Сброс строба
for (i=0;i<300;i++)continue; //Задержка на время исполнения команды
//(>1.59ms)
}
/**---------------------------------------------------------------------------LCD_SwitchCursor()
------------------------------------------------------------------------------Установка режима курсора: включение/выключение курсора, вкл./выкл. мигания
Вход:
bit cursor: 1 - включить курсор,
0 - выключить курсор;
bit blink:
1 - включить мигание,
0 - выключить мигание.
----------------------------------------------------------------------------- */
void LCD_SwitchCursor(bit cursor, bit blink)
{
unsigned char i=0;
WriteMax( DATA_IND, DISPLAY_CTRL |
DISPLAY_ON |
((cursor)?CURSOR_ON:0) |
((blink)?BLINK:0) );
Strobe(0x8); //R/W = 0; RS = 0
}
/**----------------------------------------------------------------------------
34
LCD_Clear()
------------------------------------------------------------------------------Очистка ЖКИ и установка текущей позиции на первый символ первой строки
----------------------------------------------------------------------------- */
void LCD_Clear(void)
{
int i;
WriteMax(DATA_IND, CLEAR);
Strobe(0x8); //clear
cur_x = 0;
cur_y = 0;
//
for(i=0; i<1600; i++)continue;
}
/**---------------------------------------------------------------------------InitLCD()
------------------------------------------------------------------------------Инициализация ЖКИ.
----------------------------------------------------------------------------- */
void InitLCD(void)
{
unsigned short i;
for(i=0; i<4000; i++)continue; //Ожидание включения ЖКИ (>15мс после подачи
//питания)
//
cmd = 0x30;
//
WriteMax(DATA_IND, FUNCTION_SET|EIGHT_BITS);
Strobe(0x8);
for(i=0; i<1500; i++)continue; //Ожидание, предусмотренное протоколом
//инициализации (>4.1мс)
//
cmd = 0x30;
//
WriteMax(DATA_IND, FUNCTION_SET|EIGHT_BITS);
Strobe(0x8);
for(i=0; i<50; i++)continue;
//Ожидание, предусмотренное протоколом
//инициализации (>4.1мс)
//
cmd = 0x30;
//
WriteMax(DATA_IND, FUNCTION_SET|EIGHT_BITS);
Strobe(0x8);
//
for(i=0; i<100; i++)continue;
//
cmd = 0x38;
//
WriteMax(DATA_IND, FUNCTION_SET|EIGHT_BITS|TWO_LINE);
Strobe(0x8);
//
cmd = 0x08;
//
WriteMax(DATA_IND, DISPLAY_CTRL); //Display off
Strobe(0x8);
//
cmd = 0x01;
//
35
WriteMax(DATA_IND, CLEAR);
Strobe(0x8);
//
for(i=0; i<1600; i++)continue;
WriteMax(DATA_IND, ENTRY_MODE|INCR);
Strobe(0x8);
//
cmd = 0x0F;
//Display ON
WriteMax(DATA_IND, DISPLAY_CTRL|DISPLAY_ON); //Cursor OFF, Blinking OFF
Strobe(0x8);
}
/**---------------------------------------------------------------------------LCD_Putch()
------------------------------------------------------------------------------Вывод на текущую позицию символа. Текущая позиция определяется в зависимости
от значения флага CurPosCtrl: если он установлен, то по переменным cur_x, cur_y
(при этом она увеличивается с каждым выведенным символом);
если он сброшен, то по внутреннему указателю ЖКИ (не увеличивается по выводу
символа).
Вход:
char ch - выводимый символ
----------------------------------------------------------------------------- */
void LCD_Putch(char ch)
{
if(CurPosCtrl)
{
LCD_GotoXY(cur_x,cur_y);
if(++cur_x>15)cur_x=0,cur_y=~cur_y;
}
WriteMax(DATA_IND,ch);
Strobe(0xC); //R/W = 0, RS = 1 (данные)
}
/**---------------------------------------------------------------------------LCD_GotoXY()
------------------------------------------------------------------------------Установка текущей позиции ЖКИ. Сохранение ее во внутренних переменных драйвера.
Вход:
uchar x - номер столбца (позиции в строке): 0..15.
bit y - номер строки: 0..1.
----------------------------------------------------------------------------- */
void LCD_GotoXY(unsigned char x,bit y)
{
WriteMax(DATA_IND,RAM_DD|(x+((y)?0x40:0)));
Strobe(0x8); //set ram
cur_x = x;
cur_y = y;
}
/**---------------------------------------------------------------------------LCD_Type()
36
------------------------------------------------------------------------------Вывод ASCIIZ-строки на ЖКИ начиная с текущей позиции.
Вход:
char *s - указатель на строку.
----------------------------------------------------------------------------- */
void LCD_Type(char* s)
{
bit t = CurPosCtrl;
SwitchCurPosControl(1);
while(*s)
LCD_Putch(*s++);
SwitchCurPosControl(t);
}
3.3 Контрольные вопросы
1. Какие символы может отображать встроенный контролер ЖКИ?
2. Для чего используется строб Е?
3. Зачем при написании программ нужно отслеживать текущую позицию
курсора ЖКИ?
4. Какая команда будет выполняться при подаче сигналов RS =1 R/W=1?
3.4 Пример программы
Ниже приведен пример программы, которая выводит на экран ЖКИ
символы, введенные с клавиатуры. При введении пользователем символа «.»
экран очищается.
Код программы предлагается записать в файл «jki.c». Ниже приведено
содержание этого файла.
#include "aduc812.h"
#include "sio.h"
#include "lcd.h"
void main(void){
unsigned char c;
init_sio(S9600);
InitLCD();
while (1){
if (rsiostat){
c=rsio();
if (c=='.')
{
LCD_Clear();
Continue;
37
}
LCD_Putch(c);
}
}
}
Сначала необходимо включить в проект все драйверы работы: драйвер
работы с последовательным каналом, для того чтобы пользователь мог вводить
данные в консоль и драйвер работы с ЖКИ, для того чтобы отображать данные
на экране ЖКИ.
Далее нужно инициализировать последовательный канал и ЖКИ.
Затем, если символ введен и это не точка, его нужно вывести на экран
ЖКИ. Если введен символ «.», экран очищается. Все эти действия повторяются,
пока пользователь не выйдет из программы нажатием кнопки Esc.
Проект с программой должен выглядеть так, как показано на рисунке 3.4.
Рис. 3.4- Окно программы в среде Keil µVision для примера
программы лабораторной работы 2
38
3.5 Задание
Написать программу, которая по вводу в окно консоли даты в формате
«дд.мм.гг.» выдает на экран жидкокристаллического индикатора день недели.
3.6 Методические указания к выполнению задания
Для вычисления номера дня недели по введенной дате можно
воспользоваться алгоритмом, приведенным ниже.
int day, month, year,addval,isday;
if (month < 3) addval = 1;
else
addval = 0;
isday=(int) (((( 3 * year - (7 * (year + (int)((month + 9) / 12))) / 4) +
(int)((23 * month) / 9 )+ day + 2 + ((int)((year - addval) / 100) + 1) *
3 / 4 - 16)%7));
switch (isday)
{
Case 0:LCD_Type(“monday”);break;
Case 1:LCD_Type(“tuesday”);break;
Case 2:LCD_Type(“wednesday”);break;
Case 3:LCD_Type(“thursday”);break;
Case 4:LCD_Type(“friday”);break;
Case 5:LCD_Type(“saturday”);break;
Case 6:LCD_Type(“sunday”);break;
}
39
ЛАБОРАТОРНАЯ РАБОТА 4
РАБОТА С МАТРИЧНОЙ КЛАВИАТУРОЙ АК1604А-WWB
Цель работы: изучить принцип организации и порядок работы с
матричной клавиатурой.
Ход работы:
– ознакомиться с теоретическом материалом;
– ознакомиться с драйвером работы с матричной клавиатурой;
– ответить на контрольные вопросы;
– выполнить задание, ознакомившись с методическими указаниями.
4.1 Теоретический материал
Клавиатура организована в виде матрицы 4х4. Один вывод каждой
кнопки соединяется с горизонтальной линией, второй вывод соединяется с
вертикальной
линией.
Каждая
горизонтальная
линия
одним
концом
соединяется с источником питания, а вторым подключается к входному порту.
Вертикальная линия подключается только с одной стороны к отдельным
разрядам выходного порта.
Рис. 4.1. Организация матричной клавиатуры АК1604А-WWB
Если все ключи разомкнуты, то потенциал на выходных портах ROW
остается высоким, т.е. соответствует логической единице. Однако если
40
замкнуть один из ключей и на соответствующую вертикальную линию подать
сигнал низкого уровня, то потенциал горизонтальной линии, с которой
соединена эта кнопка, так же станет низким. Иначе говоря, если записать в порт
COL значение 1101, то это позволит сканировать состояние кнопок этого
«столбца». Например, если при этом будет нажата кнопка К26, то на
горизонтальной линии будет низкий потенциал и соответствующий разряд
выходного порта примет значение логического нуля, т.е. ROW=1101.
Для доступа к портам клавиатуры используется регистр KB микросхемы
ПЛИС (адрес 080000h).
Таблица 4.1
Регистр клавиатуры
COL
ROW
0
1
2
3
4
5
6
7
W
W
W
W
R
R
R
R
Таким образом, полный
опрос матричной
клавиатуры
включает
последовательное обнуление младших четырех битов регистра KB с анализом
на каждом шаге старших разрядов регистра.
Дребезг
При нажатии на кнопку напряжение не сразу устанавливается на уровне
0 В, а «скачет» в течение некоторого времени (1–10 мс), пока цепь надежно не
замкнется. После того, как клавиша будет отпущена, напряжение так же
«скачет», пока не установится на уровне логической «1» (рисунок 4.2).
Рис. 4.2. Дребезг напряжения
41
Поскольку процессор обладает высоким быстродействием, то он может
воспринять эти скачки напряжения за несколько нажатий. Для устранения
влияния «дребезга» используется программная задержка.
4.2 Драйвер работы с матричной клавиатурой
Ниже приведен исходный код драйвера для работы с матричной
клавиатурой с комментариями к нему.
#include "max.h"
/*---------------------------------------------------------------------------Переменные и флаги
-----------------------------------------------------------------------------*/
char KBTable[]="147*2580369#ABCD"; //Таблица символов, соответствующих //клавишам
//клавиатуры SDK-1.1
/*---------------------------------------------------------------------------Функции
-----------------------------------------------------------------------------*/
/**---------------------------------------------------------------------------ScanKBOnce()
------------------------------------------------------------------------------Единичное сканирование клавиатуры SDK-1.1. Если нажата клавиша, то
соответствующий ей символ (см. таблицу KBTable[]) помещается по указанному
адресу.
Вход:
char *ch - адрес, куда поместить символ нажатой клавиши. Если
не было зарегистрировано нажатия, этот аргумент игнорируется.
Выход:
*ch - помещенный символ первой (в порядке сканирования) из нажатых
клавиш.
Результат(возвращаемое
значение):
0
-
ни
одна
клавиша
не
была
нажата
сканировании;
1 - зарегистрировано нажатие.
----------------------------------------------------------------------------- */
bit ScanKBOnce(char *ch)
{
unsigned char row,col,rownum,colnum;
unsigned int i;
//Сканирование производится по "столбцам" клавиатуры, на которые подается
//"бегущий 0".
for(colnum = 0; colnum < 4; colnum++)
{
col = 0x1 << colnum; //0001,0010,0100,1000,0001,...
WriteMax(KB, ~col); //11111110,11111101,11111011,11110111,11111110,...
//При подаче нуля на очередной столбец на каждом из "рядов" проверяется
//наличие нуля (факт замыкания контакта клавишей)
42
при
for(rownum = 0; rownum < 4; rownum++)
{
row = ReadMax(KB) & (0x10 << rownum);
if( !row ) //Обнаружено нажатие клавиши:
{
for(i = 0; i<10000; i++)continue;//проверка на дребезг контакта:
//через примерно 40мс повтор сканирования той же клавиши
row = ReadMax(KB) & (0x10 << rownum);
if( !row )
{
*ch = (KBTable[(colnum<<2) + rownum]);
return 1; //Стабильное нажатие клавиши
}
}
}
}
return 0; //Ни одна клавиша не нажата
}
4.3 Контрольные вопросы
1. Какой регистр ПЛИС используется для доступа к портам клавиатуры?
2. В чем заключается явление дребезга?
3. Если записать в порт COL значение 1101, и при этом будет нажата
кнопка
К27,
какое
значение
примет
разряд
выходного
(см. рисунок 4.3)?
Рис. 4.3. Схема матричной клавиатуры
43
порта
RO
4.4 Задание
Написать программу, которая выводит в окно консоли значения клавиш,
нажатых на клавиатуре стенда SDK 1.1. Программа должна работать в
бесконечном цикле.
4.5 Методические указания
Окно проекта должно выглядеть так, как показано на рисунке 4.4.
Рис. 4.4 Окно проекта для работы с матричной клавиатурой
Для того, чтобы считать в переменную символьного типа ch значение,
введенное с клавиатуры, нужно воспользоваться функцией ScanKBOnce,
представленной в драйвере работы с клавиатурой.
ScanKBOnce(&ch) – возвращает единицу если клавиша клавиатуры
нажата и записывает нажатый символ по адресу переменной ch (операция & –
операция взятия адреса).
44
ЛАБОРАТОРНАЯ РАБОТА 5
ПРОГРАММИРОВАНИЕ ЧАСОВ РЕАЛЬНОГО ВРЕМЕНИ
Цель работы: изучить принцип организации и порядок работы с часами
реального времени.
Ход работы:
– ознакомиться с теоретическом материалом;
– ознакомиться с драйвером работы с часами реального времени;
– ответить на контрольные вопросы;
– ознакомиться с примером программы и запустить его.
5.1 Теоретический материал
Часы реального времени содержит микросхема PCF8583.
Микросхема PCF8583 содержит 8-битную оперативную память объемом
256 байт с 8-битным адресным регистром, осуществляющим автоматическое
инкрементирование адреса, генератор частоты, шину I2C и схему сброса при
выключении питания. Первые 16 байт ОЗУ представляют собой 8-битные
регистры специального назначения. Первый регистр по адресу 00 – регистр
управления состояния. Следующие 7 регистров – счетчики, последние 8
регистров могут быть запрограммированы как регистры сигнала или быть
вообще отключены и использованы как обычные регистры памяти (когда
сигналы отключены). Оставшиеся 240 байт используются как оперативная
память. При подключении питания к шине I2C сбрасывается регистр
управления/состояния и все счетчики адресов. Устройство начинает работать в
режиме часов на частоте 32,768 кГц в 24-часовом формате времени и с датой и
временем, установленным на 1.01.00 в 00:00:00:00.
В случае если выбран режим часов, то сотые доли секунд, секунды,
минуты, часы, дата (календарь на 4 года) и дни недели хранятся в двоичнодесятичном формате BCD (binary-coded decimal). При считывании должны быть
переведены в обычный двоичный формат (функция BCD2Bin()).
45
Адрес устройства на шине I2C – 1010000, плюс младший бит
направления обмена.
5.2 Драйвер работы с часами реального времени
Ниже приведен исходный код драйвера работы с часами реального
времени с комментариями к нему.
#include "i2c.h"
//заголовочный файл драйвера работы с //интерфейсом I2C,
находится в папке C:/Users/SDK1.1
#include "rtc.h"
/*--------------------------------------------------------------------------Функции
----------------------------------------------------------------------------*/
/**---------------------------------------------------------------------------BCD2Bin()
------------------------------------------------------------------------------Перевод числа из формата BCD (binary-coded decimal) в обычный двоичный формат
Вход:
Результат:
uchar val - число в BCD-формате
двоичный аналог
----------------------------------------------------------------------------*/
#define BCD2Bin(val)
( ((val)&0xF) + ( (((val)&0xF0)>>4) * 10 ) )
/**---------------------------------------------------------------------------Bin2BCD()
------------------------------------------------------------------------------Перевод числа в формат BCD (binary-coded decimal) из обычного двоичного формата
Вход:
uchar val - двоичное число
Результат:
BCD-аналог
----------------------------------------------------------------------------*/
#define Bin2BCD(val)
( ((val) % 10) + (((val) / 10)<<4) )
/**--------------------------------------------------------------------------GetTime()
-----------------------------------------------------------------------------Получение текущего времени
Вход:
TIME xdata * time - указатель на структуру в области xdata, куда
будет помещено текущее время.
Результат:
0 - успешно;
1 - часы не откликаются
----------------------------------------------------------------------------*/
bit GetTime(TIME xdata * time)
46
{
unsigned char h;
if( !GetAck(RTC_ADDRESS) )
return 1; //если часы реального времени не готовы к //обмену;GetAckфункция из драйвера I2C
if( ReceiveBlock(RTC_ADDRESS, 1, (unsigned char xdata*)time, 4) )
return 1; //сохранить блок данных из I2C-устройства в //переменную
time;функция ReceiveBlock- функция из драйвера I2C , //возвращает 1 в случае отказа
устройства
//далее идет заполнение структуры time. Ее описание смотреть в //файле rtc.h
time->hsec = BCD2Bin(time->hsec);
time->sec
= BCD2Bin(time->sec);
time->min
= BCD2Bin(time->min);
h
= BCD2Bin(time->hour & 0x3F);
if( time->hour & 0xC0 )
{
if(time->hour < 12)
time->hour = h + 12;
else
time->hour = 0;
}
else
time->hour = h;
return 0;
}
/**---------------------------------------------------------------------------SetTime()
------------------------------------------------------------------------------Установка текущего времени
Вход:
TIME xdata * time - указатель на структуру в области xdata, с
новым временем.
Результат:
0 - успешно;
1 - часы не откликаются
---------------------------------------------------------------------------- */
bit SetTime(TIME xdata * time)
{
unsigned char h;
TIME t;
if( !GetAck(RTC_ADDRESS) )
return 1; //если часы реального времени не готовы к //обмену;GetAckфункция из драйвера I2C
t.hsec = Bin2BCD(time->hsec);
t.sec
= Bin2BCD(time->sec);
t.min
= Bin2BCD(time->min);
47
t.hour = Bin2BCD(time->hour & 0x3F);
if( TransmitBlock(RTC_ADDRESS, 1, (unsigned char xdata*)&t, 4) )
return 1; //если не получилось записать блок данных во //внутреннюю
память
return 0;
}
5.3 Контрольные вопросы
1. В какую микросхему входят часы реального времени?
2.
С
помощью
какого
интерфейса
часы
реального
времени
взаимодействуют с микроконтроллером?
3. В каком формате хранится время в часах реального времени?
5.4 Пример программы
Ниже приведен пример программы, которая выводит счетчик секунд на
экран ЖКИ и в окно консоли. Вывод прекращается по нажатию кнопки на
клавиатуре ПК.
Окно проекта должно выглядеть так, как показано на рисунке 5.1.
Рис. 5.1. Окно проекта для примера программы программирования часов реального
времени
48
Ниже приведен исходный код программы.
#include "aduc812.h"
#include "sio.h"
#include "max.h"
#include "lcd.h"
#include "rtc.h"
unsigned char xdata buffer[50];
TIME xdata time = {0, 1, 2, 1};
void main(void)
{
unsigned short i;
InitLCD();
init_sio(S9600);
type("Hello!\r\n");
type("Press any key to exit\r\n");
if(SetTime(&time))
LCD_Clear();
LCD_Type("
while(1)
Clock
");
//Вывод в цикле текущего времени на ЖКИ и терминал ПК
{
if(rsiostat())
//Цикл прерывается нажатием клавиши на терминале ПК
{
rsio(); break;
}
type("Current time:");
LCD_GotoXY(0,1); // переход на следующую строку
( GetTime(&time) );
//
Получение текущего времени
i = 0;
//Секунды
buffer[i++] = (time.sec / 10) + '0';
buffer[i++] = (time.sec % 10) + '0';
buffer[i] = '\0';
type(buffer); wsio(13); // Вывод времени
на экран монитора Т2
LCD_Type(buffer); // Вывод времени на ЖКИ
}
}
В программе в цикле проверяется, введен ли символ с клавиатуры. Если
он введен, происходит выход из программы. Если нет, получают текущее время
в структуру time типа TIME.
Затем формируют строку текущего времени buffer и выводят ее на экран.
49
Символ
'0'
добавляется
к
количеству
секунд,
чтобы
перевести
получившуюся цифру в соответствующий ей символ.
5.5 Задание
Изменить
программу,
приведенную
в
примере
так,
чтобы
она
отсчитывала не только секунды, но также часы и минуты и выводила результат
на экран ЖКИ и в окно консоли.
50
ЛАБОРАТОРНАЯ РАБОТА 6
ПРОГРАММИРОВАНИЕ МИКРОСХЕМЫ EEPROM
Цель работы: изучить принцип организации и порядок работы с
микросхемой EEPROM.
Ход работы:
– ознакомиться с теоретическим материалом;
– ознакомиться с драйвером работы с микросхемой EEPROM;
– ответить на контрольные вопросы;
– ознакомиться с примером программы и запустить его.
6.1 Теоретический материал
На стенде SDK-1.1 установлена EEPROM AT24C01A, состоящая из 128
однобайтных страниц общим объемом 1Кбайт. Адрес EEPROM на шине I2C
равен 1010001, плюс младший бит, отвечающий за направление обмена.
Особенности EЕPROM AT24C01A:
• внутреннее ПЗУ 128x8;
• двухпроводной последовательный интерфейс;
• двунаправленный протокол передачи данных;
• совместимость по частоте 100 кГц (1.8 V, 2.5 V, 2.7 V) и 400 кГц (5 V);
• вывод защиты записи, обеспечивающий аппаратную защиту данных;
• поддержка страничной записи в 8-байтном (1 K, 2 K), и 16-байтном
(4 K, 8 K, 16 K) режимах;
• поддержка неполной страничной записи;
• самосинхронизирующийся цикл записи (максимум – 10 мс);
• высокая надежность: продолжительность работы 1 миллион циклов,
сохранение данных в памяти в течение 100 лет;
• автоматическая градуировка и возможность работы в широком
диапазоне температур;
• 8-штыревой и 14-штыревой модуль JEDEC SOIC, 8-штыревой модуль
PDIP.
51
AT24C01A содержит 1024 бит последовательной памяти EЕPROM,
состоящей из 128-битных слов, которая может быть перезаписана с помощью
электрических сигналов и считана программным путем. Данное устройство
предназначено для применения в промышленных и коммерческих областях, где
важным условием является низкое энергопотребление и малое напряжение
питания.
AT24C01A включает 8-штыревой модуль PDIP, 8- и 14-штыревой модуль
SOIC. Доступ осуществляется через 2-проводной последовательный интерфейс.
Внутренний счетчик адреса содержит последний адрес, к которому
производилось обращение для чтения или записи, увеличенный на единицу.
После выключения питания счетчик не сохраняет свое значение. Во время
операции чтения счетчик адреса автоматически переключается с последнего
байта страницы на первый байт той же самой страницы.
6.2 Драйвер работы с микросхемой EEPROM
Ниже приведен исходный код драйвера работы с микросхемой EEPROM
с комментариями к нему.
5
#include "eeprom.h" //Описание I2C-адреса EEPROM
6
#include "i2c.h"
7
/*----------------------------------------------------------------------------
8
9
//Функции модуля работы с I2C.
Функции
-----------------------------------------------------------------------------*/
10 /**---------------------------------------------------------------------------11
WriteBlockEEPROM()
12 ------------------------------------------------------------------------------13 Зпись блока данных в EEPROM. Контроль тайм-аута на ответ EEPROM примитивный,
14 выполнен за счет отслеживания примерной длительности исполнения цикла ожидания
15 ответа. Записываемый блок, если он больше 8 байт, разбивается на "страницы"
16 по 8 байт, которые последовательно передаются EEPROM для записи.
17 Вход:
18
uchar address - адрес (номер ячейки) EEPROM, с которого нужно
поместить блок;
19
uchar *buf - указатель на блок в области xdata;
20
uchar length - длина блока. length + address не должно превышать
21
размера EEPROM (определяется константой EEPROM_SIZE (eeprom.h)).
22 Результат:
0 - успешно;
23
1 - EEPROM не отвечает, либо длина блока больше EEPROM_SIZE
52
24 ----------------------------------------------------------------------------- */
25 bit WriteBlockEEPROM(unsigned char address, unsigned char xdata *buf, unsigned char
length)
26 {
27 unsigned short try;
28 unsigned char pages, i, remainder;
29
if((address + length) > EEPROM_SIZE)
30
{
31
return 1;
32
}
33
pages = length / 8;
34
remainder = length % 8;
35
for(i = 0; i < pages; ++i)
36
{
37
try = 0;
38
while(!GetAck(EEPROM_ADDRESS))
39
{
40
if(++try > 5000)
41
{
42
return 1; //EEPROM failed to respond
43
}
44
}
45
if( TransmitBlock(EEPROM_ADDRESS, address + (i<<3), buf + (i<<3), 8) )
46
{
47
return 1; //Error writing
48
}
49
}
50
if( remainder )
51
{
52
try = 0;
53
while(!GetAck(EEPROM_ADDRESS))
54
{
55
if(++try > 5000)
56
{
57
return 1; //EEPROM failed to respond
58
}
59
}
60
if( TransmitBlock(EEPROM_ADDRESS, address + (i<<3), buf + (i<<3), remainder) )
61
{
62
return 1; //Error writing
63
}
64
}
65
return 0;
66 }
67 /**----------------------------------------------------------------------------
53
68
ReadBlockEEPROM()
69 ------------------------------------------------------------------------------70 Чтение блока данных из EEPROM.
71 Вход:
uchar address - адрес (номер ячейки) EEPROM, с которого нужно
72
прочесть блок;
73
uchar *buf - указатель на блок в области xdata;
74
uchar length - длина блока. length + address не должно превышать
75
размера EEPROM (определяется константой EEPROM_SIZE (eeprom.h)).
76 Результат:
0 - успешно;
77
1 - EEPROM не отвечает, либо длина блока больше EEPROM_SIZE
78 ----------------------------------------------------------------------------- */
79 bit ReadBlockEEPROM(unsigned char address, unsigned char xdata *buf, unsigned char
length)
80 {
81 unsigned short try;
82
if((address + length) > EEPROM_SIZE) return 1;
83
try = 0;
84
while(!GetAck(EEPROM_ADDRESS))
85
{
86
if(++try > 5000) // >10 мс
return 1; //EEPROM failed to respond
87
}
88
if( ReceiveBlock(EEPROM_ADDRESS, address, buf, length) )
89
{
90
return 1; //Error writing
91
}
92
return 0;
93 }
6.3 Контрольные вопросы
1. Через какой интерфейс осуществляется взаимодействие с микросхемой
EEPROM?
2. Какой вид памяти представляет из себя микросхема?
3. Каков объем памяти микросхемы?
6.4 Пример программы
Программа, приведенная ниже, записывает в EEPROM числа от 0 до 28.
Если блок записался, на экран ЖКИ выводится сообщение "Write OK". Далее из
EEPROM считывается записанный блок данных и проверяется, совпадает ли он
с исходным.
54
Окно проекта должно выглядеть так, как показано на рисунке 6.1.
Рис. 6.1.Окно проекта примера программы работы с микросхемой EEPROM
Ниже приведен код программы.
#include "aduc812.h"
#include "lcd.h"
#include "eeprom.h"
unsigned char xdata buffer[30];
void main(void)
{
unsigned short i, p;
unsigned char ch, leds;
InitLCD();
for(i = 0; i < 29;
i++)
buffer[i] = (unsigned char)(i);
LCD_Clear();
LCD_Type("
EEPROM
");
LCD_GotoXY(0,1);
if( WriteBlockEEPROM(0, buffer, 29) )
LCD_Type("Write error!");
else
LCD_Type("Write OK");
for(i = 0; i < 65000; i++);
LCD_GotoXY(0,1);
if( ReadBlockEEPROM(0, buffer, 29) )
LCD_Type("Read error!");
else
{
for(i = 0; i < 29; i++)
//—⥭ЁҐ гбЇҐи­® - Їа®ўҐаЄ
55
if( buffer[i] != (unsigned char)(i) )
{
LCD_Type("Check error!");
break;
}
if(i == 29) LCD_Type("Check OK");
}
while(1);
}
56
Учебное электронное текстовое издание
Ковалев Владимир Владимирович
УЧЕБНЫЙ
МИКРОПРОЦЕССОРНЫЙ СТЕНД
SDK 1.1
Редактор
Компьютерная верстка
Н.В. Лутова
авторская
Рекомендовано Методическим советом
Разрешен к публикации 24.02.2014
Электронный формат – pdf
Объем 2,2 уч.-изд. л.
620002, Екатеринбург, ул. Мира, 19
Информационный портал УрФУ
http://www.urfu.ru