Описание команд 1. Установить начальный адрес нижнего столбца для режима адресации страницы (00h0Fh). 2. Установить более высокий начальный адрес столбца для режима адресации страницы (10h1Fh). 3. Установить режим адресации памяти (20h). 4. Установить адрес столбца (21h). 5. Установить адрес страницы (22h). 6. Установить начальную строку дисплея (40h7Fh). 7. Установить контрастный контроль для BANK0 (81h). 8. Установить повторное отображение сегмента (A0h/A1h). 9. Включить весь дисплей (A4h/A5h). 10. Установить нормальный/инвертированный режим дисплея (A6h/A7h). 11. Установить мультиплексное соотношение (A8h). 12. Установить состояние дисплея Вкл/Выкл (AEh/AFh). 13. Установить начальный адрес для режима адресации страницы (B0hB7h). 14. Установить направление сканирования COM-выхода (C0h/C8h). 15. Установить смещение дисплея (D3h). 16. Установить частоту деления дисплея/частоту генератора (D5h). Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 35 17. Установить период предварительной зарядки (D9h). 18. Настройка конфигурации аппаратного обеспечения COM-выводов (DAh).
Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 36 Функции для работы с дисплеем • SetCursor() – установка курсора по заданным координатам. • DrawPixel() – выведение на экран пикселя белого или черного цвета по заданным координатам. • WriteChar() – выведение символа на дисплей. Необходимо создать библиотеку шрифтов, где каждый символ представлен в виде последовательности байтов. Пример: Символ «S» 7x10 будет выглядеть так: 0x38, 0x44, 0x40, 0x30, 0x08, 0x04, 0x44, 0x38, 0x00, 0x00. 00 111 000 0x38 0 1 000 1 00 0x44 0 1 000000 0x40 00 11 0000 0x30 0000 1 000 0x08 0 0 000 1 00 0x04 0 1 000 1 00 0x44 00 111 000 0x38 00000000 0x00 00000000 0x00 • WriteString() – выведение строки на дисплей. • Fill() – заполняет дисплей одним цветом (белым или черным). • UpdateScreen() – записывает все изменения в память и выводит на экран. • Init() – функция инициализации дисплея, в память контроллера отправляется конфигурация (0xAE, 0xA6, 0x20, 0x00, 0x21, 0x00, 0x7F, 0x22, 0x00, 0x07, 0xA1, 0xC8, 0xA8, 0x3F, 0x81, 0x7F, 0x8D, 0x14, 0xAF) по адресу 0x00, параметры курсора устанавливаются на 0. Варианты заданий Вариант 1. Написать программу, реализующую монитор состояний светодиодов. При отправке по UART со стороны персонального компьютера символа «1» меняется состояние зеленого светодиода, «2» - желтого, «3» - красного. Выводить на дисплей информацию о состояниях всех светодиодов. Например: горит только желтый светодиод, на дисплее будет выведено: Green off Yellow on Red off Вариант 2. Написать программу, реализующую функции простого текстового редактора. Необходиом выводить на дисплей символы с клавиатуры, отправляемые по UART согласно таблице ASCII, при нажатии клавиши “Backspace” один символ стирается.
Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 37 Вариант 3. Написать программу, реализующую калькулятор с операциями сложения, вычитания, умножения и деления. С клавиатуры персонального компьютера по UART отправляется выражение, которое выводится на дисплей, при нажатии кнопки “=” на дисплее остается только ответ. Клавиша “Backspace” очищает дисплей. Вариант 4. Написать программу, реализующую функции электронного секундомера. Точность измерения времени – десятые доли секунды. Управление производится посредством двух кнопок программируемой клавиатуры SDK-1.1M (Старт/Стоп и Сброс). Вариант 5. Написать программу, рисующую на дисплее различные геометрические фигуры: квадрат, круг или треугольник, в зависимости от посылаемого с персонального компьютера через UART символа (“s”, “c”, “t”). Вариант 6. Написать программу, реализующую функции электронных часов. На дисплее должны отображаться часы, минуты и секунды.
Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 38 Лабораторная работа, «Клавиатура»Описание клавиатуры Клавиатура SDK-1.1M организована в виде матрицы 4х3. Связь с процессором осуществляется через интерфейс I 2 C. Строки и столбцы клавиатуры подключены к ногам 8-битной микросхемы PCA9538 (рис. 8). К портам P0-P3 подключены ряды, к P4, P5, P6 подключены колонки. Доступ к колонкам и рядам организован как чтение/запись определенного байта памяти, где каждый бит отвечает за определенную ногу микросхемы PCA9538. Рис. 21. Схема подключения кнопок к PCA9538. Работа с PCA9538 по I2C Последний бит адреса подчиненного устройства определяет операцию (чтение или запись), которая должна быть выполнена. Low (L) означает операцию записи, High (H) означает операцию чтения (таблица 1). Рис. 22. Адрес подчиненного устройства. Таблица. 4. Варианты I 2 C адресов. Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 39 После успешного подтверждения байта адреса ведущее устройство шины отправляет командный байт (таблица 2), который хранится в контрольном регистре в PCA9538. Два бита этого командного байта определяют операцию (чтение или запись) и внутренний регистр (вход, выход, инверсия полярности или конфигурация), которые будут затронуты. Этот регистр можно записать или прочитать через шину I 2 C. Байт команды отправляется только во время передачи записи. После того, как командный байт был отправлен, адрес, к которому был адресован регистр, продолжает обращаться к операциям чтения до тех пор, пока не будет отправлен новый байт команды. Таблица. 5. Командный байт. Описание регистров Регистр входного порта (регистр 0) отражает входящие логические уровни выводов, независимо от того, определен ли вывод как вход или выход регистром конфигурации. Действует только на операцию чтения. Записи в эти регистры не имеют никакого эффекта. Значение по умолчанию X определяется применяемым извне логическим уровнем. Перед операцией чтения передается запись с командным байтом, чтобы указать устройству I 2 C, что в следующий раз осуществляется доступ к регистру входного порта. Таблица. 6. Входной регистр. Бит I7 I6 I5 I4 I3 I2 I1 I0 Стандартное значение X X X X X X X X Регистр выходного порта (регистр 1) показывает исходящие логические уровни выводов, определенных как выходы регистром конфигурации. Битовые значения в этом регистре не влияют на выводы, определенные как входы. В свою очередь, чтения из этого регистра отражают значение, которое находится в триггере, управляющем выбором выхода, а не фактическое значение входа. Таблица. 7. Выходной регистр. Бит O7 O6 O5 O4 O3 O2 O1 O0 Стандартное значение 1 1 1 1 1 1 1 1 Регистр инверсии полярности (регистр 2) позволяет инвертировать полярность выводов, определенных как входы регистра конфигурации. Если бит в этом регистре установлен (записан с 1), соответствующая полярность контакта порта инвертирована. Если бит в этом регистре очищается (записывается с 0), исходная полярность соответствующего контакта порта сохраняется. Таблица. 8. Регистр инверсии полярности. Бит N7 N6 N5 N4 N3 N2 N1 N0 Стандартное значение 0 0 0 0 0 0 0 0
Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 40 Регистр конфигурации (регистр 3) устанавливает назначения ввода/вывода. Если бит в этом регистре установлен в 1, соответствующий вывод порта активируется как вход. Если бит в этом регистре принимает значение 0, соответствующий вывод порта активируется как выход. Таблица. 9. Конфигурационный регистр. Бит C7 C6 C5 C4 C3 C2 C1 C0 Стандартное значение 1 1 1 1 1 1 1 1 Запись и чтение данных на PCA9538 Запись: Данные передаются на PCA9538 путем отправки адреса устройства и установки младшего значащего бита в логический 0. Байт команды отправляется после адреса и определяет, какой регистр получает данные, следующие за байтом команды. Нет ограничений на количество байтов данных, отправленных во время одной передачи. Чтение: Сначала ведущее устройство шины должно отправить адрес PCA9538 с младшим значащим битом, установленным на логический 0. Байт команды отправляется после адреса и определяет, к какому регистру обращаются. После перезапуска адрес устройства отправляется снова, но на этот раз младший значащий бит устанавливается на логический 1. После этого данные из регистра, определенного командным байтом, отправляются PCA9538. После перезапуска значение регистра, определенного байтом команды, совпадает с регистром, к которому осуществляется доступ при перезапуске. Данные синхронизируются в регистре по переднему фронту тактового импульса ACK. На количество байтов данных, полученных в одной передаче чтения ограничения нет, но когда получен последний байт, ведущее устройство шины не должно подтверждать данные. Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 41 Лабораторная работа, «Прерывания» Общие сведения Прерывание – процесс переключения ЦП с одной программы на другую по внешнему сигналу с сохранением информации для последующего возобновления прерванной программы. Основная цель введения прерываний – реализация асинхронного режима работы и распараллеливания работы отдельных устройств вычислительного комплекса. Механизм прерываний реализуется аппаратно-программными средствами. Каждое событие, требующее прерывания, сопровождается сигналом прерывания, оповещающим об этом вычислительную машину, и называемым запросом прерывания. Обработка прерывания выполняется в три этапа: 1. Прекращение выполнения текущей программы. Для корректного возврата к выполнению программы после обработки прерывания необходимо сохранить контекст программы – содержимое caller-saved регистров микроконтроллера. Содержимое регистров сохраняется в стек. 2. Переход к выполнению программы обработчик. Определяется источник прерывания и соответствующий вектор прерывания. Адрес вектора прерывания записывается в регистр счетчика команд. После чего осуществляется переход к программе-обработчику прерывания и ее выполнение. 3. Возврат управления прерванной программе. Для корректного возврата управления необходимо восстановить контекст программы из стека. Последней командой программы обработки прерывания должна быть команда, которая осуществляет возврат в основную программу и восстановление предварительно сохраненного счетчика команд. Вектор прерывания – вектор начального состояния обработчик прерывания и содержит всю необходимую информацию для перехода к обработчику, в том числе его начальный адрес. Каждому типу прерываний соответствует свой вектор прерывания, который инициализирует выполнение соответствующего обработчика. Обычно векторы прерывания хранятся в специально выделенных фиксированных ячейках памяти с короткими адресами, представляющих собой таблицу векторов прерываний. Для перехода к соответствующей прерывающей программе процессор должен располагать вектором прерывания и адресом этого вектора. По этому адресу, как правило, находится команда безусловного перехода к подпрограмме обработки прерывания. Приоритеты прерываний – это механизм, позволяющий установить определенный порядок обработки запросов прерываний. При наличии нескольких запросов прерывания, поступивших одновременно, приоритет прерывания будет определять, какой из поступивших запросов будет обработан в первую очередь. Вложенные прерывания – механизм, позволяющий осуществлять обработку поступившего прерывания в период обработки другого прерывания. В случае, если во время обработки прерывания поступает запрос на прерывание с более высоким уровнем приоритета, управление передается обработчику прерывания более высокого приоритета, при этом работа обработчика прерывания с более низким уровнем приоритета приостанавливается. Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 42 Максимальное число программ, которые могут приостанавливать друг друга называется глубиной прерываний. Задания Реализовать обработчик прерываний, а также основную программу, которая будет прерываться (мигание светодиодов, вывод текста на дисплей и т.д) в соответствии с вариантом. Вариант Основная программа Обработчик прерывания Источник прерывания Длительность 1 Переключение светодиодов Включается красный и зеленый светодиод Таймер 2с 2 Вывод на дисплей результата арифметической операции Вывод на экран «Interrupt» Кнопка 1с 3 Переключение светодиодов Светодиоды не горят Dip- переключатель 2с 4 Вывод на дисплей результата арифметической операции Вывод на экран «Interrupt» Таймер 2с 5 Переключение светодиодов Включается желтый и зеленый светодиод Кнопка 1с 6 Вывод на дисплей результата арифметической операции Вывод на экран «Interrupt» Dip- переключатель 2с
Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 43 Лабораторная работа, «Операционная система реального времени FreeRTOS» Общие сведения FreeRTOS – многозадачная операционная система реального времени для встраиваемых систем. За переключение между задачами отвечает диспетчер, работающий по прерыванию от таймера. Задача выглядит как обычная функция Си, которая выполняет некоторое действие в бесконечном цикле. Для STM32 используется CMSIS-RTOS API. Пример задачи, переключающей состояние светодиода раз 500мс: void Start_ledTask( voidconst * argument) { for(;;) { HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_13); osDelay(500); } } Так как задачи выполняются асинхронно, то при использовании общей переменной данные могут теряться. Для обеспечения правильного обмена данными между задачами используются очереди. Одни задачи кладут данные в очередь, другие оттуда читают. За переполнением очереди и чтением после окончания записи следит диспетчер. Если очередь пуста/переполнена, то та задача, которая собирается считать/записать туда данные переводится в состояние WAIT и диспетчер выведет ее из этого состояния только когда очередь будет готова принять/отдать данные. Семафоры бывают двух типов: бинарные и счетные. Работа бинарного семафора очень похода на работу флага. То есть, когда некое событие поднимает флаг, а программа этот флаг отслеживает в цикле. В FreeRTOS функцию этого цикла выполняет диспетчер. Счетный семафор работает по такому же принципу. Разница лишь в том, что у него состояние это не единичный флаг, а некая переменная. Задача, которая выдает семафор эту переменную увеличивает, а которая считывает – уменьшает. Таблица. 10. Описание API FreeRTOS. API Описание osThreadCreate Начать выполнение потока osThreadTerminate Закончить выполнение потока osThreadYield Передвать выполнение другому потоку osThreadGetId Получить индефикатор потока для ссылки на него osThreadSetPriority Изменить приоритет выполнения потока osThreadGetPriority Получить текущий приоритет выполнения потока osDelay Подождать в течение указанного времени osWait Ожидать события типа Signal, Message, Mail osTimerCreate Определить атрибуты Callback таймера osTimerStart Запустить таймер с назначением времени osSignalSet Установить сигнальные флаги потока osSignalClear Сбросить сигнальные флаги потока osMutexCreate Инициализация мьютекса Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 44 osMutexWait Получить мьютекс или подождать, пока он не станет доступным osMutexRelease Освободить мьютекс osMutexDelete Удалить мьютекс osSemaphoreCreate Инициализация семафора osSemaphoreWait Получить семафор или подождать, пока он не станет доступным osSemaphoreRelease Освободить семафор osSemaphoreDelete Удалить семафор osMessageCreate Инициализация очереди FreeRTOS и STM32CubeMX Для того чтобы установить FreeRTOS, необходимо назначить один из таймеров микроконтроллера (TIM1) на генерацию системных тиков. Конфигурация FreeRTOS производится в разделе Middleware. В этом разделе можно конфигурировать: • Задачи; • Очереди; • Семафоры; • Таймеры; • Мьютексы.
Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 45 Лабораторная работа, «Введение в LwIP» Общие сведения Учебный стенд SDK-1.1M оборудован разъемом RJ-45. KSZ8081 – это приемопередатчик физического уровня Ethenet для передачи данных через витую пару со скоростью 10/100 Мбит/с. В микроконтроллерах STM32 стек TCP/IP представлен в виде LwIP (Lightweight IP). Стек LwIP предлагает три типа API: • Raw API; • Netconn API; • Socket API. Архитектура стека LwIP построена на модели, включающей четыре уровня абстракции: • Прикладной уровень содержит все протоколы для передачи данных между процессами. • Транспортный уровень обрабатывает соединения между хостами. • Интернет уровень соединяет независимые сети, устанавливая межсетевое взаимодействие. • Уровень сетевого интерфейса содержит технологии коммуникации для одного сегмента локальной сети. Рис. 23. Архитектура стека LwIP. Raw API Raw API – это родной интерфейс LwIP. Он позволяет использовать обратные вызовы функций (callbacks) внутри стека. То есть перед началом работы со стеком необходимо присвоить указатели на функции-обработчики событий, которые в процессе работы будут вызываться внутри LwIP.
Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 46 Таблица. 11. Описание RAW API TCP Функции API Описание Установка TCP- соединения tcp_new Создает новый TCP PCB (блок управления протоколом) tcp_bind Привязывает TCP PCB к локальному IP-адресу и порту tcp_listen Начало процесса прослушки tcp_accept Назначает функцию обратного вызова, которая будет вызваться при получении нового соединения TCP tcp_accepted Сообщает стеку LwIP, что входящее соединение TCP принято tcp_connect Подключение к удаленному хосту TCP Отправка данных через TCP tcp_write Записывает данные в очередь на отправку tcp_sent Назначает функцию обратного вызова, которая будет вызваться при подтверждении данных удаленным хостом tcp_output Принудительно отправляет данные в очередь Получение данных через TCP tcp_recv Назначает функцию обратного вызова, которая будет вызываться при поступлении новых данных tcp_recved Вызывается, когда приложение обработало входящий пакет данных Опрос приложений tcp_poll Назначает функции обратного вызова, которые будут вызываться периодически. Используется приложением для проверки того, имеются ли оставшиеся данные приложения, которые необходимо отправить, или существуют ли соединения, которые необходимо закрыть Закрытие и прерывание соединения tcp_close Закрывает TCP-соединение с удаленным хостом. tcp_err Назначает функцию обратного вызова для обработки соединений, прерванных LwIP из-за ошибок tcp_abort Прерывает TCP-соединение
Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 47 Таблица. 12. Описание RAW API UDP Netconn API Netconn API – высокоуровневый последовательный интерфейс, разработанный поверх RAW API. Этот интерфейс требует наличия операционной системы реального времени (RTOS) и поддерживает многопоточные операции. Таблица. 13. Описание Netconn API Функции API Описание netconn_new Создает новое соединение netconn_delete Удаляет существующее соединение netconn_bind Привязывает соединение к локальному IP-адресу и порту netconn_connect Присоединяется у удаленному IP-адресу и порту netconn_send Отправляет данные по подключенному в данный момент удаленному IP-адресу или порту netconn_recv Принимает данные от netconn netconn_listen Устанавливает TCP-соединение в режим прослушки netconn_accept Принимает входящее соединение в режиме прослушки TCP-соединения netconn_write Отправляет данные в подключенный TCP netconn Функции API Описание udp_new Создает новый UDP PCB udp_remove Удаляет UDP PCB udp_bind Привязывает UDP PCB к локальному IP-адресу и порту udp_connect Устанавливает UDP PCB к удаленному IP-адресу и порту udp_disconnect Удаляет IP-адрес и порт UDP PCB udp_send Отправляет данные через UDP udp_recv Определяет функцию обратного вызова, которая вызывается при получении данных
Быковский С.В., Ключев А.О., Кустарев П.В., Платунов А.Е. ФПИ и КТ университета ИТМО 48 netconn_close Закрывает TCP-соединение, не удаляя его Socket API Socket API – высокоуровневый интерфейс сокетов, разработанный поверх Netconn API. Этот интерфейс обеспечивает высокую переносимость написанных программ, потому что является стандартизированным API. Таблица. 14. Описание Socket API Функции API Описание soket Создает новый сокет bind Связывает сокет с IP-адресом и портом listen Прослушать соединения сокетов connect Соединяет сокет с удаленным IP-адресом и портом accept Принимает новое соединение на сокете read Читает данные из сокета write Записывает данные в сокет close Закрывает сокет (с удалением) Задание Необходимо реализовать на SDK-1.1M программу для обмена данными с компьютером, используя один из интерфейсов LwIP. |