Вопрос:
EFR32: Как управлять периферийными узлами микроконтроллеров EFR32, например, как помигать светодиодом?
Ответ:
Перед началом программирования периферийных узлов (ПУ) микроконтроллеров EFR32 необходимо вооружиться двумя техническими документами, которые называются Datasheet [1] и Reference Manual [2]. Первый документ выпускается производителем на каждый конкретный артикул. Он содержит перечень ПУ в микросхеме и дает привязку ПУ к конкретным выводам микросхемы. Детальное описание архитектуры и всех режимов работы ПУ можно найти в документах, которые называются Reference Manual и выпускаются на группу микроконтроллеров со сходными ПУ.
Чтобы упростить разработку конечного приложения Silabs предоставляет библиотеки (CMSIS, emlib), которые содержат набор необходимых переменных и стандартных функций для работы с периферийными узлами микрконтроллеров Silabs. Подробное описание всех функций можно найти в онлайн справочнике по emlib и CMSIS [3]. Использование бибилотек emlib и CMSIS позволяет избежать программирования на уровне регистров.
Работа с GPIO
Архитектура GPIO и режимы работы подробно описаны в Reference Manual [2]. Там можно найти информацию о возможных режимах работы каждого конкретного выхода микросхемы. Каждый выход GPIO можно сконфигурировать определенным образом, в зависимости от поставленной задачи. Наиболее часто используются следующие режимы работы:
– Настройка GPIO на вход или выход (Input Mode/Output Mode);
– Подтяжка GPIO к «земле» либо к «питанию» (Pull-Down, Pull-Up);
– Настройка комплементарного выхода (Push-Pull);
– Настройка выхода с открытым коллектором (Open Drain);
– Также возможно использование альтернативных функций (подключение к АЦП, ЦАП, UART и др.)

Рисунок 1 – Конфигурация GPIO.
Выводы GPIO объединены в несколько шестнадцатиразрядных портов. Каждый порт имеет буквенное обозначение (A,B,C и т.д.), а каждый вывод внутри порта обозначен цифрами, таким образом, выводы имеют обозначение вида PA1. Каждый вывод GPIO соответствует физическому выводу самой микросхемы, согласно Datasheet [1] (Например, выводу 26, микросхемы EFR32MG12, в корпусе QFN48, соответствует вывод GPIO – PA1).

Рисунок 2 – Выводы микроконтроллера EFR32MG12.
CMSIS (Cortex Microcontroller Software Interface Standard) – это независимый от производителя уровень аппаратной абстракции для серии ядер Cortex-M. CMSIS предоставляет последовательные и простые интерфейсы для ядра, его периферии и операционных систем реального времени.
Библиотека emlib – это низкоуровневая библиотека поддержки периферийных устройств для микроконтроллеров EFM32, EZR32 и EFR32 компании Silicon Laboratories. Библиотека содержит описание всех периферийных узлов для каждого конкретного микроконтроллера, основные функции для работы с ними и перечисления возможных режимов работы, которыми оперируют функции. В Таблице 1 содержится пример перечисления основных режимов работы GPIO.
Таблица 1 – Пример перечисления GPIO_Mode_TypeDef
Имя переменной
|
Описание
|
gpioModeInput
|
Настройка GPIO на вход
|
gpioModePushPull
|
Настройка комплементарного выхода
|
gpioModeWiredAnd
|
Настройка выхода с открытым коллектором
|
Например, если к выводу PA6 микроконтроллера подключена кнопка, и мы хотим опрашивать ее состояние, то необходимо сконфигурировать вывод соответствующим образом. В библиотеке emlib за это отвечает функция GPIO_PinModeSet(). Аргументами функции, в данном случае, будут являться порт A (gpioPortA), номер пина (6), а также необходимый режим конфигурации. Возможные режимы конфигурации GPIO описаны в перечислении GPIO_Mode_TypeDef. В данном случае, необходимо использовать настройку пина на вход (gpioModeInput). Таким образом, вызов функции будет выглядеть следующим образом:
GPIO_PinModeSet(gpioPortA,6, gpioModeInput, 1);
В демонстрационных проектах, для отладочных плат EFR32, в файле hal-config-board.h можно найти имена различных периферийных узлов и соответствующие им порты и пины.
Например, кнопка «BUTTON0» отладочной платы задана в этом файле следующим образом:
#define BSP_BUTTON0_PIN (6U)
#define BSP_BUTTON0_PORT (gpioPortF)
Таким образом, в демонстрационных проектах вместо порта и пина можно указывать конкретные имена узлов:
GPIO_PinModeSet(BSP_BUTTON0_PORT,BSP_BUTTON0_PIN, gpioModeInput, 1);
В демонстрационных проектах ZigBee и Thread, для настройки периферии можно использовать специальный инструмент Simplicity Studio – Hardware Configurator. Hardware Configurator представляет собой графический интерфейс, позволяющий быстро сконфигурировать необходимые периферийные узлы. Более подробную информацию об использовании Hardware Configurator можно найти в Simplicity Studio User's Guide [5]. Файл конфигурации можно найти в корневой папке демонстрационного проекта (<Название микроконтроллера>.hwconf).

Рисунок 3 – Интерфейс Hardware Configurator.
Некоторые периферийные узлы используются беспроводными стеками по умолчанию, и переконфигурировать их нельзя, например системные таймеры, регистры для работы с радиоканалом и др. Подробно они описаны в инструкции по разработке приложений [4], в разделе 7.
Важно, перед настройкой периферии, выполнить начальную инициализацию микроконтроллера. Для этого так же используются функции библиотеки emlib [3].
В демонстрационных проектах стандартные операции по инициализации периферии выполняются в следующих функциях:
· initMCU() – функция initMCU() используется для инициализации и запуска тактирования ядра микроконтроллера. Также, функция конфигурирует периферию внутри микросхемы (например, инициализация таймера). Эта функция вызывается в самом начале функции main();
· initBoard() – функция initBoard() используется для инициализации периферийных узлов, находящихся на плате, например, внешней Flash памяти, GPIO, UART и др. Функция должна быть вызвана после initMCU();
· initApp() – функция initApp() используется для инициализации специфических для приложения функций, таких как, например, включение SPI дисплея в отладочной плате. Функция должна быть вызвана после initBoard();
Помимо этого, в каждую из вышеперечисленных операций, разработчик может добавить необходимые ему функции инициализации.
Ниже представлен пример настройки и работы кнопок и светодиодов отладочной платы EFR32 Mighty Gecko:
void main(void)
{
// Начальная инициализация
initMcu();
initBoard();
GPIO_PinModeSet(BSP_LED0_PORT,BSP_LED0_PIN, gpioModePushPull, 1); // Настройка светодиода 0
GPIO_PinModeSet(BSP_BUTTON0_PORT,BSP_BUTTON0_PIN, gpioModeInput, 1); // Настройка кнопки 0
while (1) //Бесконечный цикл
{
// Если нажата кнопка 0 - зажечь светодиод 0, если нет - погасить
if(GPIO_PinInGet(BSP_BUTTON0_PORT,BSP_BUTTON0_PIN)==0) GPIO_PinOutClear(BSP_LED0_PORT,BSP_LED0_PIN);
else GPIO_PinOutSet(BSP_LED0_PORT,BSP_LED0_PIN);
}
}
Список использованных источников:
1. Описание микросхемы EFR32MG12:
https://www.silabs.com/documents/public/data-sheets/efr32mg14-datasheet.pdf;
2. Описание периферийных узлов EFR32MG12:
https://www.silabs.com/documents/public/reference-manuals/efr32xg12-rm.pdf;
3. Онлайн справочник по функциям библиотек emlib и CMSIS:
https://siliconlabs.github.io/Gecko_SDK_Doc;
4. Инструкция для разработки приложений на языке C:
UG136: Silicon Labs Bluetooth C Application Developer's Guide;
5. Руководство по разработке приложений в Simplicity Studio:
AN0822: Simplicity Studio User's Guide;