Подписаться на получение новых статей на почту:

STM32F3 Discovery. Архитектура и библиотеки (CMSIS, SPL, HAL). Шаг №79

Всем привет. Как Вы помните в прошлой статье мы настроили программный комплекс для работы с микроконтроллерами STM32 и скомпилировали первую программу. В этой записи познакомимся с архитектурой данной платы, микроконтроллера и имеющиеся библиотеки для работы.

Ниже представлен рисунок платы STM32F3 Discovery, где: 1 — MEMS датчик. 3-осевой цифровой гироскоп L3GD20. 2 — МЕМС система-в-корпусе, содержащая 3-осевой цифровой линейный акселерометр и 3-осевой цифровой геомагнитный сенсор LSM303DLHC. 4 – LD1 (PWR) – питание 3.3V. 5 – LD2 – красный/зеленый светодиод. По умолчанию красный. Зеленый означает связь между ST-LINK/v2 (or V2-B) и ПК. У меня ST-LINK/v2-B, а также индикации пользовательского порта USB. 6. -LD3/10 (red), LD4/9 (blue), LD5/8 (orange) and LD6/7 (green). В прошлой записи мы с Вами мигали светодиодом LD4. 7. – Две кнопки: пользовательская USER и сброса RESET. 8. — USB USER with Mini-B connector.

stm32f3discovery 9 — USB отладчик/программатор ST-LINK/V2. 10. — Микроконтроллер STM32F303VCT6. 11. — Внешний высокочастотный генератор 8 Мгц. 12. – Здесь должен быть низкочастотный генератор, к сожелению не запаян. 13. – SWD – интерфейс. 14. – Джемперы для выбора программирования внешних контроллеров или внутреннего, в первом случае должны быть удалены. 15 – Джемпер JP3 – перемычка, предназначена для подключения амперметра, что б  измерить потребление контроллера. Понятно если она удалена, то наш камушек не запустится. 16. – STM32F103C8T6 на нем находится отладочная плата. 17. — LD3985M33R Регулятор с низким падением напряжения и уровнем шума, 150мА, 3.3В.

Теперь познакомимся поближе с архитектурой микроконтроллера STM32F303VCT6. Его техническая характеристика: корпус LQFP-100, ядро ARM Cortex-M4, максимальная частота ядра 72МГц, объём памяти программ 256 Кбайт, тип памяти программ FLASH, объём оперативной памяти SRAM 40 кбайт, RAM 8 кбайт, количество входов/выходов 87, интерфейсы ( CAN, I²C, IrDA, LIN, SPI, UART/USART, USB), периферия (DMA, I2S, POR, PWM, WDT), АЦП/ЦАП 4*12 bit/2*12bit, напряжение питания 2 …3.6 В, рабочая температура –40 …...+85 С. На рисунке ниже распиновка, где видим 87 портов ввода/вывода, 45 из них Normal I/Os  (TC, TTa), 42 5-volt tolerant I/Os (FT, FTf) – совместимые с 5 В. (на плате справа 5В выводы, слева 3,3В). Каждая цифровая линия ввода-вывода может выполнять функцию линии ввода-вывода общего
Pinoutsназначения или альтернативную функцию. По ходу продвижения проектов мы с Вами будем последовательно знакомится с периферией.

Рассмотрим блок диаграмму ниже. Сердцем является 32-битное ядро ARM Cortex-M4, работающее до 72 МГц. Имеет встроенный блок с плавающей запятой FPU и блок защиты памяти MPU, встроенные макро-ячейки трассировки — Embedded Trace Macrocell (ETM), которые могут быть использованы для наблюдения за процессом выполнения основной программы внутри микроконтроллера. Они способны непрерывно выводить данные этих наблюдений через контакты ETM до тех пор, пока устройство работает. NVIC (Nested vectored interrupt controller) – модуль контроля прерываний. TPIU (Trace Port Interface Unit). Содержит память FLASH –256 Кбайт, SRAM 40 кбайт, RAM 8 кбайт. Между ядром  и памятью расположена Bus matrix (Шинная матрица), которая позволяет соединить устройства напрямую. Также здесь видим два типа шинной матрицы AHB и APB, где первая более производительная и используется для связи высокоскоростных внутренних компонентов, а последняя для периферии (устройств ввода/вывода). Контроллер имеет 4 –ри 12-разрядных ADC (АЦП) (5Мбит/с) и датчик температуры, 7 компараторов (GP Comparator1 …7), 4-ри программируеммых операционных усилителя (OpAmp1…4) (PGA (Programmable Gain Array) ), 2 12 разрядных канала DAC (ЦАП), RTC (часы реального времени), два сторожевых таймера — независимый и оконный (WinWatchdog and Ind. WDG32K), 17 таймеров общего назначения и многофункциональные.

STM32F303-BlockDiagram

В общих чертах мы рассмотрели архитектуру контроллера. Теперь рассмотори доступные программные библиотеки. Сделав обзор можна выделить следующие: CMSIS, SPL и HAL. Рассмотрим каждую применив в простом примере мигая светодиодом.

CMSIS 1). CMSIS (Cortex Microcontroller Software Interface Standard) — стандартная библиотека для Cortex®-M. Обеспечивает поддержку устройств и упрощает программные интерфейсы. CMSIS предоставляет последовательные и простые интерфейсы для ядра, его периферии и операционных систем реального времени. Ее использования является профессиональным способом написания программ, т.к. предполагает прямую запись в регистры и соответственно необходимо постоянное чтение и изучение даташитов. Независим от производителя аппаратного уровня.
Components CMSISCMSIS включает в себя следующие компоненты:
— CMSIS-CORE: Consistent system startup and peripheral access (Постоянный запуск системы и периферийный доступ);
— CMSIS-RTOS: Deterministic Real-Time Software Execution (Детерминированное исполнение программного обеспечения реального времени);
— CMSIS-DSP: Fast implementation of digital signal processing (Быстрая реализация цифровой обработки сигналов);
— CMSIS-Driver: Generic peripheral interfaces for middleware and application code (Общие периферийные интерфейсы для промежуточного программного обеспечения и кода приложения);
— CMSIS-Pack: Easy access to reusable software components (Легкий доступ к многократно используемым программным компонентам);
— CMSIS-SVD: Consistent view to device and peripherals (Согласованное представление устройства и периферийных устройств);
— CMSIS-DAP: Connectivity to low-cost evaluation hardware (Возможность подключения к недорогому оборудованию для оценки). ПО для отладки.

Для примера напишем программу – мигаем светодиодом. Для этого нам понадабится документация описывающая регистры. В моем случае RM0316 Reference manual STM32F303xB/C/D/E, STM32F303x6/8, STM32F328x8, STM32F358xC, STM32F398xE advanced ARM ® -based MCUs , а также описние конткретной ножки за что отвечает DS9118: ARM®-based Cortex®-M4 32b MCU+FPU, up to 256KB Flash+ 48KB SRAM, 4 ADCs, 2 DAC ch., 7 comp, 4 PGA, timers, 2.0-3.6 V. Для начала в программе затактируем порт, т.к. по умолчанию все отключено чем достигается уменьшенное эрергопотребление. Открываем Reference manual и смотрим раздел Reset and clock control далее RCC register map и смотрим что за включение IOPEEN отвечает регистр RCC_AHBENR.

RCC_AHBENR

Перейдем в описание тактирования перефирии данного регистра AHB peripheral clock enable register (RCC_AHBENR), где видим что данный порт находится под 21-м битом. Включаем его RCC->AHBENR|=(1<<21). Далее сконфигурируем регистры GPIO. Нас интересует три: GPIOE_MODER и GPIOx_ODR. C помощью них повторим программу с предыдущей статьи, затактируем PE8. Первый отвечает за конфигурацию входа выхода, выбираем 01: General purpose output mode. GPIOE->MODER|=0×10000. Второй за включение низкого/высокого уровня на ножке. Ниже программа:

#include "stm32f3xx.h" //Заголовочный файл микроконтроллера
unsigned int i;
void delay () {
     for (i=0;i<500000;i++);
}
int main (void) {
     RCC->AHBENR|=(1<<21);
     GPIOE->MODER|=0×10000;
     while (1){
          delay ();
          GPIOE->ODR|=0×100;
          delay ();
          GPIOE->ODR&=~(0×100);
}    }

2). SPL (Standard Peripherals Library) — данная библиотека предназначена для объединения всех процессоров фирмы ST Electronics. Разработана для урощения преносимости кода и в первую очередь расчитана на начинающег разаработчика.  ST работала над заменой SPL под названием «low layer», которая совместима с HAL. Драйверы Low Layer (LL) разработаны для обеспечения почти легкого экспертно-ориентированного уровня, который ближе к оборудованию, чем HAL. В дополнение к HAL также доступны LL API.  Пример тойже программы на SPL.

#include <stm32f30x.h>
#include <stm32f30x_rcc.h>
#include <stm32f30x_gpio.h>
#define LED    GPIO_Pin_8
int main(){
</code><code>   long i;
</code><code>   GPIO_InitTypeDef gpio;
</code><span style="color: #339966;"><code>   // Blue LED is connected to port E, pin 8 (AHB bus)
</code><code>   RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOE, ENABLE );
</code><span style="color: #339966;"><code>   // Configure port E (LED)
</code><code>   GPIO_StructInit( &gpio ); <span style="color: #339966;">//объявляем и инициализируем переменную структуры данных</span>
</code><code>   gpio.GPIO_Mode = GPIO_Mode_OUT;
</code><code>   gpio.GPIO_Pin  = LED;
</code><code>   GPIO_Init( GPIOE, &gpio );
</code><span style="color: #339966;"><code>   // Blinking LEDS
</code><code>   while(1){
</code><span style="color: #339966;"><code>   // On
</code><code>      GPIO_SetBits( GPIOE, LED );
</code><code>      for( i = 0; i < 500000; i++ );
</code><span style="color: #339966;"><code>       // All off
</code><code>      GPIO_ResetBits( GPIOE, LED );
</code><code>      for( i = 0; i < 500000; i++ );
</code><code>   }}

Каждая функция описывается в технической документации UM1581 User manual Description of STM32F30xx/31xx Standard Peripheral Library. Здесь подключаем три заголовочных файла которые содержат необходимоые данные, структуры, функции управления сбросом и синхронизацией, а также для конфигурации портов ввода/вывода.

3). HAL — (Hardware Acess Level , Hardware Abstraction Layer) — Еще одна общая библиотека для разработки. С которой вышла и программа CubeMX для конфигурации, которую мы с Вами использовали в прошлой статье. Там же мы написали программу мигания светодиодом используя данную библиотеку. Как видим на рисунке, ниже, куб генерирует драйвера HAL and CMSIS. Что ж опишем основные используемые файлы:
system_stm32f3x.c и <span style="color: #0000ff;">system_stm32f3x.h</span> - предоставляют минимальные наборы функций для конфигурации системы тактирования;
core_cm4.h – предоставляет доступ к регистрам ядра и его периферии;
—  stm32f3x.h - заголовочный файл микроконтроллера;
startup_system32f3x.s — стартовый код, содержит таблица векторов прерываний и др.

HAL and CMSIS#include «main.h»
#include «stm32f3xx_hal.h»
void SystemClock_Config (void); /*Объявляем функции конфигурации тактирования*/
static void MX_GPIO_Init (void); /*Инициализация ввода/вывода*/
int main (void) {
/*Reset of all peripherals, Initializes the Flash interface and the Systick.*/
HAL_Init ();
/* Configure the system clock */
SystemClock_Config ();
/* Initialize all configured peripherals */
MX_GPIO_Init ();
while (1) {
       HAL_GPIO_TogglePin (GPIOE, GPIO_PIN_8);//Переключаем состояние ножки
       HAL_Delay (100);  }
}
void SystemClock_Config (void) {
       RCC_OscInitTypeDef RCC_OscInitStruct;
       RCC_ClkInitTypeDef RCC_ClkInitStruct;
       /**Initializes the CPU, AHB and APB busses clocks */
       RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
       RCC_OscInitStruct.HSIState = RCC_HSI_ON;
       RCC_OscInitStruct.HSICalibrationValue = 16;  
       RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
       if (HAL_RCC_OscConfig (&RCC_OscInitStruct) != HAL_OK) {
               _Error_Handler (__FILE__, __LINE__);
        }
        /**Initializes the CPU, AHB and APB busses clocks */
       RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
       |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
       RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
       RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
       RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
       RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
       if (HAL_RCC_ClockConfig (&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
              _Error_Handler (__FILE__, __LINE__);
       }
       /**Configure the Systick interrupt time*/
       HAL_SYSTICK_Config (HAL_RCC_GetHCLKFreq ()/1000);
        /**Configure the Systick*/
       HAL_SYSTICK_CLKSourceConfig (SYSTICK_CLKSOURCE_HCLK);
       /* SysTick_IRQn interrupt configuration */
       HAL_NVIC_SetPriority (SysTick_IRQn, 0, 0);
  }
/** Configure pins as Analog Input Output  EVENT_OUT EXTI */
static void MX_GPIO_Init (void) {
       GPIO_InitTypeDef GPIO_InitStruct;
       /* GPIO Ports Clock Enable */
       __HAL_RCC_GPIOE_CLK_ENABLE ();
       /*Configure GPIO pin Output Level */
       HAL_GPIO_WritePin (GPIOE, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
       |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
       /*Configure GPIO pins : PE8 PE9 PE10 PE11 PE12 PE13 PE14 PE15 */
       GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
       |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
       GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
       GPIO_InitStruct.Pull = GPIO_NOPULL;
       GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
       HAL_GPIO_Init (GPIOE, &GPIO_InitStruct);
 }
void _Error_Handler (char * file, int line){
while (1){
}
#ifdef USE_FULL_ASSERT

void assert_failed (uint8_t* file, uint32_t line) {
}
#endif 
Здесь также как и в предыдущем примере можем просмотреть описание каждой функции в документации, например UM1786 User Manual Description of STM32F3 HAL and low-layer drivers.

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

Просмотрено 1398 раз.

Я на Google+

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

Ваш e-mail не будет опубликован.

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe without commenting