Научная статья на тему 'UGFX - ГРАФИЧЕСКАЯ БИБЛИОТЕКА ДЛЯ МИКРОКОНТРОЛЛЕРОВ. ЧАСТЬ 2'

UGFX - ГРАФИЧЕСКАЯ БИБЛИОТЕКА ДЛЯ МИКРОКОНТРОЛЛЕРОВ. ЧАСТЬ 2 Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
257
37
i Надоели баннеры? Вы всегда можете отключить рекламу.

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Курниц Андрей

Статья продолжает знакомить читателя с графической библиотекой uGFX. В предыдущей статье [1] было показано, как запустить библиотеку uGFX в среде настольной операционной системы Windows. В данной статье речь идет о запуске uGFX на ARM Cortex-M3 микроконтроллере, к которому подключен модуль цветного TFT-дисплея с контроллером ILI9341. Приводится оценка объема памяти, потребляемой библиотекой uGFX.

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

Текст научной работы на тему «UGFX - ГРАФИЧЕСКАЯ БИБЛИОТЕКА ДЛЯ МИКРОКОНТРОЛЛЕРОВ. ЧАСТЬ 2»

uGFX —

графическая библиотека для микроконтроллеров.

Часть 2

Андрей КУРНИЦ

kurnits@stim.by

Статья продолжает знакомить читателя с графической библиотекой uGFX. В предыдущей статье [1] было показано, как запустить библиотеку uGFX в среде настольной операционной системы windows. В данной статье речь идет о запуске uGFX на ARM Cortex-M3 микроконтроллере, к которому подключен модуль цветного TFT-дисплея с контроллером ILI9341. Приводится оценка объема памяти, потребляемой библиотекой uGFX.

Аппаратная часть

Микроконтроллер

Библиотека uGFX не накладывает никаких ограничений на используемый микроконтроллер [1] как по архитектуре, так и по разрядности. Однако надо понимать, что при проектировании устройства с графическим интерфейсом выбор слабого микроконтрол-

Рис. 1. Отладочная плата STM32VLDISCOVERY

лера, с малым объемом памяти программ и ОЗУ, может привести к ситуации, когда вся доступная память микроконтроллера будет исчерпана. Это связано с необходимостью хранения во флэш-памяти различных растровых графических образов (например, шрифтов), занимающих большой по меркам микроконтроллеров объем памяти. Кроме этого, ограничивающим фактором является быстродействие микроконтроллера, которого должно хватать для вывода графической информации без существенных временных задержек.

Выходом может стать хранение графических образов на внешнем относительно микроконтроллера носителе: микросхеме флэш-памяти или SD-карте памяти. Однако в этом случае появится проигрыш во времени доступа к записанным данным и, как следствие, задержка вывода графической информации существенно увеличится.

Целесообразно использовать достаточно мощный микроконтроллер и обойтись без дополнительных носителей информации. Автор использовал 32-разрядный микроконтроллер с ядром ARM Cortex-M начального уровня — STM32F100RB. Микроконтроллер имеет на борту 128 кбайт флэш-памяти и 8 кбайт ОЗУ, работает на частотах до 24 МГц.

Забегая вперед надо сказать, что ресурсов выбранного микроконтроллера оказалось недостаточно для проверки всех возможностей uGFX. Однако ничто не мешает в реальном проекте применить более мощный микроконтроллер с таким ядром. Самые совершенные образцы микроконтроллеров с ядром ARM Cortex-M имеют встроенную флэш-память объемом до 2 Мбайт, а ОЗУ — объемом до 256 кбайт. Быстродействие же достигает 225 млн операций в секунду на частоте в 180 МГц [2].

Для того чтобы упростить построение макета устройства, была выбрана отладочная плата STM32VLDISCOVERY [3]. Ее отличительными чертами являются:

• Микроконтроллер STM32F100RB — 32-битное ядро ARM Cortex-M3, 128 кбайт флэш-памяти, 8 кбайт ОЗУ, максимальная рабочая частота 24 МГц.

• Расположенный на плате программатор-отладчик ST-LINK, что позволяет обойтись без приобретения отдельного программатора.

• Все выводы микроконтроллера выведены на плату в виде однорядных разъемов с шагом 2,54 мм, что облегчает макетирование устройства.

• Питание по USB-шине позволяет обойтись без дополнительного блока питания. Внешний вид отладочной платы приведен

на рис. 1. Более подробно с данной отладочной платой можно ознакомиться в [4].

Дисплейный модуль

В качестве дисплейного модуля автор выбрал недорогой модуль азиатского производства, основанный на контроллере ILI9341. На модуль установлен цветной дисплей с диагональю 2,2 дюйма и разрешением 240x320 пикселей [5] (рис. 2). Надо сказать, что это максимально возможное разрешение для контроллера ILI9341.

Хотя контроллер ILI9341 фирмы Ilitek [6] имеет также параллельный интерфейс для подключения к микроконтроллеру, на плату модуля выведен лишь последовательный SPI-интерфейс.

С одной стороны, подключение по SPI-интерфейсу ограничит скорость передачи информации между микроконтроллером и графическим контроллером, а с другой — потребует гораздо меньше выводов микроконтроллера и, соответственно, соединительных линий.

Рис. 2. Дисплейный модуль

На плате дисплейного модуля присутствуют следующие выводы:

• VCC — напряжение питания модуля, +5 или +3,3 В;

• GND — общий провод («земля»);

• CS — выбор кристалла;

• RESET — сброс ILI9341 в исходное состояние;

• D/C — выбор типа передаваемой информации: данные, команда;

• SDI (MOSI) — последовательные данные из микроконтроллера в контроллер ILI9341;

• SCK — тактовый сигнал интерфейса SPI;

• LED — положительное напряжение подсветки дисплея;

• SDO (MISO) — последовательные данные из контроллера ILI9341 в микроконтроллер. Напряжение питания дисплейного модуля может составлять как +5 В, так и +3,3 В. Выбор производится с помощью перемычки J1 на плате модуля. Если перемычки нет, то должно подаваться напряжение +5 В, которое понижается до +3,3 В стабилизатором, установленным на плате модуля. Важно, чтобы логические уровни на выводах SCK, SDI (MOSI), CS, RESET и D/C были 3,3 В.

Подключение дисплейного модуля

Очевидно, что SPI-интерфейс графического контроллера ILI9341 (выводы SDI (MOSI), SCK и SDO (MISO)) должен быть подключен к аппаратному SPI-интерфейсу микроконтроллера STM32F100RB. Микроконтроллер содержит два SPI-интерфейса: SPI1 и SPI2. Выбираем интерфейс SPI1, чьи сигналы соответствуют выводам PA5, PA6, PA7 микроконтроллера.

Позднее необходимо будет внести некоторые изменения в файл поддержки платформы (board file) так, чтобы uGFX при записи информации в ILI9341 обращалась именно к интерфейсу SPI1 микроконтроллера.

Для подключения выводов CS, RESET, D/C, которые управляют процессом передачи ин-

формации и состоянием контроллера ILI9341, можно использовать любые выводы общего назначения (GPIO) микроконтроллера. Автор использовал выводы PC6, PC7, PC8 (рис. 3).

Опять-таки, в файле с исходным кодом драйвера выводы PC6, PC7, PC8 необходимо соответствующим образом настроить и обеспечить к ним доступ со стороны uGFX.

Номинал резистора R1 подобран так, чтобы обеспечить ток через светодиоды подсветки дисплея порядка 60 мА.

Программная часть

Стоит задача запустить одно из демонстрационных приложений uGFX на данной аппаратной платформе. Причем, чтобы не вникать в особенности какой-либо операционной системы из списка поддерживаемых uGFX, было принято решение использовать uGFX без операционной системы вообще.

Программное обеспечение

Итак, имеем ARM Cortex-M3 микроконтроллер, к которому по интерфейсу SPI подключен графический контроллер ILI9341. Также имеем библиотеку uGFX, представленную в исходных кодах (автор использовал версию 2.1 от 19.06.2014). Теперь необходимо выбрать и настроить программное обеспечение для сборки пробного приложения и его загрузки во флэш-память выбранного микроконтроллера. Подразумевается, что на рабочей машине установлена операционная система Windows.

В качестве программного обеспечения для сборки и прошивки приложения хорошо подходит бесплатная интегрированная среда разработки CooCox CoIDE [7] в связке с компилятором GNU GCC для микроконтроллеров ARM Cortex-M [8].

Основные достоинства CooCox IDE:

• Среда разработки, специально созданная для микроконтроллеров ARM Cortex.

• Основана на популярной среде Eclipse, полностью бесплатна.

• Поддержка множества ARM Cortex-M микроконтроллеров таких фирм, как ST, Atmel, NXP, Freescale, TI и др., в том числе и выбранного STM32F100RB.

• Поддержка множества программаторов-отладчиков, в том числе и ST-LINK, установленного на выбранной плате STM32VLDISCOVERY.

• Удобная сборка, прошивка и отладка программы.

• Встроенные библиотеки для работы с периферией микроконтроллеров (например, CMSIS — библиотека для всего семейства ARM Cortex-M и ST Standard Peripherals Library — библиотека, созданная компанией STMicroelectronics для поддержки своих микроконтроллеров).

Недостаток среды CooCox CoIDE — отсутствие поддержки Make-файлов, активно используемых в библиотеке uGFX, следовательно, придется подготовить библиотеку uGFX для работы в среде CoIDE.

Настройка среды разработки

Необходимо загрузить последнюю версию CooCox CoIDE с официального сайта [7] и установить в любой каталог на диске, например в c:\CooCox\CoIDE\. Автор работал с версией CooCox CoIDE 1.7.7. В состав CooCox CoIDE не входит компилятор, поэтому до создания проекта компилятор необходимо скачать и установить отдельно.

Рекомендуется использовать официальный компилятор от компании ARM — ARM GCC, хотя возможно применение и других GCC-компиляторов, например CodeSoucery GCC. Скачать компилятор ARM GCC можно по адресу [8]. Автор использовал версию 4.8 от 2014.06.09. Рекомендуется скачать установщик для Windows (название файла, который скачивал автор: gcc-arm-none-eabi-4_8-2014q2-20140609-win32.exe), после чего выполнить установку компилятора. Образец пути установки: c:\Program Files (x86)\GNU Tools ARM Embedded\4.8 2014q2\.

Рис. 4. Настройка библиотек в среде CoIDE

После того как компилятор GCC установлен, следует в настройках CooCox CoIDE указать путь к нему, чтобы среда разработки могла с его помощью собирать проекты. Для этого нужно запустить CooCox CoIDE, выбрать пункт меню Project — Select Toolchain Path и ввести путь к ранее установленному ARM GCC-компилятору, например, так: C:\Program Files (x86)\GNU Tools ARM Embedded\4.8 2014q2\bin.

Далее можно создать пустой проект и убедиться, что он успешно собирается. Для этого следует выбрать пункт меню Project — New Project и ввести название проекта, например ugfx_stm32. Далее будет предложено выбрать тип микроконтроллера, следует выбрать ST — STM32F100x — STM32F100RB. После выбора типа микроконтроллера среда создаст каталог с названием, соответствующим названию проекта: c:\CooCox\CoIDE\workspace\ugfx_stm32\.

После этого среда CoIDE откроет вкладку Repository, где предложит выбрать компоненты библиотек CMSIS и Standard Peripherals Library, необходимые прикладной программе для обращения к аппаратуре микроконтроллера так, как описано ниже.

В разделе COMMON нужно выбрать пункты C Library и CMSIS core. В разделе BOOT — CMSIS Boot. В разделе PERIPHERAL.ST — пункты RCC, GPIO, SPI, MISC (рис. 4). Выбор пунктов приводит к появлению соответствующих каталогов и исходных файлов в каталоге проекта.

Пункты RCC, GPIO, SPI, MISC раздела PERIPHERAL.ST предписывают использование соответствующих частей библиотеки Standard Peripherals Library. Для того чтобы

в работе не возникло препятствий, следует отредактировать файл stm32f10x_conf.h в каталоге \ugfx_stm32\cmsis_boot. В файле надо убрать комментарий со строк, соответствующих применяемым частям Standard Peripherals Library:

#include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_spi.h" #include "misc.h"

Далее можно проверить сборку пустого проекта — выбрать пункт меню Project — Build. Сборка должна завершиться без ошибок.

Если выбрать пункт меню Flash — Program Download, то полученная прошивка должна загрузиться во флэш-память микроконтроллера. При этом плата STM32VLDISCOVERY должна быть подключена к рабочей машине через USB. Таким образом, можно проверить правильность соединений и настроек программатора/отладчика (по умолчанию должен быть выбран ST-LINK, и никаких дополнительных настроек не требуется).

Адаптация библиотеки uGFX

К сожалению, при всем своем удобстве среда CooCox CoIDE не поддерживает Make-файлы, широко применяемые в библиотеке uGFX. Вместо этого CoIDE использует собственные форматы для хранения информации об исходных файлах, подлежащих обработке, и правилах этой обработки.

Поэтому для совместного использования CooCox CoIDE и uGFX придется один раз проделать рутинную работу по ручному добавлению файлов библиотеки в проект на CooCox CoIDE.

-DJugli] J (_ |dmofs| '¡Litgdfep]

■ U|snc|

.[gatfc]

U Maudio]

- i'j[gdfcp]

,_11ПКЛ11 Qfl 11

■J [gemenl]

. [ginpul]

оаоч D [gqueue] UMIimoti . j[gwin]

Рис. 5. Структура каталогов необходимой части uGFX

В каталог проекта CoIDE (в нашем случае c:\CooCox\CoIDE\workspace\ugfx_stm32\) необходимо скопировать часть библиотеки uGFX так, чтобы каталог проекта содержал подкаталог ugfx с внутренней структурой, показанной на рис. 5.

Копировать следует только файлы с исходным кодом (расширения *.c и *.h). В каталог \ugfx\src\gos\ можно не копировать файлы, нужные при использовании операционных систем (ChibiOS, FreeRTOS и т. д.). Необходимо и достаточно скопировать файлы gfx_raw32.c, gfx_raw32.h, sys_defs.h, sys_options.h, sys_rules.h из соответствующего каталога дистрибутива uGFX.

Теперь можно добавить все исходные файлы uGFX в проект CoIDE. Предварительно надо создать структуру проекта, соответствующую структуре каталогов (рис. 5). Для этого в окне Project, содержащем дерево проекта, надо вызвать контекстное меню (щелчок правой кнопкой мыши по названию проекта ugfx_stm32) и выбрать пункт Add Group. Далее ввести название создаваемой группы в соответствии с именем каталога, это будет ugfx (рис. 5). Таким же образом создать все подгруппы в соответствии с рис. 5. Затем каждую группу следует наполнить файлами, выбирая пункт контекстного меню Add Files и выбирая файлы *.c и *.h из соответствующего по названию каталога.

Файлы из каталога \ugfx\src\gdisp\fonts\ добавлять в проект не следует, иначе возникнут ошибки компоновки при сборке приложения, работающего со шрифтами. Файлы из каталога \ugfx\src\gdisp\fonts\ включаются в сборку из исходных файлов с помощью инструкций #include.

Написание файла платформы

В составе uGFX уже имеется файл платформы для контроллера ILI9341, подключенного по интерфейсу SPI. Файл называется board_ILI9341_spi.h и находится в каталоге \ugfx\boards\addons\gdisp\. Однако при его анализе выяснилось, что он подходит

только для операционной системы ChibiOS. Автор же выбрал вариант без операционной системы, поэтому файл платформы board_ ILI9341_spi.h пришлось переписать. При этом для инициализации периферии использовалась библиотека Standard Peripherals Library, ранее включенная в проект средствами CoIDE.

Структура библиотеки uGFX подразумевает, что файлы платформы должны находиться в каталоге \ugfx\boards\addons\gdisp\, однако в целях упрощения структуры файлов проекта автор поместил файл платформы в каталог с драйвером контроллера ILI9341: \ugfx\drivers\gdisp\ILI9341\.

Анализ файла платформы выявил, что следующие функции нуждаются в реализации:

1) void init_board(Gdisplay *g) — отвечает за инициализацию периферии микроконтроллера, в нашем случае это SPI1 и порты GPIOA и GPIOC. Вызывается во время инициализации библиотеки uGFX API-функцией gdispInit ().

2) voidsetpin_reset(Gdisplay *g, bool_tstate) — должна устанавливать вывод RESET в состояние, заданное своим аргументом state.

3) void wr it e _in d ex (Gd isp lay *g, uint16_t index) — должна передавать в ILI9341 адрес регистра или адрес в видеопамяти, куда будет осуществляться дальнейшая запись.

4) void write_data(Gdisplay *g, uint16_t data) — должна осуществлять запись по адресу, предварительно установленному функцией write_index(). Содержимое переписанного файла board_

ILI9341_spi.h (в целях экономии размера статьи опущены функции, содержащие пустые тела, и комментарии):

/* Настройка SPI1. */

SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPIJnitStmcture.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; SPIJnitStmcture.SPI_CPHA = SPI_CPHA_1Edge; SPIJnitStmcture.SPI_CPOL = SPI_CPOL_Low; SPIJnitStmcture.SPI_NSS = SPI_NSS_Soft; SPIJnitStmcture.SPI_DataSize = SPI_DataSize_8b; SPIJnitStmcture.SPI_FirstBit = SPI_FirstBit_MSB; SPIJnitStmcture.SPI_CRCPolynomial = 7;

SPI_Init(SPI1, &SPIJnitStmcture);

/* Разрешить работу SPI1. */ SPI_Cmd(SPI1, ENABLE);

}

static inline void setpin_reset(GDisplay *g, bool_t state) { (void) g;

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

if (state == TRUE) {

GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_RESET); } else {

GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_SET);

}

}

static inline void send_data(uint16_t data) {

/* Ожидать окончания предыдущей передачи, если она идет. */ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); /* Передать младший байт data */ SPI_I2S_SendData(SPI1, data);

}

static inline void write_index(GDisplay *g, uint16_t index) { (void) g;

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); /* Вывод CS — высокий уровень. */ GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET); /* Вывод D/C — низкий уровень. */ GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET); /* Вывод CS — низкий уровень. */ GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET); /* Передать адрес */ send_data(index);

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); /* Вывод D/C — высокий уровень. */ GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);

}

static inline void write_data(GDisplay *g, uint16_t data) { (void) g;

send_data(data);

}

#endif /* _GDISP_LLD_BOARD_H */

Для обмена с контроллером ILI9341 интерфейс SPI1 микроконтроллера настроен следующим образом:

• Режим работы — мастер.

• Тактовый сигнал SCK — в промежутках между передачами низкий уровень, стро-бирование данных по первому перепаду.

• Размер передаваемого слова — 8 бит.

• Последовательность передачи бит — старшим битом вперед.

Реализация функции send_data() — передача байта данных по SPI — выполнена самым компактным по размеру кода способом (используется опрос состояния SPI-контроллера в бесконечном цикле). Однако такая реализация является неэффективной с точки зрения затрат процессорного времени. В целях повышения эффективности в реальном проекте следует буферизировать запись или использовать контроллер прямого доступа к памяти DMA.

Адаптация модуля Gos

В случае когда библиотека uGFX работает под операционной системой, она вызывает ряд API-функций данной операционной системы, например API-функцию для приоста-

новки выполнения программы (или потока) на заданное количество миллисекунд.

В случае когда uGFX работает без операционной системы, возникает задача адаптировать модуль GOS к периферии выбранного микроконтроллера.

Задача адаптации сводится к следующему:

• Организовать отсчет равных временных интервалов — тиков.

• Организовать счетчик этих тиков и функцию, возвращающую значение этого счетчика.

• Реализовать функцию для перевода заданного количества миллисекунд в количество тиков.

В нашем случае используется микроконтроллер с архитектурой ARM Cortex-M3, особенностью всех микроконтроллеров с такой архитектурой (даже от разных производителей) является наличие специального 24-битного таймера/счетчика SysTick, который идеально подходит для нашей задачи.

uGFX измеряет временные промежутки в миллисекундах, поэтому целесообразно выбрать период тиков так, чтобы он был кратен одной миллисекунде. Выберем период тиков равным одной миллисекунде.

Итак, таймер SysTick должен отсчитывать время, равное одной миллисекунде, после чего счетчик тиков должен увеличиться на единицу.

Адаптация модуля GOS сводится к реализации следующих функций в файле \ugfx\src\gos\gfx_raw32.c:

• void_goslnit(void) — сюда следует добавить дополнительную функциональность: инициализацию таймера SysTick;

• void sysTick_Handler(void) — обработчик прерывания от таймера SysTick, в котором должен инкрементироваться счетчик тиков;

• systemticks_t gfxsystemticks(void) — функция должна возвращать текущее значение счетчика тиков;

• systemticks_t gfxMillisecondsto ticks(delayt ime_t ms) — функция должна переводить заданное время в миллисекундах в количество тиков.

Изменения в файле gfx_raw32.c: /* ... */

#include "stm32f10x.h" /* ... */

/* MsTickCounter — счетчик тиков */ static systemticks_t MsTickCounter; /* SystemCoreClock — частота тактирования в МГц */ extern uint32_t SystemCoreClock;

/* ... */

void _gosInit(void) {

/* ... */

/* Настроить тактирование микроконтроллера. */ SystemInit();

/* Записать действующую частоту тактирования в SystemCoreClock */

SystemCoreClockUpdate();

/* Конфигурация таймера SysTick. Разрешение прерывания от него. */

/* 1/1000 секунды — интервал срабатывания прерывания от таймера SysTick. */

#ifndef _GDISP_LLD_BOARD_H #define _GDISP_LLD_BOARD_H

#include "stm32f10x.h"

static void send_data(uint16_t data);

static inline void init_board(GDisplay *g) {

g->board = 0;

/* Структуры для инициализации SPI и GPIO. */ SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;

/* Включить тактирование контроллера SPI1, портов GPIOA и GPIOC. */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

/* Инициализация выводов PA5, PA6, PA7 порта GPIOA, куда выведен интерфейс SPI1. */

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 I GPIO_Pin_6 I GPIO_Pin_7; GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Инициализация выводов PC6, PC7, PC8 порта GPIOC. */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 I GPIO_Pin_7 I GPIO_Pin_8; GPIO_Init(GPIOC, &GPIO_InitStructure);

/* Структуру SPI_InitStructure — в исходное состояние. */ SPI_StructInit(&SPI_InitStructure);

SysTick_Config(SystemCoreClock / 1000); /* ... */

}

/* ... */

/* Обработчик прерывания от таймера SysTick */ void SysTick_Handler(void) { /* Инкремент счетчика тиков */ MsTickCounter++;

}

systemticks_t gfxMillisecondsToTicks(delaytime_t ms) { return ms;

systemticks_t gfxSystemTicks(void) { return MsTickCounter;

/* ... */

Функция systemlnitO является частью библиотеки CMSIS, ее реализация находится в файле \ugfx_stm32\cmsis_boot\system_ stm32f10x. c. Функция настраивает тактирование микроконтроллера так, чтобы при подключенном внешнем кварцевом резонаторе на 8 МГц (как на плате STM32VLDISCOVERY) системная частота составляла 24 МГц.

Функция systemCoreClockupdate() — также часть библиотеки CMSIS. Она устанавливает значение глобальной переменной systemCoreClock равным действующей системной частоте тактирования. Значение этой частоты необходимо для правильной конфигурации таймера SysTick.

Функция sysTick_Config() инициализирует таймер SysTick, запускает его и разрешает прерывание от него. При этом период срабатывания прерывания устанавливает равным количеству периодов системной частоты, заданному своим аргументом. Если задать аргумент равным системной частоте, то срабатывания будут раз в секунду. Соответственно аргумент SystemCoreClock/1000 предписывает задать прерывания раз в миллисекунду.

Статическая переменная MstickCounter — это счетчик тиков, его значение увеличивается на 1 внутри прерывания от таймера SysTick. Таймер SysTick настроен так, чтобы на заданной частоте тактирования прерывание от него срабатывало каждую миллисекунду. Таким образом, MsTickCounter является счетчиком миллисекунд.

Функция gfxsystemticks() просто возвращает значение счетчика MsTickCounter. А функция gfxMШisecondsToTicks(), которая должна переводить время, заданное в миллисекундах, в количество тиков, просто возвращает свой аргумент.

При компиляции проекта выявились ошибки, связанные с тем, что в файле gfx_raw32.h переопределяются типы данных (size_t, int8_t, uint32_t и др.) из стандартной библиотеки языка С. Чтобы обойти эту проблему, следует добавить в начало файла gfx_raw32.h строки:

Адаптация драйвера 1Ы9341

В процессе компиляции проекта выяснилось, что драйвер графического контроллера Ш9341 — файл \ugfx\drivers\gdisp\ILI9341\gdisp_lld_ILI9341.c также нуждается в небольшой доработке. Дело в том, что для организации временных задержек в этом файле используется вызов функции chThdSleepMiШsecondsO, являющейся частью операционной системы ChibiOS (сказывается то, что ранее uGFX была частью ChibiOS).

Наиболее простой путь обойти эту проблему — заменить вызовы функции chThdSleepMiШseconds() на вызовы gfxSleepMШiseconds().

запуск демонстрационного проекта

Теперь можно собирать демонстрационное приложение из дистрибутива uGFX. Пусть это будет вывод графиков функций средствами модулей GWIN и GDISP. Для этого следует в рабочую папку проекта (\ugfx_stm32V в нашем случае) скопировать из каталога \ugfx\demos\modules\gwin\graph\ файл, содержащий непосредственно код приложения, — тат.с и файл конфигурации библиотеки uGFX — gfxconf.h. Далее файлы тат.с и gfxconf.h следует добавить в проект в среде СоГОЕ, как было описано выше.

Затем нужно сконфигурировать uGFX для работы без операционной системы, для чего в файл gfxconf.h следует добавить строчку:

#define GFX_USE_OS_RAW32 TRUE

Сборка проекта должна пройти без ошибок. Далее следует записать полученный образ прошивки во флэш-память микроконтроллера. Для этого при подключенной по USB плате STM32VLDISCOVERY надо выбрать пункт меню Flash ^ Program Download.

После этого, если все сделано правильно, на экране должен появиться логотип uGFX, а спустя мгновение — двумерный график функции, нарисованный с помощью окна Graph, созданного средствами модуля GWIN (рис. 6).

По умолчанию дисплей выводит изображение в портретной ориентации. Можно развернуть изображение в альбомную ориентацию, выполнив следующее.

В файле gfxconf.h надо разрешить управление изображением с помощью API-функций, добавив строку:

#define GDISP_NEED_CONTROL TRUE

В файл main.cпосле вызова gfxlnit() следует добавить строку:

gdispSetOrientation(GDISP_ROTATE_LANDSCAPE);

Драйвер ILI9341 поддерживает поворот изображения, драйверы других контроллеров могут и не иметь такой функции.

Потребление памяти

Интересно оценить объем памяти, потребляемой библиотекой uGFX. Это можно сделать, выполнив сборку различных демонстрационных проектов из состава uGFX, определяя размер получаемых двоичных файлов прошивки. Размер файла прошивки в байтах выводит компилятор GCC в окне Console в среде CoIDE. В таблице приведено потребление памяти для различных демонстрационных проектов.

Компилятор ARM GCC позволяет оптимизировать получаемый файл прошивки. В таблице приведены полученные размеры прошивок для двух случаев — компиляция без оптимизации (опция компилятора -O0) и с оптимизацией по размеру файла (опция -Os).

#include <stdint.h> #include <stddef.h>

Таблица. Потребление памяти программ библиотекой uGFX

Демонстрационное приложение Путь Объем памяти программ, байт

Без оптимизации (-00) Оптимизация по размеру кода (-Os)

Окно Graph — двумерный график \demos\modules\gwin\graph\ 27 388 21 328

Отображение текстовых строк двумя различными шрифтами высотой 10 и 11 пикселей. Шрифты хранятся в памяти программ \demos\modules\gdisp\fonts\ 32 452 26 544

Полноценный графический интерфейс пользователя \demos\modules\gwin\widgets\ 75 724 5 0 084

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

Надо отметить, что автор не получил работающее приложение с полноценным графическим интерфейсом пользователя (таблица) по причине нехватки памяти ОЗУ (у выбранного микроконтроллера всего 8 кбайт).

Результаты, приведенные в таблице, подтверждают сказанное в начале статьи о необходимости выбора микроконтроллера с достаточно большими объемами памяти. При этом объемы памяти, указанные в таблице, — отправная точка, в реальном приложении дополнительная память потребуется как на само приложение, так и на хранение растровых графических объектов (например, шрифтов). Память ОЗУ также будет расходоваться на создание каждого графического элемента (окно, кнопка, консоль и т. п.).

Выводы

Библиотека uGFX оказалась действительно платформенно независимой. По усмотрению автора был выбран микроконтроллер, дисплейный модуль с графическим контроллером из списка поддерживаемых, которые были произвольным образом соединены между

собой. Библиотеку uGFX удалось адаптировать к данной аппаратной платформе и запустить приложение, ее использующее.

Адаптация библиотеки uGFX к выбранной аппаратной платформе все-таки требует определенных усилий, однако эта работа выполняется только один раз в самом начале и впоследствии программист не возвращается к низкоуровневым функциям, работающим с аппаратурой, а оперирует высокоуровневыми API-функциями.

Библиотека uGFX испытывает сильное влияние операционной системы ChibiOS, частью которой она являлась ранее. Это относится к драйверам и файлам платформы. Такая ситуация может потребовать дополнительных усилий по адаптации uGFX при ее использовании на операционных системах, отличных от ChibiOS.

Из данных, приведенных в таблице, следует, что uGFX для работы на 32-разрядном микроконтроллере требуется не менее 22 кбайт памяти программ. А памяти ОЗУ размером 8 кбайт оказалось недостаточно, чтобы задействовать все возможности uGFX. ■

Литература

1. Курниц А. uGFX — графическая библиотека для микроконтроллеров // Компоненты и технологии. 2014. № 10.

2. http://www.st.com/web/en/catalog/mmc/SC1169/SS1577

3. http://www.st.com/web/en/catalog/tools/FM116/SC959/SS1532/ PF250863?sc=stm32-discovery#

4. Курниц А. STM32 Discovery — стартовый набор разработчика ARM Cortex-M3 со встроенным программатором // Современная электроника. 2011. № 6.

5. http://www.alibaba.com/product-detail/Wholesale-1PC-2-2-Inch-240_ 1671643976.html

6. http://www.newhavendisplay.com/app_notes/ILI9341.pdf

7. http://www.coocox.org/CooCox_CoIDE.htm

8. https://launchpad.net/gcc-arm-embedded/+download

Honeywell

А

EPCOS

SICK

|ЮИ|

ТЕ

■mnffntn

Panasonic

jnmicorr

umi-T

источники Питания

>п

■'

Генераторы серии Ав Омгоп - это 2-канальные многофункциональные генераторы 2-в-1: генераторы сигналов произвольной формы и функциональные генераторы.

Модели с суффиксом -Г имеют встроенный частотомер.

Существует оборудование, тестирование которого невозможно до тех пор, пока на него не будет подан внешний сигнал. Для таких целей используются генераторы сигналов.

* Два канала

* Частота выходного сигнала от 1 мкГц до 60 МГц

* Частота дискретизации 250 Мвыб./с с разрешением 1 мкГц

* 5 базовых форм сигналов и 45 встроенных сигналов произвольной формы

* Сигнал произвольной формы: 1 М точек

* Функции модуляции: AM, ЧМ, ФМ, ШИМ, ЧМн, развертка и пакетный импульс

* Встроенный высокоточный частотомер: 100 мГц-200 МГц

www.platan.ru

ПЛАТАН

Офисы в Москве: м. Молодежная, ул. Ивана Франко, 40, стр. 2, (495) 97 ООО 99, platan@aha.ru; м. Электрозаводская, ул. Б. Семеновская, АО, стр. 26, БЦ Агат, (495) 744 70 70, platan@platan.ru Офис в Санкт-Петербурге: ул. Зверинская, 44, (812) 232 88 36, baltika@platan.spb.ru

i Надоели баннеры? Вы всегда можете отключить рекламу.