Главная » Микроконтроллеры » Библиотеки CMSIS для STM32

Библиотеки CMSIS для STM32

Работа непосредственно с 32-битными регистрами микроконтроллеров является не легкой задачей. Хотя можно написать приложение с использованием имен реестров, однако внесение изменений в существующую программу даже через короткий промежуток времени сопряжено с большими трудностями.

По этой причине разработчики все чаще используют предопределенные функции, которые выполняют операции над командами из многих регистров. Производитель предоставляет полные библиотеки в соответствии со стандартом CMSIS (Cortex Microcontroller Software Interface Standard — стандарт программного обеспечения для микроконтроллеров Cortex) для микроконтроллеров STM32 и других, оснащенных ядром Cortex-M3.

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

Структура интерфейса CMSIS и его место в приложении показано на рис1.

Структура интерфейса CMSIS

Рис. 1. Конструкция интерфейса CMSIS и его место в приложении

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

Кроме того, вышеупомянутые уровни были расширены производителями микроконтроллеров, которые участвовали в создании CMSIS двумя «уровнями»: уровень доступа к периферийным устройствам и функции доступа для периферийных устройств.

CMSIS для STM32

Библиотека стандартных периферийных устройств STM32F10x v3.1.0 (StdPeriph_Lib) была написана в соответствии с форматом Doxygen, что значительно упрощает процесс создания документации и ее использования. Вся документация для этой библиотеки была включена в файл справки, а не в том виде, в котором она ранее применялась STMicroelectronics в отдельном PDF файле. Новый тип документации облегчил просмотр ее содержимого и поиск информации.

Вместе с архивом библиотеки StdPeriph_Lib мы получаем шаблоны проектов для трех самых популярных компиляторов: IAR, Keil и ARM-GCC.

Структура файлов проекта, например, с использованием аналого-цифрового преобразователя, построенного на основе шаблона проекта для среды uVision, показана на рис. 2:

шаблона проекта для среды uVision

Рис. 2. Файловая структура среды uVision для проекта с использованием аналого-цифрового преобразователя

Если шаблон проекта копируется в текущий каталог, то компилятор должен быть проинформирован о том, где искать соответствующие файлы, и используемые источники должны быть добавлены в проект. Мы делаем это в среде uVision, щелкая правой кнопкой мыши на имени проекта и выбирая опцию Manage Component из контекстного меню (рис. 2). Затем мы находим нужные файлы на диске и добавляем их.

Как упоминалось выше, для правильной компиляции проекта необходимо обновить места (пути), где компилятор будет искать заголовочные файлы * .h. Для этого выберите меню Project / Options for Target …, после чего откроется окно, в котором на вкладке C / C ++ редактируем путь для поиска файлов заголовков.

Структура библиотеки

Файлы в библиотеке разделены на два блока (модули), расположенных в каталогах \ STM32F10x_StdPeriph_Driver и \ CMSIS. Дерево  каталогов модуля CMSIS Стандартной периферийной библиотеки показаны на рис. 3, а дерево STM32F10x_StdPeriph_Driver на рис. 4.

Структура модуля CMSIS

Рис. 3. Структура модуля CMSIS

Структура модуля STM32F10x_StdPefriph_Driver

Рис. 4. Структура модуля STM32F10x_StdPefriph_Driver

Отдельные файлы запуска подготовлены для каждого из подсемейств микроконтроллеров STM32 . В табл. 1 показано, какой файл запуска использовать с каким подсемейством STM32. Мы получаем три набора файлов запуска вместе с библиотекой API — для трех самых популярных компиляторов: Keil (ARM), IAR и GCC. 

Таблица 1. Стартовые файлы для подсемейства STM32

Стартовые файлы для подсемейства STM32Файл system_stm32f10x.c содержит определения и функции, которые можно использовать для настройки тактового сигнала микроконтроллера. При использовании функций, содержащихся в файле, сначала выберите, используя комментарии, как часто должен работать MCU.

Фрагмент, который необходимо отредактировать для этой цели, показан в примере 1. В коде приложения достаточно вызвать функцию SystemInit () и настроит все тактовые сигналы (системные часы, HCLK, PCLK2, PCLK1).

Пример 1. Фрагмент файла system_stm32f10x.c -f определения тактовой частоты системы, используемые функцией SystemInit ()

/ * #define SYSCLK_FREQ_HSE HSE_Value * /
/ * #define SYSCLK_FREQ_24MHz 24000000 * /
/ * #define SYSCLK_FREQ_36MHz 36000000 * /
/ * #define SYSCLK_FREQ_48MHz 48000000 * /
/ * #define SYSCLK_FREQ_56MHz 56000000 * /
#define SYSCLK_FREQ_72MHz 72000000

Модуль STM32F10x_StdPeriph_Driver включает в себя файлы, которые, согласно их названию, содержат функции API, связанные с отдельными периферийными устройствами — см. Рис. 4. Эти библиотечные файлы редактировать не следует.

К каждому проекту прикреплены два важных файла: stm32f10x_conf.h и stm32f10x_it.c. В первом заголовочном файле мы включаем или отключаем (посредством комментариев) присоединение заголовочных файлов из модуля STM32F10x_StdPeriph_Driver -f к проекту, см. Пример 2.

Пример 2. Область файла stm32f10x_conf.h, где комментарии включают или отключают вложение заголовочных файлов.

/ * #include "stm32f10x_adc.h" * /
/ * #include "stm32f10x_bkp.h" * /
/ * #include "stm32f10x_can.h" * /
/ * #include "stm32f10x_crc.h" * /
/ * #include "stm32f10x_dac.h" * /
/ * #include "stm32f10x_dbgmcu.h" * /
#include "stm32f10x_dma.h"
/ * #include "stm32f10x_exti.h" * /
/ * #include "stm32f10x_flash.h" * /
/ * #include "stm32f10x_fsmc.h" * /
#include "stm32f10x_gpio.h"
/ * #include "stm32f10x_i2c.h" * /
/ * #include "stm32f10x_iwdg.h" * /
/ * #include "stm32f10x_pwr.h" * /
#include "stm32f10x_rcc.h"
/ * #include "stm32f10x_rtc.h" * /
/ * #include "stm32f10x_sdio.h" * /
#include "stm32f10x_spi.h"
/ * #include "stm32f10x_tim.h" * /
/ * #include "stm32f10x_usart.h" * /
/ * #include "stm32f10x_wwdg.h" * /
/ * # Включите "misc.h" * /

С точки зрения программиста, одним из наиболее важных файлов является stm32f10x_it.c, в который помещены все функции обработки прерываний. Его слегка модифицированный фрагмент с пустыми функциями показан, например, 3.

Как видите, это набор пустых функций, которые вызываются при возникновении соответствующего прерывания. По сравнению с версией этого файла, предоставленной STMicroelectronics, комментарии, которые были показаны здесь как избыточные, были удалены. Название сервисной функции прерывания уже само по себе имеет смысл. В результате был получен более лаконичный код без потери читабельности.

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

Пример 3. Фрагмент файла stm32f10x_it.c

void UsageFault_Handler (void)
{
while (1)
{};
};
void SVC_Handler (void)
{
};
void DebugMon_Handler (void)
{
};
void PendSV_Handler (void)
{
};
void SysTick_Handler (void)
{
};

Конфигурация периферийных устройств

Отдельные типы данных создаются для каждого устройства независимо от того, является ли оно GPIO, контроллером прерываний или любым другим элементом системы. Для портов ввода / вывода они называются: GPIO_TypeDef и тип GPIO_InitTypeDef, используемый для инициализации. Для программиста начальный тип является наиболее важным, потому что это переменная этого типа, которую мы явно создаем в написанном коде.

Тип GPIO_TypeDef обеспечивает доступ к отдельным регистрам микроконтроллера и используется главным образом функциями API, в то время как переменная типа GPIO_InitTypeDef должна существовать в каждом приложении, которое использует порты ввода / вывода, поскольку оно используется для инициализации и настройки портов. В примере 4 указана ключевая часть кода, отвечающего за GPIOB порта конфигурации.

Пример 4. Использование API — настройка порта GPIOB

// PINs PB8, PB9 как двухтактные выходы
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz;
GPIO_Init (GPIOB, & GPIO_InitStructure);

Переменная GPIO_InitStructure, созданная в начале, является структурой. Инициализация выводов или, в особом случае, всего порта выполняется таким образом, что программист заполняет поля структуры, а затем передает адрес переменной, подготовленный таким образом, в функцию инициализации.

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

Затем мы устанавливаем максимальную скорость, с которой выводы смогут работать. Подготовленная таким образом переменная должна быть передана путем ввода ее адреса в аргументе в инициирующую функцию GPIO_Init (). Вторым аргументом, передаваемым функции, является имя порта, к которому должны применяться выбранные параметры.




Добавить комментарий


.