Учебник STM32 – описание, программирование, отличие от Arduino

Учебник STM32 - описание, программирование, отличие от Arduino Мультикоптеры

Небольшое вступление

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

Именно с идеи создания собственного пультика для управления светом в комнате и началось моё увлечение электроникой, микроконтроллерами и различными радиоустройствами.

Список статей:

  1. Начинаем изучать STM32 или Управляем светом по-умному
  2. Начинаем изучать STM32: битовые операции
  3. Начинаем изучать STM32: Что такое регистры? Как с ними работать?

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

Легкое решение выглядело весьма привлекательно, ведь насколько я понял на тот момент, код собирается на раз-два. Но сделав вывод, что я не узнаю, что творится внутри микроконтроллера за рамками Arduino-скетчей я решил поискать более интересный вариант, который подразумевал глубокое изучение и погружение в дебри микроконтроллерной техники.

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

Смотрите про коптеры:  В Казани прошли гонки квадрокоптеров — фоторепортаж

Всё это для меня на тот момент показалось непостижимо сложным, и я даже пришел в некоторое смятение, но от реализации поставленной задачи отказываться не собирался. Так я познакомился с семейством микроконтроллеров STM32 и платой STM32F0-Discovery, после изучения которых мне хотелось бы сваять свой девайс под нужные мне цели.

К моему большому удивлению, такого большого комьюнити, статей, примеров, различных материалов по STM не было в таком же изобилии как для Arduino. Конечно, если поискать найдется множество статей «для начинающих» где описано, как и с чего начать. Но на тот момент мне показалось, что все это очень сложно, не рассказывались многие детали, интересные для пытливого ума новичка, вещи.

Многие статьи хоть и характеризовались как «обучение для самых маленьких», но не всегда с их помощью получалось достичь требуемого результата, даже с готовыми примерами кода. Именно поэтому я решил написать небольшой цикл статей по программированию на STM32 в свете реализации конкретной задумки: пульт управления освещением в комнате.

Приступим к первоначальной настройке и подготовке ide к работе!

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

Pack Installer

. В данном установщике содержатся низкоуровневые библиотеки, Middleware, примеры программ, которые регулярно пополняются и обновляются.

Для начала работы с нашей платой нам необходимо установить ряд пакетов необходимых для работы и необходимо найти микроконтроллер, с которым мы будем работать. Так же можно воспользоваться поиском вверху окна. После того, как мы нашли наш МК кликаем на него и во второй половине окна и нам необходимо установить следующий перечень библиотек:

  1. Keil::STM32F0xx_DFP – полноценный пакет программного обеспечения для конкретного семейства микроконтроллеров, включающий в себя мануалы, даташиты, SVD-файлы, библиотеки от производителя.
  2. ARM::CMSIS – пакет Cortex Microcontroller Software Interface Standard, включающий в себя полный набор библиотек от ARM для поддержки ядра Cortex.
  3. Keil::ARM_Compiler – последняя версия компилятора для ARM.

После установки требуемых паков можно перейти к настройке IDE и нашего отладчика/программатора. Для этого нам необходимо открыть главное окно Keil и создать новый проект.

Для этого необходимо перейти в меню

Project -> New uVision Project

и выбрать папку, в которую сохраним наш проект.

После Keil спросит нас какой МК будет использоваться в проекте. Выбираем нужный нам МК и нажимаем ОК.

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

  1. Ядро библиотеки CMSIS, в котором объявлены настройки, адреса регистров и многое другое из того что необходимо для работы нашего МК.
  2. Startup-файл, который отвечает за первоначальную инициализацию МК при старте, объявление векторов и обработчиков прерываний и многое другое.

Если все зависимости у подключаемых удовлетворены – менеджер будет нам сигнализировать об этом зеленым цветом:


После того как мы нажмем клавишу

ОК

мы можем приступать к созданию нашего проекта.

Для того, чтобы сконфигурировать параметры проекта и настроить наш программатор нужно правым кликом по Target 1 открыть соответствующее меню.

В главном меню проекта настраиваем параметр

Xtal

в значение

8.0 MHz

. Данный параметр отвечает за частоту работы кварцевого осциллятора нашего МК:


Далее переходим к настройке нашего программатора/дебагер. Кликаем в этом же окне на вкладку

Debug

и выбираем в поле

Use

параметр

ST-Link Debugger

и переходим в настройки:


В настройках мы должны увидеть модель нашего ST-Link установленного на плате, его серийный номер, версию HW и IDCODE МК который будем прошивать:

Для удобства можно настроить параметр, отвечающий за то, чтобы МК сбрасывался автоматически после перепрошивки. Для этого нужно поставить галочку в поле Reset and Run.

Dsi хост (dsihost) в микроконтроллерах stm32

MIPI-DSI – универсальный интерфейс, позволяющий работать с TFT-дисплеями как при наличии встроенной графической памяти и контроллера, так и без них [7]. Если RGB-интерфейс требует большого числа сигнальных линий, то DSI позволяет обойтись несколькими дифференциальными парами (CLK и DATAn).

Стандарт MIPI-DSI подразумевает наличие двух рабочих режимов:

  • режим команд (Command mode) используется для работы с дисплеями со встроенным контроллером и графической памятью. При этом DSI-хост, как и в случае DBI, производит передачу как данных, так и команд;
  • видеорежим (Video mode) используется для работы с дисплеями без собственной памяти. В этом случае DSI-хост передает изображение в реальном времени (аналогично DPI).

В настоящий момент DSI-хост (DSIHOST) реализован в новых семействах STM32: STM32F469/479, STM32F7x8/x9 и STM32L4R9/S9.

Основная функция DSIHOST заключается в формировании DSI-пакетов из данных, которые поступают от TFT-контроллера LTDC или от других блоков посредством периферийной шины APB. Если данные поступают от LTDC, то DSI-хост может работать как в видеорежиме, так и в режиме команд (Adapted Command mode). Если же работа с DSI-хостом идет через APB, то доступен только режим команд.

Структурная схема DSIHOST в STM32 включает в себя несколько основных блоков (рисунок 10):

  • DSI-преобразователь (DSIWrapper) обеспечивает взаимодействие между TFT-контроллером LTDC и ядром DSI. Здесь выполняется преобразование цветов и полярностей сигналов, а также обработка команд в режиме Adapted Command mode. Кроме того, данный блок управляет системой ФАПЧ и некоторыми функциями D-PHY.
  • Интерфейс LTDC принимает сообщения от LTDC и помещает их в FIFO-буфер. Эти данные используются для формирования видеопотока в видеорежиме и формирования команд memory_write_start and memory_write_continue в режиме Adapted Command mode.
  • Преобразователь APB-Generic осуществляет обмен между периферийной шиной APB и ядром DSI. Для этого используется три FIFO-буфера: команд (Command FIFO), записи (Write payload FIFO), чтения (Read payload FIFO).
  • Внутренние регистры необходимы для настройки DSI Host. Взаимодействие с ними идет по периферийной шине APB.
  • Обработчик пакетов (PacketHandler) используется для формирования и обработки DSI-пакетов, контроля ошибок, подсчета контрольных сумм и так далее.
  • Интерфейс D-PHY отвечает за взаимодействие ядра и D-PHY.
  • Блок контроля ошибок следит за ошибками синхронизации, обеспечивает программный сброс и формирование ряда прерываний.
  • Видеогенератор используется для формирования на дисплее вертикальных или горизонтальных прямоугольных полос без участия LTDC.

DSIHOST использует одну дифференциальную линию тактирования (CLK) и до двух линий данных (DATAn) (рисунок 10). Шина данных DATA0 является двунаправленной при работе в режиме команд, а в видеорежиме она может быть как двунаправленной, так и однонаправленной.

DSIHOST поддерживает все форматы и разрядности, которые поддерживает и LTDC. Говоря о разрешении, стоит отметить, что пропускная способность DSIHOST позволяет создавать графические приложения с разрешением более 800×480.

Чтобы упростить себе жизнь, при подключении DSI-дисплея стоит воспользоваться автоматической генерацией кода в STM32CubeMX.

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

Power management часть 2 (перевод из книги mastering stm32) | radiotech.kz

Продолжаем перевод главы, которая описывает управление питанием в микроконтроллерах STM32.

Power Management часть 1. Управление питанием в микроконтроллерах Cortex-M
Power Management часть 3. Управление питанием в микроконтроллерах STM32L
Power Management часть 4. Использование калькулятора энергопотребления CubeMX

18.3 Управление питанием в микроконтроллерах STM32F

До сих пор мы рассматривали параметры, свойственные всем микроконтроллерам STM32. Тем не менее, семейства микроконтроллеров STM32 делится еще на две больших ветки STM32F и STM32L. Вторая серия микроконтроллеров адресована как раз для энергосберегающих применений и обеспечивает большое количество режимов для минимизации потребления питания.

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

18.3.1 Источники питания

На рисунке 3 показаны все источники питания, которые могут быть у микроконтроллеров STM32 (следует отметить, что схема упрощена и некоторые из микроконтроллеров имеют более сложную схему питания, нежели изображенная). Как уже было сказано ранее, даже если мы используем лишь один источник питания, микроконтроллер имеет внутреннюю структуру распределения, которая определяет несколько областей напряжения, используемых для питания тех периферийных устройств, которые имеют схожие характеристики питания. Для примера, напряжение VDDA питает те аналоговые периферийные устройства, которым требуется отдельный (лучше отфильтрованный) источник питания, через выводы VDDA микроконтроллера.

Напряжения VDD и VDD18 являются наиболее значимыми. VDD подается внешним источником питания, когда как VDD18 формируется внутренним стабилизатором напряжения микроконтроллера. Этот стабилизатор можно настроить для работы в режиме пониженного энергопотребления, как мы увидим далее. Для сохранения содержания резервных регистров и обеспечения функционирования RTC, когда VDD отключен, можно запитать вывод VBAT от дополнительного резервного источника питания или от батареи. Вывод VBAT обеспечивает питание RTC, генератора LSE и одного или двух выводов, используемых для пробуждения микроконтроллера из режимов глубокого сна, обеспечивая работу RTC даже когда нет основного питания VDD. По этой причине источник питания VBAT называют источником питания RTC. Переключение на источник питания VBAT управляется посредством PDR (Power Down Reset), встроенного в блок сброса.

18.3.2 Режимы питания

В первой части этой главы мы увидели, что микроконтроллер на базе Cortex-M ядра обеспечивает три основных режима питания: Run, Sleep и Deep Sleep. И теперь самое время рассмотреть как инженеры ST переработали эти режимы в своих микроконтроллерах STM32F. Таблица 1 суммирует эти режимы и показывает три основные функции, предоставляемые HAL для каждого из режимов питания. Их мы проанализируем немного позже.

18.3.2.1 Режим Run

По умолчанию и после подачи питания или сброса микроконтроллера, STM32F устанавливает режим работы Run или по другому активный режим работы, который потребляет большое количество энергии даже при выполнении несущественных задач. Потребление этого режима и режима Sleep зависит от тактовой частоты микроконтроллера. На рисунке 4 показаны уровни энергопотребления некоторых микроконтроллеров серии STM32F4. В активном режиме основной стабилизатор обеспечивает полную мощность для домена 1.8/1.2V (это ядро, память и цифровая периферия). В этом режиме выходное напряжение стабилизатора 1.8/1.2V в зависимости от конкретного микроконтроллера STM32F, его можно программно масштабировать до различных значений напряжения и подробнее об этом будет сказано чуть позже. Некоторые более новые микроконтроллеры серии STM32F4 предоставляют сразу два режима работы:

  • Нормальный режим: процессор и цифровая логика работают на максимальной частоте при заданном напряжении масштабирования (scale 1, scale 2, scale 3).
  • Режим Over-Drive: этот режим позволяет процессору и основной логике работать на более высоких частотах, чем в обычном режиме для scale 1 и scale 2. Подробнее об этом позже.
Энергопотребление некоторых микроконтроллеров серии STM32F4
Рисунок 4. Энергопотребление некоторых микроконтроллеров серии STM32F4

18.3.2.1.1 Динамическое масштабирование напряжения в микроконтроллерах STM32F4/F7

Потребляемая мощность в цепи постоянного тока определяется потребляемым током и напряжением в цепи. Это означает, что мы можем уменьшить потребляемую мощность, уменьшив напряжение питания. STM32F4/F7 предоставляют технологию интеллектуального контроля питания под названием Dynamic Voltage Scaling (DVS), отличающуюся от той, что есть в серии STM32L. Идея DVS заключается в том, что многим встраиваемым системам не всегда требуются полные возможности обработки системы, поскольку не все подсистемы активны в одно время. В этом случае система может оставаться в активном режиме работы и процессор не будет работать на максимальной тактовой частоте. Напряжение, подаваемое на процессор, может быть уменьшено с уменьшением тактовой частоты. Благодаря такому механизму управления питанием, мы уменьшаем потребляемую мощность, отслеживая входное напряжение процессора в соответствии с требованиями к производительности системы.

Это выражается в масштабировании выходного напряжения регулятора STM32F4, которое падает до 1.2В, когда мы понижаем тактовую частоту. STM32F4/F7 предлагает три коэффициента масштабирования (scale 1, scale 2, scale 3). Максимально возможная тактовая частота ядра для конкретного коэффициента масштабирования зависит от конкретного микроконтроллера STM32. Например, STM32F401 имеет только два коэффициента масштабирования, scale 2 и scale 3, которые позволяют ядру работать на частотах 84МГц и 60МГц соответственно. Для управления масштабированием напряжения CubeHAL предоставляет следующую функцию:

HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling);

которая принимает следующие константы:

PWR_REGULATOR_VOLTAGE_SCALE1,
PWR_REGULATOR_VOLTAGE_SCALE2,
PWR_REGULATOR_VOLTAGE_SCALE3

Масштабирование напряжения можно изменить только в том случае, если источником системной тактовой частоты является HSI или HSE. Итак, чтобы увеличить/уменьшить скалирование напряжения вы должны выполнить следующие процедуры:

Во-первых, установите HSI или HSE в качестве источника системной тактовой частоты, используя

HAL_RCC_ClockConfig();

Во-вторых, для настройки PLL вызовите функцию

HAL_RCC_OscConfig();

В-третьих, для настройки скалирования напряжения вызовите

HAL_PWREx_ConfigVoltageScaling();

И в-четвертых, установите новую системную тактовую частоту

HAL_RCC_ClockConfig();

Для получения дополнительной информации по этой теме смотрите апноут AN4365.

18.3.2.1.2 Режим Over/Under-Drive в микроконтроллерах STM32F4/F7

Некоторые микроконтроллеры из серии STM32F4 и все из STM32F7 предоставляют два или даже более вспомогательных режима. Эти режимы называются Over-Drive и Under-Drive. Первый заключается в увеличении тактовой частоты с помощью «разгона». Входить в режим Over-Drive рекомендуется когда приложение не выполняет критические задачи и источником системной тактовой частоты является HSI или HSE. Эти функции могут быть полезны, когда мы хотим временно увеличить/уменьшить тактовую частоту микроконтроллера без перенастройки тактового дерева, что обычно приводит незначительным издержкам. HAL предоставляет две удобные функции для выполнения этих операций:

HAL_PWREx_EnableOverDrive();
HAL_PWREx_DisableOverDrive();

Режим Under-Drive противоположен Over-Drive и заключается в понижении тактовой частоты и отключении некоторых периферийных устройств. В этом режиме возможно перевести внутренний регулятор напряжения в режим пониженного энергопотребления. В некоторых микроконтроллерах STM32F4/F7 этот режим доступен даже в Stop режиме.

18.3.2.2 Режим Sleep

Войти в спящий режим можно с помощью выполнения инструкций WFI или WFE. В спящем режиме все порты ввода/вывода сохраняют свое состояние. Нет необходимости заботиться о выполнении данных инструкций, т.к. CubeHAL предоставляет для этого специальную функцию:

void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry);

Первый ее параметр Regulator, не имеет смысла в спящем режиме для всех микроконтроллеров STM32F и оставлен для совместимости с серией STM32L. Второй параметр, SLEEPEntry, может принимать значенияPWR_SLEEPENTRY_WFI или PWR_SLEEPENTRY_WFE: как следует из названий, первый выполняет инструкцию WFI, а второй — WFE.

Учебник STM32 - описание, программирование, отличие от Arduino

Если вы посмотрите на функцию HAL_PWR_EnterSLEEPMode(), то вы обнаружите, что, если мы передадим параметр PWR_SLEEPENTRY_WFE, она выполнит две инструкции WFE последовательно. Это приводит к тому, что HAL_PWR_EnterSLEEPMode() входит в спящий режим таким же образом, как если бы она вызывалась с параметром PWR_SLEEPENTRY_WFI (двойной вызов инструкции WFE приводит к тому, что если установлен регистр событий, то он очищается первой инструкцией WFE, а вторая переводит микроконтроллер в спящий режим). Я не знаю почему ST использовали подобный подход. Если вы хотите получить полный контроль над режимами энергопотребления микроконтроллера, вам необходимо изменить содержание этой функции в соответствии с вашей задачей. Ясно, что микроконтроллер выйдет из спящего режима при условии выхода для инструкции WFE.

Если используется инструкция WFI для входа в спящий режим, любое прерывание от периферийного устройств, подтвержденной вложенным вектором в контроллере прерываний (NVIC), может вывести устройство из спящего режима.

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

  • включено прерывание регистре управления периферийного устройства, но не в NVIC, установлен бит SEVONPEND в регистре управления System Control Register — когда микроконтроллер возобновляет работу после инструкции WFE, бит ожидания прерывания от периферии и бит IRQ в регистре NVIC должны быть очищены;
  • сконфигурировано внешнее и внутреннее прерывание линии EXTI в режиме события — когда микроконтроллер возобновляет работу после инструкции WFE, нет необходимости очищать бит ожидания прерывания периферийного устройства или NVIC, поскольку бит ожидания, соответствующий данному событию, не устанавливается.

Этот режим предлагает самое низкое время пробуждения, поскольку не тратится время на вход/выход из прерывания.

18.3.2.3 Режим Stop

Режим Stop или режим остановки основан на режиме глубокого сна Cortex-M в сочетании с выключением тактирования периферийных устройств. В этом режиме все тактовые сигналы в домене 1.8В останавливаются, генераторы PLL, HSI и HSE отключены. SRAM и содержимое регистра сохраняется. Все порты ввода/вывода сохраняют свое состояние. Регулятор напряжения может быть как в нормальном режиме работы, так и в режиме пониженного энергопотребления. Для перевода микроконтроллера в режим остановки HAL предоставляет функцию:

void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry);

где параметр Regulator принимает значение PWR_MAINREGULATOR_ON, чтобы оставить внутренний регулятор напряжения включенным, или значение PWR_LOWPOWERREGULATOR_ON, чтобы перевести его в режим пониженного энергопотребления. Параметр STOPEntry может принимать значения PWR_STOPENTRY_WFI или PWR_STOPENTRY_WFE.

Чтобы войти в режим остановки, все ожидающие прерывания биты линии EXTI периферийных устройств и RTC Alarm флаг должны быть сброшены. В противном случае процедура входа в режим остановки игнорируется и выполнение программы будет продолжено. Если приложению необходимо отключить внешний тактовый генератор HSE перед входом в режим остановки, источник системной тактовой частоты должен быть сперва переключен на HSI, а затем сброшен бит HSEON. В противном случае, если перед входом в режим остановки бит HSEON не сброшен, необходимо включить функцию систему безопасности CSS, чтобы обнаружить сбой внешнего генератора и избежать неисправности при входе в режим остановки.

Любая линия EXTI, сконфигурированная в режиме прерывания или события, вынуждает процессор выйти из режима остановки, если он был введен в режиме пониженного энергопотребления с использованием инструкций WFI или WFE. Поскольку и HSE, и PLL отключаются перед входом в этот режим, то при выходе из него источником системной тактовой частоты устанавливается HSI. Это означает, что наш код должен переконфигурировать дерево тактирования в соответствии с желаемой SYSCLK.

18.3.2.4 Режим Standby

Режим ожидания позволяет достичь минимального потребления. Он основан на режиме глубокого сна Cortex-M с полностью отключенным внутренним регулятором напряжения. Домен 1.8/1.2V отключен. PLL, генераторы HSI и HSE также отключены. SRAM и содержимое регистров теряется, за исключением регистров в standby режима. Для перевода микроконтроллера в режим ожидания HAL предоставляет функцию:

void HAL_PWR_EnterSTANDBYMode(void);

Микроконтроллер может выйти из режима ожидания, когда происходит внешний сброс (NRST), сброс IWDG, нарастающий фронт на одном из активированных выводов WKUPx или по событию от RTC. Все регистры сбрасываются после выхода из режима, за исключением регистра управления питанием PWR->CSR. После выхода выполнение программы возобновляется так же, как и после сброса. Используя макрос:

__HAL_PWR_GET_FLAG(PWR_FLAG_SB);

мы можем проверить, сбрасывается ли микроконтроллер после выхода из режима ожидания. Поскольку и HSE, и PLL отключаются перед входом в режим ожидания, то при выходе из него источником системной тактовой частоты устанавливается HSI. Это означает, что наш код должен переконфигурировать дерево тактирования в соответствии с желаемой SYSCLK.

18.3.2.5 Примеры режимов пониженного энергопотребления

В следующем примере для платы Nucleo-F030R8, показано, как работают режимы пониженного энергопотребления.

Filename: src/main-ex1.c

int main(void) 
{
	char msg[20];

	HAL_Init();
	Nucleo_BSP_Init();

	/* Before we can access to every register of the PWR peripheral we must enable it */
	__HAL_RCC_PWR_CLK_ENABLE();

	while (1) 
	{
		if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB)) 
		{
		/* If standby flag set in PWR->CSR, then the reset is generated from
		 * the exit of the standby mode */
		sprintf(msg, "RESET after STANDBY modern");
		HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
		/* We have to explicitly clear the flag */
		__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU|PWR_FLAG_SB);
		}

		sprintf(msg, "MCU in run modern");
		HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
		while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET) 
		{
		HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
		HAL_Delay(100);
		}

		HAL_Delay(200);

		sprintf(msg, "Entering in SLEEP modern");
		HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);

		SleepMode();

		sprintf(msg, "Exiting from SLEEP modern");
		HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);

		while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET);
		HAL_Delay(200);

		sprintf(msg, "Entering in STOP modern");
		HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);

		StopMode();

		sprintf(msg, "Exiting from STOP modern");
		HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);

		while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET);
		HAL_Delay(200);

		sprintf(msg, "Entering in STANDBY modern");
		HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);

		StandbyMode();

		while(1); //Never arrives here, since MCU is reset when exiting from STANDBY
	}
}

void SleepMode(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;

  /* Disable all GPIOs to reduce power */
  MX_GPIO_Deinit();

  /* Configure User push-button as external interrupt generator */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  GPIO_InitStruct.Pin = B1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

  HAL_UART_DeInit(&huart2);

  /* Suspend Tick increment to prevent wakeup by Systick interrupt.
     Otherwise the Systick interrupt will wake up the device within 1ms (HAL time base) */
  HAL_SuspendTick();

  __HAL_RCC_PWR_CLK_ENABLE();
  /* Request to enter SLEEP mode */
  HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);

  /* Resume Tick interrupt if disabled prior to sleep mode entry*/
  HAL_ResumeTick();

  /* Reinitialize GPIOs */
  MX_GPIO_Init();

  /* Reinitialize UART2 */
  MX_USART2_UART_Init();
}

void StopMode(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;

  /* Disable all GPIOs to reduce power */
  MX_GPIO_Deinit();

  /* Configure User push-button as external interrupt generator */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  GPIO_InitStruct.Pin = B1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

  HAL_UART_DeInit(&huart2);

  /* Suspend Tick increment to prevent wakeup by Systick interrupt.
     Otherwise the Systick interrupt will wake up the device within 1ms (HAL time base) */
  HAL_SuspendTick();

  /* We enable again the PWR peripheral */
  __HAL_RCC_PWR_CLK_ENABLE();
  /* Request to enter SLEEP mode */
  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);

  /* Resume Tick interrupt if disabled prior to sleep mode entry*/
  HAL_ResumeTick();

  /* Reinitialize GPIOs */
  MX_GPIO_Init();

  /* Reinitialize UART2 */
  MX_USART2_UART_Init();
}


void StandbyMode(void) 
{
  MX_GPIO_Deinit();

  /* This procedure come from the STM32F030 Errata sheet*/
  __HAL_RCC_PWR_CLK_ENABLE();

  HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);

  /* Clear PWR wake up Flag */
  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);

  /* Enable WKUP pin */
  HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);

  /* Enter STANDBY mode */
  HAL_PWR_EnterSTANDBYMode();
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 
{
  if(GPIO_Pin == B1_Pin) 
  {
    while(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin) == GPIO_PIN_RESET);
  }
}

Макрос __HAL_RCC_PWR_CLK_ENABLE() в строке 9 включает периферийное устройство PWR: прежде чем мы сможем выполнить хоть какую-нибудь операцию, связанную с управлением питанием, нам необходимо включить PWR, даже если мы просто проверяем установлен ли флаг ожидания в регистре PWR->CSR. Это является источником головной боли для многих начинающих разработчиков. 

Строки [13:21] проверяют установку флага ожидания: если установлен, то это означает, что микроконтроллер был сброшен после выхода из режима ожидания Standby. Строки [23:29] представляют режим работы: светодиод LD2 мигает пока не будет нажата кнопка USER на плате Nucleo, подключенная к PC13. Остальные строки в main() просто позволяют переключаться между тремя режимами пониженного энергопотребления при каждом нажатии кнопки USER.

Строки [64:96] определяют функцию SleepMode(), используемую для перевода микроконтроллера в спящий режим. Все GPIO настроены как аналоговые входа, чтобы уменьшить потребление тока на неиспользуемых выводах (особенно те выводы, которые могут быть источником утечек тока). Отключается тактирование периферийных устройств, за исключением порта GPIOC, т.к. PC13 используется для выхода из режимов пониженного энергопотребления. То же самое относится к интерфейсу UART2 и таймеру SysTick, который останавливается для того, чтобы предотвратить выход микроконтроллера из спящего режима через 1мс. Вызов функции HAL_PWR_EnterSLEEPMode() в строке 86 переводит микроконтроллер в спящий режим до тех пор, пока он не пробуждается при нажатии кнопки USER (микроконтроллер пробуждается, потому что мы настроили соответствующее прерывание, которое вызывает инструкцию WFI, которая выводит МК из режима пониженного энергопотребления).

Функция StopMode() практически идентична функции SleepMode(), за исключением того, что она вызывает функцию HAL_PWR_EnterSTOPMode() для перевода микроконтроллера в режим остановки.

И наконец, строки [134:159] определяют функцию StandbyMode(). Здесь мы следуем процедуре, описанной в Errata для микроконтроллера STM32F030, поскольку в этом микроконтроллере есть аппаратная ошибка, которая не позволяет ему войти в режим ожидания: сначала необходимо отключить вывод PWR_WAKEUP_PIN1, а затем очистить флаг пробуждения в PWR->CSR для повторного включения вывода пробуждения, который в микроконтроллере STM32F030 совпадает с выводом PA0.

Учебник STM32 - описание, программирование, отличие от Arduino

Микроконтроллеры STM32 обычно имеют два вывода пробуждения, которые называются PWR_WAKEUP_PIN1 и PWR_WAKEUP_PIN2. Для многих микроконтроллеров STM32 в корпусе LQFP64 второй вывод пробуждения совпадает с PC13, который подключен к кнопке USER на всех платах Nucleo (кроме Nucleo-F302, где он подключен к выводу PB13). Тем не менее, мы не можем PWR_WAKEUP_PIN2 в нашем примере, потому что этот вывод подтянут к питанию резистором на печатной плате. Когда мы конфигурируем выводы пробуждения в сочетании с режимом ожидания, мы не используем соответствующую периферию GPIO, которая бы позволила нам настраивать вывод на вход, потому что она отключается перед входом в режим ожидания: выводы пробуждения напрямую обрабатываются периферийным устройством PWR, которое сбрасывает микроконтроллер, если один из двух выводов устанавливается в логическую единицу, т.е. на нем появляется напряжение питания. Итак, в примере мы используем вывод PWR_WAKEUP_PIN1, который соответствует выводу PA0 в микроконтроллере STM32F030.

Платы Nucleo позволяют измерить потребление тока микроконтроллера с помощью штыревого разъема IDD. Перед началом измерений необходимо установить соединения с платой, как показано на рисунке 5, сняв перемычку IDD и подключив щупы амперметра. Убедитесь, что амперметр настроен на шкалу мА. Таким образом, вы можете увидеть энергопотребление для каждого из режимов питания микроконтроллера.

Учебник STM32 - описание, программирование, отличие от Arduino

18.3.3 Важное предупреждение для микроконтроллеров STM32F1

Во время разработки примеров для FreeRTOS в соответствующей главе, автор книги столкнулся с неприятным поведением микроконтроллера STM32F103 при входе в режим остановки с помощью функции HAL_PWR_EnterSTOPMode() из CubeF1 HAL. В частности, возникшая проблема связана с выходом из этого режима, когда микроконтроллер входит в него с помощью инструкции WFI. В режим остановки микроконтроллер входит правильно, но во время пробуждения от прерывания, он немедленно генерирует исключение Hard Fault. Изучив данный случай, автор пришел к выводу, что разработчики ST не следуют советам ARM в вопросе перехода в режимы пониженного энергопотребления в микроконтроллерах Cortex-M3, как описано здесь.

Изменение процедуры HAL следующим образом решило данную проблему:

void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) 
{
	/* Check the parameters */
	assert_param(IS_PWR_REGULATOR(Regulator));
	assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
	/* Clear PDDS bit in PWR register to specify entering in STOP mode when CPU enter in Dee
	   psleep */
	CLEAR_BIT(PWR->CR, PWR_CR_PDDS);
	/* Select the voltage regulator mode by setting LPDS bit in PWR register according to Re
	   gulator parameter value */
	MODIFY_REG(PWR->CR, PWR_CR_LPDS, Regulator);
	/* Set SLEEPDEEP bit of Cortex System Control Register */
	SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
	/* Select Stop mode entry --------------------------------------------------*/
	if(STOPEntry == PWR_STOPENTRY_WFI)
	{
		/* Request Wait For Interrupt */
		__DSB(); //Added by me
		__WFI();
		__ISB(); //Added by me
	}
	else
	{
		/* Request Wait For Event */
		__SEV();
		PWR_OverloadWfe(); /* WFE redefine locally */
		PWR_OverloadWfe(); /* WFE redefine locally */
	}
	/* Reset SLEEPDEEP bit of Cortex System Control Register */
	CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
}

Изменение заключается просто в добавлении двух инструкций барьера памяти, одной до и после инструкции WFI.

Автор задал вопрос по этой проблеме на официальном форуме ST, но на момент написания этой главы ответа еще не было.


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

Обзор аппаратной периферии stm32 для создания графических приложений

Номенклатура микроконтроллеров STM32 чрезвычайно богата и насчитывает более тысячи различных моделей, объединенных в 64 линейки. Каждая из линеек имеет индивидуальный набор периферийных блоков, позволяющих взаимодействовать с TFT-дисплеями (таблица 1):

  • SPI-интерфейс – коммуникационный интерфейс для дисплеев с MIPI-DBI Type C. При наличии SPI TFT-дисплеи могут использоваться со всеми без исключения контроллерами STM32. Этот случай достаточно простой и очевидный, и отдельно о встроенном SPI-интерфейсе STM32 в рамках данной статьи рассказано не будет;
  • FSMC (Flexible Static Memory Controller) – контроллер внешней памяти, который позволяет взаимодействовать с TFT-дисплеями, снабженными интерфейсами Motorola 6800 и Intel 8080. При определенных условиях FSMC может использоваться для работы с TFT-дисплеями с RGB-интерфейсом;
  • LTDC (LCD-TFT Display Controller) – специализированный TFT-контроллер, который позволяет работать с TFT-дисплеями, оснащенными RGB-интерфейсом;
  • MIPI-DSI Host – специализированный интерфейс для работы с TFT-дисплеями, с MIPI-DSI.

В большинстве случаев внутренней памяти микроконтроллера не хватает для хранения графических изображений и размещения экранной памяти. По этой причине очень часто требуется внешняя Flash и ОЗУ. Для увеличения объема Flash идеально подходит интерфейс QuadSPI, который присутствует практически во всех последних линейках STM32.

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

  • Chrom-ART – графический ускоритель. Представляет собой особый контроллер прямого доступа к памяти, созданный специально для оптимизации процессов по пересылке больших массивов графических данных с возможностью их потоковой обработки.
  • Chrom-GRC – блок оптимизации хранения графических данных, позволяющий экономить до 20% памяти при работе с дисплеями округлой формы.
  • JPEG-кодек – специализированный ускоритель, необходимый для JPEG-кодирования и декодирования графических изображений.

Таблица 1. Специализированная периферия микроконтроллеров STM32 для графических приложений

НаименованиеИнтерфейсы дисплеевГрафические ускорителиВнешняя память
SPIMotorola 6800Intel 8080RGBMIPI-DSILVDS
SPIFSMCLTDCDSIСhromeArtChrom-GRCJPEG-CodecQuadSPISDRAM
STM32L0x1
STM32L0x2
STM32L0x3
STM32L100
STM32L151/152
STM32L162
STM32L431
STM32L451
STM32L471
STM32L432
STM32L452
STM32L433
STM32L475
STM32L476
STM32L496
STM32L4R5
STM32L4S5
STM32L4R7
STM32L4S7
STM32L4R9
STM32L4S9
STM32F0x0
STM32F0x1
STM32F0x2
STM32F0x8
STM32F100
STM32F101
STM32F102
STM32F103
STM32F105
STM32F107
STM32F205
STM32F215
STM32F207
STM32F217
STM32F301
STM32F302
STM32F303
STM32F3x4
STM32F373
STM32F3x8
STM32F401
STM32F410
STM32F411
STM32F412
STM32F413
STM32F405
STM32F407
STM32F446
STM32F427
STM32F437
STM32F429
STM32F439
STM32F469
STM32F479
STM32F7x2
STM32F7x3
STM32F7x5
STM32F7x6
STM32F7x7
STM32F7x8
STM32F7x9
STM32H743
STM32H753

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

Обзор встроенного tft-контроллера (ltdc)

Для создания наиболее продвинутых графических приложений с максимальным разрешением экрана следует использовать встроенный TFT-контроллер (LTDC), который присутствует в старших линейках STM32: STM32L4R7, STM32L4S7, STM32L4R9, STM32L4S9, STM32F429/439, STM32F469/479, STM32F7x6, STM32F7x7, STM32F7x8, STM32F7x9, STM32H743, STM32H753 [6].

LTDC имеет следующие особенности:

  • 24/16/8-битный RGB-интерфейс;
  • разрешения до XGA 1024×768;
  • два графических слоя с собственными буферами FIFO 64×32 бит;
  • возможность программирования параметров каждого слоя;
  • программирование размеров и положения отображаемых окон;
  • поддержка 8 форматов цвета;
  • встроенный конвертер форматов цвета;
  • поддержка палитр с числом цветов до 256 (24-битных);
  • возможность смешивания слоев для получения эффекта полупрозрачности (альфа-смешение);
  • поддержка хромакея (Color keying);
  • поддержка псевдослучайного дизеринга (2 бита);
  • четыре вектора прерывания.

Характеристики TFT-контроллеров различных семейств незначительно различаются. Например, в случае с STM32H7 TFT-контроллер подключается к высокоскоростной шине AXI (рисунок 5), в то время как в остальных семействах он работает с шиной AHB. Рассмотрим структурную схему LTDC подробнее.

Встроенный TFT-контроллер использует три источника тактирования:

  • HCLK – для обмена данными по шине AXI или AHB;
  • PCLK – для взаимодействия с внутренними регистрами TFT-контроллера;
  • LCD_CLK – для формирования интерфейсных сигналов для связи с дисплеем.

Обмен данными между TFT-контроллером и шинами AXI (или AHB) осуществляется посредством FIFO-буферов 64×32 бит – по одному на каждый экранный слой.

LTDC поддерживает работу с двумя экранными слоями, каждый из которых имеет возможность независимой настройки параметров, например, размеров и положения окна отображения. Это позволяет без проблем создавать такие эффекты, как картинка в картинке.

Максимальная разрядность шины RGB для LTDC составляет 24 бита. Это обеспечивает высокую производительность и оптимальную поддержку 8 различных форматов цвета: ARGB8888, RGB888, RGB565, ARGB1555, ARGB4444, L8, AL44, AL88.

Еще одним полезным аппаратным блоком, входящим в состав LTDC, является микшер (Blending Unit). Он позволяет производить альфа-смешение изображений двух слоев между собой или с постоянным цветом заднего фона (рисунок 6). Если говорить простым языком, то это эффект полупрозрачности. Наличие аппаратного блока смешивания позволяет получать современную картинку без загрузки процессора.

Говоря о прозрачности, нельзя не упомянуть о том, что LTDC поддерживает чрезвычайно популярную технологию хромакея (Color keying). Она заключается в том, что один из цветов верхнего слоя «назначается» прозрачным, и вместо пикселей с таким цветом отображается нижний слой. На рисунке 7 показан конкретный пример, в котором зеленый цвет слоя Layer1 заменяется картинкой со слоя Layer2.

Еще одним важным достоинством TFT-контроллеров в STM32 является наличие аппаратного дизеринга (2 бита). Этот эффект заключается в возможности смешивания цветов соседних пикселей, что позволяет «сглаживать» резкие переходы (рисунок 8).

Чтобы подключить микроконтроллер STM32 к RGB-дисплею, можно либо самостоятельно изучить документацию, либо воспользоваться программой STM32CubeMX или взять за основу готовые проекты, например, отладочные платы. STM32CubeMX помогает быстро выполнить распиновку и настройку TFT-контроллера без значительных затрат времени (рисунок 9). Программа автоматически назначает выводы и генерирует код инициализации.

Если же за основу решено взять готовый проект, то хорошим вариантом будет использование отладочных наборов производства компании ST (таблица 2). При этом вместе с готовой схемотехникой разработчик получает и набор ПО для конкретного решения.

Таблица 2. Отладочные наборы STM32 с RGB-дисплеями [6]

Отладочный наборМикро-
контроллер
Параметры TFTВстроенная память SRAM, кбайтВнешняя SDRAM, битВнешняя SRAM, бит
ИнтерфейсДиагональ, дюймРазрешение, точекФормат цветаСенсорный экран
32F429IDISCOVERYSTM32F429DPI2,4240×320RGB666Резистивный25616
STM32439I-EVAL2STM32F439DPI5,7640×480RGB666Емкостной2563216
STM32429I-EVAL1STM32F429DPI4,3480×272RGB888Резистивный2563216
32F469IDISCOVERYSTM32F469MIPI-DSI4800×480RGB888Емкостной38432
STM32469I-EVALSTM32F469MIPI-DSI4800×480RGB888Емкостной3843216
32F746GDISCOVERYSTM32F746DPI4,3480×272RGB888Емкостной32032
STM32746G-EVALSTM32F746DPI5,7640×480RGB666Емкостной3203216
STM32F769I-DISCOSTM32F769MIPI-DSI4800×480RGB888Емкостной51232
STM32F779I-EVALSTM32F779MIPI-DSI4800×480RGB888Емкостной5123216
STM32F769I-EVALSTM32F769MIPI-DSI4800×480RGB888Емкостной5123216
STM32H753I-EVALSTM32H753IDPI5,7640×480RGB888Емкостной10003216
STM32H743I-EVALSTM32H743IDPI5,7640×480RGB888Емкостной10003216

Одним из недостатков RGB-интерфейса является большое число сигнальных линий. Чтобы уменьшить число занятых выводов и сохранить высокое разрешение дисплея, следует рассмотреть возможность использования MIPI-DSI.

Обзор продуктовых линеек

STM32L
STM32L

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

Серии STM32F-1, STM32F-2 и STM32L полностью совместимы. Каждая из серий имеет десятки микросхем, которые можно без труда поменять на другие изделия. STM32F-1 была первой линейкой, ее производительность была ограничена. Из-за этого по характеристикам контроллеры быстро догнали изделия семейства Stellaris и LPC17.

Позднее была выпущена STM32F-2 с улучшенными характеристиками – тактовая частота достигала 120 МГц. Отличается высокой процессорной мощностью, которая достигнута благодаря новой технологии производства 90 нм. Линейка STM32L представлена моделями, которые изготовлены по специальному технологическому процессу. Утечки транзисторов минимальны, благодаря чему приборы показывают лучшие значения.

Важно отметить, что контроллеры линейки STM32W не имеют pin-to-pin совместимости с STM32F-1, STM32F-2 и STM32L. Причина заключается в том, что линейку разрабатывала компания, которая предоставила радиочастотную часть. Это наложило ограничения на разработку для компании ST.

STM32F100R4
STM32F100R4

Микросхема STM32F100R4 имеет минимальный набор функций. Объем флэш памяти составляет 16 Кбайт, ОЗУ – 4 Кбайт, тактовая частота составляет 12 МГц. Если требуется более быстрое устройство с увеличенным объемом флэш-памяти до 128 Кбайт, подойдет STM32F101RB.

Расширение озу в микроконтроллерах stm32

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

Таблица 3. Объем графической памяти для различных разрешений

РазрешениеЧисло пикселейОбъем буфера ОЗУ, кбайт
8-бит16-бит24-бит32-бит
QVGA (320×240)7680075150225300
HVGA (480×320)153600150300450600
VGA (640×480)3072003006009001200
WVGA (800×480)38400037575011251500
SVGA (800×600)48000046993814071875
XGA (1024×768)786432768153623043072

Как уже говорилось выше, для расширения объема ОЗУ микроконтроллеров STM32 используется встроенный контроллер внешней памяти FSMC или FMC. FSMC-контроллер работает только со статическим ОЗУ. FMC-контроллер присутствует в старших линейках микроконтроллеров и способен работать также и с SDRAM.

FMC-контроллер топовых семейств STM32 включает в себя три полноценных контроллера для следующих типов памяти: NOR/PSRAM, NAND, Synchronous DRAM (SDRAM/Mobile LPSDR SDRAM) (рисунок 11).

Для подключения различных типов памяти используются различные наборы сигналов, при этом выводы шины адреса и шины данных оказываются общими. Максимальная разрядность шины адреса составляет 26 бит, а шины данных – 32 бита.

Ключевыми особенностями FMC-контроллера семейства STM32H7 являются:

  • поддержкаразличныхтиповпамяти (SRAM, NOR Flash /OneNAND Flash, PSRAM, NAND Flash, SDRAM (SDRAM/Mobile LPSDR SDRAM);
  • программируемые тайминги для синхронного и асинхронного обмена;
  • 8-/16-/ 32-битная шина данных;
  • до четырех банков памяти;
  • встроенный FIFO-буфер для записи 16×32-бит;
  • FIFO-буфер 6×64-бит для SDRAM.

С точки зрения построения графических приложений именно SDRAM является оптимальным выбором в качестве экранного ОЗУ. При этом чем больше разрядность и скорость обмена – тем выше будет качество и плавность графического интерфейса.

Стоит отметить, что для оптимальной работы с FMC/FSMC-контроллером логично использовать контроллер прямого доступа к памяти DMA, чтобы разгрузить процессор. Речь идет как о DMA общего назначения, так и о специализированном графическом ускорителе Chrom-ART(DMA2D).

Оцените статью
Радиокоптер.ру
Добавить комментарий