Полноценный трехпортовый usb-serial адаптер на stm32 blue pill (stm32f103c8t6)

Board pinout

Information

Only the labels printed in blue/white or green/white (i.e. PC_13, PB_9, A0, D14 …) must be used in your code. The other labels are given as information (alternate-functions, power pins, …). You can also use these additional pin names:

LED1=PC_13  SERIAL_TX=PA_2  I2C_SCL=PB_8  SPI_MOSI=PA_7  PWM_OUT=PB_3
            SERIAL_RX=PA_3  I2C_SDA=PB_9  SPI_MISO=PA_6
                                          SPI_SCK =PA_5
                                          SPI_CS  =PB_6

Please notice that in order to fit the small size board, the leading ‘P’ and the ‘_’ characters are omitted from labels indicated on the board (e.g. Instead of ‘PA_1’ you can find the label ‘A1’ on the board). Arduino (green/white) and the additional naming labels are not indicated on the board.

Also notice that the on-board LED is connected to pin PC_13 and, via a resistor, to +3.3V. So to turn the LED or you have to set the DigitalOut to or respectively.

Регистры CR и CFGR

Открываем Reference manual на микроконтроллер STM32F103x8 и переходим к разделу 7: Low-, medium-, high- and XL-density reset and clock control (RCC). RCC имеет довольно много регистров, целых 10 штук. Однако, для настройки источника тактирования и делителей шин нам понадобится только 2 из них.

Clock control register (RCC_CR)

Рис. 1. Биты регистра CR

Описание основных битов регистра:

PLLRDY — флаг готовности PLL. Устанавливается аппаратно и сигнализирует о том, что PLL заблокирован.

PLLON — Включить PLL. Устанавливается и сбрасывается программно. При переходе в режим Stop или Standby сбрасывается аппаратно. Этот бит не может быть сброшен, если PLL используется как источник системного тактирования.

CSSON — включить систему CSS

HSEBYP — Если вместо кварцевого резонатора HSE мы хотим использовать внешний прямоугольный тактовый сигнал, то этот бит нужно установить в 1

HSERDY — Флаг готовности генератора HSE. Аппаратно устанавливается в 1 после успешного запуска и стабилизации частоты HSE-генератора

HSEON — Запустить HSE генератор. Устанавливается и сбрасывается программно. При переходе в режим Stop или Standby сбрасывается аппаратно и HSE генератор останавливается.  Этот бит не может быть сброшен, если HSE используется как источник системного тактирования.

HSIRDY — то же самое, что и HSERDY, только для встроенного RC-генератора HSI

HSION — то же самое, что и HSEON, только для встроенного RC-генератора HSI

Clock configuration register (RCC_CFGR)

Рис. 2. Биты регистра CFGR

Описание основных битов регистра:

MCO — подача тактового сигнала на MCO-пин микроконтроллера.

  • 0xx: Функция отключена
  • 100: Выбран System clock (SYSCLK)
  • 101: Выбран сигнал с HSI
  • 110: Выбран сигнал с HSE
  • 111: Выбран сигнал с PLL, который поделен на 2

PLLMUL — коэффициент умножения PLL. Эти биты могут быть записаны программно только при отключенном PLL

  • 0000: Входную частота PLL умножить на 2
  • 0001: —//— на 3
  • 0010: —//— на 4
  • 0011: —//— на 5
  • 0100: —//— на 6
  • 0101: —//— на 7
  • 0110: —//— на 8
  • 0111: —//— на 9
  • 1000: —//— на 10
  • 1001: —//— на 11
  • 1010: —//— на 12
  • 1011: —//— на 13
  • 1100: —//— на 14
  • 1101: —//— на 15
  • 1110: —//— на 16
  • 1111: —//— на 16

Два последних значения соответствуют одинаковому коэффициенту умножения.

PLLXTPRE — Делитель частоты с HSE генератора перед подачей на PLL. Этот бит не может быть изменен, если PLL запущен. При установке в 1 частота HSE будет поделена на 2, если 0, то делитель отключен.

PLLSRC — Источник входной частоты PLL. Не может быть изменен, если PLL запущен.

  • 0: частота HSI генератора поделенная на 2
  • 1: частота HSE генератора. Делитель может быть выбран PLLXTPRE битом.

PPRE2 — Делитель шины APB2 prescaler

  • 0xx: HCLK без деления
  • 100: HCLK / 2
  • 101: HCLK / 4
  • 110: HCLK / 8
  • 111: HCLK / 16

PPRE1 — Делитель шины APB1 prescaler. Частота шины APB1 не должна превышать 36 МГц.

  • 0xx: HCLK без деления
  • 100: HCLK / 2
  • 101: HCLK / 4
  • 110: HCLK / 8
  • 111: HCLK / 16

HPRE — AHB prescaler

  • 0xxx: SYSCLK без деления
  • 1000: SYSCLK / 2
  • 1001: SYSCLK / 4
  • 1010: SYSCLK / 8
  • 1011: SYSCLK / 16
  • 1100: SYSCLK / 64
  • 1101: SYSCLK / 128
  • 1110: SYSCLK / 256
  • 1111: SYSCLK / 512

SWS — Состояние переключателя тактирования системы. Устанавливается аппаратно и указывает на текущий источник тактирования.

  • 00: HSI генератор используется как источник тактирования системы
  • 01: HSE генератор используется как источник тактирования системы
  • 10: PLL используется как источник тактирования системы

SW — Переключатель источника тактирования системы. Изменяется программно для выбора источника SYSCLK. Устанавливается аппаратно для принудительного переключения на HSI генератор переходе в режим Stop или Standby или в случае срыва генерации HSE, который используется в качестве источника SYSCLK (только если активна система CSS)

  • 00: HSI выбран в качестве источника системного тактирования
  • 01: HSE выбран в качестве источника системного тактирования
  • 10: PLL выбран в качестве источника системного тактирования

Установка PlatformIO для работы с Arduino Uno

Как уже указывалось, ядро PlatformIO написано на Python 2.7, поэтому PlatformIO не поддерживает Python 3. В связи с этим рекомендуется установить Python версии 2 и затем переходить к установке PlatformIO IDE. PlatformIO представляет собой интегрированную среду разработки (IDE) и содержит в себе еще дополнительные инструменты (плагины, расширения) для работы с другими популярными IDE.

Можно произвести установку PlatformIO с такими текстовыми редакторами как Atom и Visual Studio Code. Нужно выбрать один из них. Если вы хотите больше кастомизации, всяких крутых плагинов и экспериментов – выбирайте Atom, если же вам нужно просто красивую, удобную IDE с отличным автодополнением кода из коробки, выбирайте Visual Studio Code. В этой статье мы выбрали Visual Studio Code.

Перейдем к установке PlatformIO для последующей разработки в ней кода для Arduino Uno.

Вначале установите Visual Studio Code с ее официального сайта. Ее установка ничем не отличается от установки обычных программ для Windows, поэтому здесь процесс ее установки мы рассматривать не будем.

Когда Visual Studio Code будет установлена она будет выглядеть примерно следующим образом:

Следующим шагом мы будем устанавливать PlatformIO используя VS Code Extensions (расширения кода для Visual Studio). Для этого в левом сайдбаре выберите квадратную иконку (пятую по счету если считать сверху) как показано на следующем рисунке. После клика на этой иконке в основном окне появится окно поиска (search box), в котором вы можете найти расширения для большинства известных языков программирования: C/C++, C#, Python, PHP, Go, JavaScript, TypeScript, Node.js и т.д.

Запустите в этом окне поиск “PlatformIO”, в результате этого вы увидите иконку PlatformIO с именем и описанием. Просто кликните на ней и установите PlatformIO. При этом может потребоваться некоторое время для установки наборов инструментов и других дополнений.

Когда процесс установки будет завершен, вы увидите интерфейс, показанный на следующем рисунке. Интерфейс включает все необходимые компоненты: New Project (новый проект), Import Arduino Project (импортировать Arduino проект), Open Project (открыть проект), Project Examples (примеры проектов) и т.д. После установки PlatformIO рекомендуется перезапустить Visual Studio Code Editor.

После этого PlatformIO будет готова к использованию. В ней мы запустим простую программу мигания светодиодом и загрузим ее в плату Arduino Uno.

Основные возможности TrueStudio

Программная платформа. TrueStudio является полноценной интегрированной средой разработки встраиваемого ПО для микроконтроллеров STM32 (рисунок 8). Внешне TrueStudio чрезвычайно похожа на AC6 System Workbench. Это не удивительно, так как обе среды используют платформу Eclipse. Сходство на этом не заканчивается. В основе TrueStudio лежат те же открытые проекты компилятора GCC и отладчика GDB.

Рис. 8. Интерфейс TrueStudio

Поддерживаемые микроконтроллеры. TrueStudio работает только с STM32 и поддерживает все микроконтроллеры семейства. Кроме того, в TrueStudio есть поддержка большинства плат от STMicroelectronics. Пользователь может открыть готовые демонстрационные проекты без скачивания каких-либо дополнительных файлов.

Работа с проектами. TrueStudio позволяет создавать и редактировать проекты, написанные на С/С++. Существует возможность создания дерева проектов, что весьма удобно при параллельной работе с несколькими приложениями.

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

Компиляция и построение проекта. Как было сказано выше, TrueStudio использует GCC для компиляции проекта. При этом возможна оптимизация кода в процессе компиляции.

TrueStudio дает пользователям возможность ручного размещения кода и данных в памяти микроконтроллера.

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

Отладка. TrueStudio поддерживает работу с использованием всех популярных отладчиков, в том числе, ST-Link, SEGGER, P&E micro и др.

Среда имеет поддержку точек останова и пошагового выполнения. В процессе отладки программист получает доступ ко всем регистрам и памяти. Кроме того к услугам пользователя также предлагаются различные анализаторы (памяти, стека, ошибок).

Стоит отметить, что процесс отладки в TrueStudio мало чем отличается от работы с другими аналогичными средами.

Поддержка систем контроля версий. TrueStudio обеспечивает одновременную работу нескольких пользователей над проектом за счет поддержки систем контроля версий: CVS, SVN, Git.

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

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

Небольшой проект, демонстрирующий взаимодействие STM32Cube и TrueStudio, представлен в видеоролике, дополняющем данную статью. В этом проекте STM32Cube используется для настройки таймера TIM4, выходные каналы которого управляют яркостью светодиода с помощью ШИМ. Отладка выполняется с помощью TrueStudio и платы STM32F4DISCOVERY.

Что еще?

Здесь мы не рассмотрели еще некоторые блоки системы тактирования, о которых хочется упомянуть.

Clock security system (CSS) — переводится примерно как «система безопасности тактирования». Если, при использовании генератора HSE в качестве источника тактового сигнала для SYSCLK или PLL, произойдет срыв генерации HSE, то CSS автоматически переключит всю систему на работу от встроенного RC-генератора HSI. Таким образом, если что-то случится с кварцем, система не зависнет намертво в неопределенном состоянии, а сможет выполнить какие-то действия, например, перевести объект управления в безопасное состояние (закрыть все вентили, отключить силовые установки, и т.д.)

Модуль часов реального времени RTC может тактироваться от встроенного LSI генератора на 40 КГц, от HSE через делитель на 128, либо от LSE с внешним кварцем на 32768 Гц. Источник тактовых импульсов выбирается с помощью RTCSEL.

Модуль USB получает тактовый сигнал от PLL, причем при частоте на выходе PLL равной 72 МГц есть возможность активировать USB Prescaler с коэффициентом деления 1.5 для получения необходимой частоты 48 МГц.

Microcontroller clock output (MCO) — вывод микроконтроллера, на который можно вывести частоту от одного из источников сигнала: SYSCLK, HSE, HSI либо сигнал с выхода PLL, поделенный пополам. Нужный источник выбирается с помощью битов MCO.

Перечень проектов

Example_First_Programm — GPIO. Первая программа. Мигание светодиодом

Example_GPIO — GPIO. Пример работы с входами и выходами

Example_StepMotor — GPIO. Пример работы с шаговым двигателем 28BYJ-48

Example_Nokia5110 — GPIO. Remap. Пример работы с выходами

Example_WG12864A — GPIO. Пример работы с LCD дисплеем WG12864A (KS0108/KS0107)

Example_ADC — ADC. Простой пример работы с АЦП

Example_ADC_DMA — ADC. Работа с АЦП с использованием DMA

Example_ADC_Injected — ADC. Работа с АЦП с настройкой Injected каналов

Example_ADC_Temperature — ADC. Использование встроенного термометра

Example_ADC_Watchdog — ADC. Аналоговый Watchdog

Example_Sonar — EXTI. Пример работы с сонаром HC-SR04

Example_USART1 — USART. Пример простого терминала

Example_USART_DMA — USART. Отправка данных через последовательный порт с помощью DMA

Example_DFPlayerMini — USART. Пример работы с MP3 плеером DFPlayer Mini. Функция произнесения числа

Example_SysTick — Таймер. Системный таймер SysTick. Задержка на SysTick

Example_TIM_CLK — Таймер. Генерирование прерывания через равные промежутки времени

Example_TIM_Time — Таймер. Измерение времени между двумя событиями

Example_PPM — Таймер. Захват сигнала

Example_Encoder — Таймер. Работа с энкодером

Example_Encoder_IT — Таймер. Работа с энкодером

Example_PWM_LED — Таймер. PWM. Управление яркостью светодиода

Example_PWM_RGB — Таймер. PWM. Управление цветом RGB светодиода

Example_PWM_Servo — Таймер. PWM. Управление сервоприводом

Example_PWM_Sound — Таймер. PWM. Генерирование звука

Example_RTC — RTC. Пример работы с часами реального времени

Example_BKP — BKP. Пример работы с регистрами Backup registers

Example_FLASH — FLASH. Пример сохранения настроек во FLASH память

Example_Watchdog — Watchdogs. Пример использование IWDG и WWDG

Example_I2C_Master — I2C. Работа с шиной I2C на примере датчика атмосферного давления BMP280

Example_I2C_Slave — I2C. Работа с шиной I2C в качестве Slave устройства

Example_BMP280 — I2C. Пример работы с датчиком атмосферного давления BMP280

Example_MS5611 — I2C. Пример работы с датчиком атмосферного давление MS5611

Example_USB_Virtual_Com_Port — USB. Пример работы с USB. Виртуальный последовательный порт

Example_USB_Keyboard — USB. Пример работы с USB. Эмуляция клавиатуры и мышки

Example_USB_Mass_Storage — USB. Пример работы с USB. STM32F103 в качестве Mass Storage Device

Example_PWR_Sleep — PWR. Использование энергосберегающего режима SLEEP

Example_PWR_Stop — PWR. Использование энергосберегающего режима STOP

Example_PWR_Standby — PWR. Энергосберегающий режим Standby. Пробуждение от Wake Up Pin

Example_PWR_Standby_RTC — PWR. Энергосберегающий режим Standby. Пробуждение от RTC

Example_Bootloader — Bootloader. Пример собственного загрузчика

Example_BLDC — Управление бесколлекторным двигателем с датчиками Холла (Sensored Brushless)

Example_PMSM — Управление PMSM с датчиками Холла с помощью STM32

Смотри также:

  • 1. STM32. Программирование STM32F103. Тестовая плата. Прошивка через последовательный порт и через ST-Link программатор
  • 2. STM32. Программирование. IDE для STM32
  • 3. STM32. Программирование STM32F103. GPIO
  • 4. STM32. Программирование STM32F103. Тактирование
  • 5. STM32. Программирование STM32F103. USART
  • 6. STM32. Программирование STM32F103. NVIC
  • 7. STM32. Программирование STM32F103. ADC
  • 8. STM32. Программирование STM32F103. DMA
  • 9. STM32. Программирование STM32F103. TIMER
  • 10. STM32. Программирование STM32F103. TIMER. Захват сигнала
  • 11. STM32. Программирование STM32F103. TIMER. Encoder
  • 12. STM32. Программирование STM32F103. TIMER. PWM
  • 13. STM32. Программирование STM32F103. EXTI
  • 14. STM32. Программирование STM32F103. RTC
  • 15. STM32. Программирование STM32F103. BKP
  • 16. STM32. Программирование STM32F103. Flash
  • 17. STM32. Программирование STM32F103. Watchdog
  • 18. STM32. Программирование STM32F103. Remap
  • 19. STM32. Программирование STM32F103. I2C Master
  • 20. STM32. Программирование STM32F103. I2C Slave
  • 21. STM32. Программирование STM32F103. USB
  • 22. STM32. Программирование STM32F103. PWR
  • 23. STM32. Программирование STM32F103. Option bytes
  • 24. STM32. Программирование STM32F103. Bootloader
  • STM32. Скачать примеры
  • System Workbench for STM32 Установка на Ubuntu
  • Keil uVision5 – IDE для STM32
  • IAR Workbench – IDE для STM32
  • Управление бесколлекторным двигателем постоянного тока (BLDC) с помощью STM32
  • Управление PMSM с помощью STM32

Загрузка STM32CubeProgrammer

На предыдущем шаге мы выбрали «STM32CubeProgrammer (Serial)» в качестве метода загрузки, но проблема в том, что этот инструмент не загружается и не устанавливается менеджером плат.

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

Будет загружен большой zip-файл (приблизительно 164 МБ для версии 2.3.0). Распакуйте zip-файл, и вы получите исполняемый файл Windows с именем «SetupSTM32CubeProgrammer-2.3.0». Дважды щелкните и продолжите установку.

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

После завершения установки убедитесь, что в пути “C:\Program Files \ STMicroelectronics \ STM32Cube \ STM32CubeProgrammer \ bin” имеется исполняемый файл «STM32_Programmer_CLI». Если он присутствует, то вы можете продолжать.

ПРИМЕЧАНИЕ. Это может быть либо Program Files, либо Program Files (x86) по указанному выше пути.

На этом завершается настройка программного обеспечения для Arduino IDE для программирования STM32 Blue Pill. Давайте приступим к написанию небольшой программы для мигания светодиода и загрузки ее в нашу плату STM32 Blue Pill.

Краткая заметка о плате разработки STM32F103C8T6

На следующем рисунке показана лицевая и задняя стороны типичной платы Blue Pill STM32. Как видите, макет платы очень прост, и некоторые могут даже спутать ее с Arduino Nano.

Важной особенностью этих плат является то, что они очень дешевы, дешевле, чем клонированная версия Arduino UNO. Я получил эту плату примерно за 2,5 доллара в местном магазине электроники. Таким образом, это, очевидно, клонированная версия (возможно, поддельный микроконтроллер STM32). На рынке доступно много клонированных версий этой платы

Особенности платы

  • Она содержит основной микроконтроллер — STM32F103C8T6.
  • Кнопка сброса — для сброса микроконтроллера.
  • Порт microUSB — для последовательной связи и питания.
  • Перемычки выбора BOOT — перемычки BOOT0 и BOOT1 для выбора загрузочной памяти.
  • Два светодиода — пользовательский светодиод и индикатор питания.
  • Кварц на 8 МГц.
  • Кварц 32,768 кГц — часы RTC.
  • SWD Interface — для программирования и отладки с использованием ST-Link.
  • Стабилизатор питания 3,3 В — преобразует 5 В в 3,3 В для питания микроконтроллера.

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

Как видно из приведенного выше изображения, каждый вывод микроконтроллера STM32F103C8T6 может иметь несколько функций (но необходимо выбрать только одну). Также обратите внимание, что некоторые контактыввода / вывода допускают 5 В, что означает, что вы можете подключить 5 В совместимый ввод / вывод на эти контакты без каких-либо проблем

Первая программа

CooCox

Выполняем пункт меню Project -> New

Указываем имя проекта:

Выбираем Чип:

В репозитории выбираем какие именно модули мы будем использовать:

Открываем main.c і набираем следующий код программы:

Компилируем (Project->Build)

При первой компиляции IDE может запросить указать местонахождение компилятора.

Надо корректно указать место, куда был установлен GCC.

После удачной компиляции заливаем программу в микроконтроллер. Эта программа будет мигать светодиодом на плате. Как залить программу в микроконтроллер мы рассматривали в предыдущей статье.

Если Вы будете заливать прошивку через UART с помощью UART-USB переходника, файл для заливки найдете в директории:
C:\CooCox\CoIDE\workspace\Example_GPIO\Example_GPIO\Debug\bin\Example_GPIO.bin

Если у Вас есть установленный ST-Link программатор, программу в микроконтроллер можно залить прямо с IDE (Flash -> Program Download).

Если при этом возникла ошибка «Error: Flash driver function execute error» Рекомендуется:

  1. Запустить STM32 ST-LINK Utility и выполнить Frimware update.
  2. Скопировать файл STLinkUSBDriver.dll из папки
    C:\Program Files\STMicroelectronics\STM32 ST-LINK Utility\ST-LINK Utility
    в папку
    C:\CooCox\CoIDE\bin
    после чего перезапустить CooCox IDE

Прошивка STM32 с помощью USB-Uart переходника под Windows

STM32BootloaderSTM32USARTFT232RLFT232RLftdichip.comVCP

Подключаем RX и TX выходы к соответствующим выводам USART1 микроконтроллера. RX переходника подключаем к TX микроконтроллера (A9). TX переходника подключаем к RX микроконтроллера (A10). Поскольку USART-USB имеет выходы питания 3.3В подадим питания на плату от него.

Чтобы перевести микроконтроллер в режим программирования, надо установить выводы BOOT0 и BOOT1 в нужное состояние и перезагрузить его кнопкой Reset или выключить и включить питание микроконтроллера. Для этого у нас есть перемычки. Различные комбинации загоняют микроконтроллер в различные режимы. Нас интересует только один режим. Для этого у микроконтроллера на выводе BOOT0 должно быть логическая единица, а на выводе BOOT1 — логический ноль. На плате это следующее положение перемычек:

После нажатия кнопки Reset или отключения и подключения питания, микроконтроллер должен перейти в режим программирования.

Using the mbed online compiler to build programs for the STM32F103C8T6 board

Create a program as if it was for a NUCLEO-F103RB board (select NUCLEO-F103RB as target platform for the online compiler).
Or click to import this demo into your online compiler.

Blinking on-board LED:

#include "mbed.h"

Serial      pc(PA_2, PA_3); // TX, RX
DigitalOut  myled(PC_13);   // on-board LED
  
int main() 
{  
    while(1) {
        // The on-board LED is connected via a resistor to +3.3V (not to GND). 
        // So the LED is active on 0
        myled = 0;      // turn the LED on
        wait_ms(200);   // wait 200 millisecond
        myled = 1;      // turn the LED off
        pc.printf("Blink\r\n");
        wait_ms(1000);  // wait 1000 millisecond
    }
}

Warning

Keep in mind that the online compiler is checking for 128kB maximum flash size. However, the STM32F103C8T6 is equipped with only 64kB. Although it seems that majority of Blue Pill boards sold online usually feature 128kB Flash rather than 64kB. Once the compilation is complete (started by clicking on the Build only button in the Compile drop list or by pressing Ctrl+B) you can visually check the size of used flash memory in the Program details — Build tab. In order to fit into an STM32F103C8T6 board the used Flash should not exceed 64kB (depending on your actual board). Try to optimize your program until it’s using less than 64kB flash memory. Have a look at mbed-STM32F030F4 and Andy’s hints for some good tips.

Вступление

В последнее десятилетие Arduino стала платформой для быстрого создания прототипов, хобби-проектов или в качестве платы отладки для начинающих радиолюбителей. Но мы все знаем об ограничениях платы Arduino. Давайте обсудим Arduino UNO, так как это самый популярный Arduino.

Эта плата медленная, работает на частоте 16 МГц, имеет очень ограниченное внутреннее оборудование и не имеет достаточной вычислительной мощности, ОЗУ и Flash для запуска приложения на основе FreeRTOS (теоретически вы можете запустить FreeRTOS на Arduino, но это не практично).

Альтернативой Arduino является плата разработки на основе микроконтроллера STM32F103C8T6, которую часто называют Blue Pill. Этот микроконтроллер основан на архитектуре ARM Cortex-M3 производства STMicroelectronics.

STM32F103C8T6 является очень мощным микроконтроллером и с 32-разрядным процессором легко может превзойти по производительности Arduino UNO. В качестве дополнительного бонуса вы можете легко запрограммировать эту плату, используя вашу Arduino IDE (хотя и с некоторыми хитростями и дополнительным программатором, например конвертером USB в U (S) ART).

И тут нам поможет System Tick Timer! Настраиваем его, отключаем прерывания, не включаем Watchdog (чтоб проц не отвлекался на что-то иное кроме выполнения). Переходим в отладчик, выполняем инструкции по шагам и сравниваем сколько успел насчитать таймер во время выполнения инструкции. Берем два абсолютно одинаковых куска кода и сравниваем кол-во тактов на инструкцию:

Оригинал (STM32F030):

«Китайское» (HK32F030):

Вот блин бабушка и приехали… Инструкции LDR/STR выполняются в полтора раза дольше и те же инструкции тратят на один такт больше если используем Immediate Value… и мало того, — по сути идентичные инструкции выполняются разное кол-во тактов, и ещё опа, — времени банально не хватает на текущую реализацию… Пусть, ядро может работать на 72 MHz, пробуем.

Меняем множитель с 6 на 9. И в теории, времени теперь навалом, а по факту впритык, потому что проц пожирает массу времени на часто используемые команды, подгоняем реализацию под нужные временные интервалы антинаучным методом «подбора» и «научного тыка». И теперь оно работает.

Как использовать выводы BOOT ?

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

Когда контакты BOOT0 и BOOT1 имеют НИЗКИЙ уровень, тогда внутренняя флэш-память выступает в качестве основного загрузочного пространства, а когда BOOT0 — ВЫСОКИЙ, а BOOT1 — низкий, системная память выступает в качестве основного загрузочного пространства. Эти два варианта важны для нас.

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

Загрузив в системную память, т. е. в bootloader ROM, вы можете перепрограммировать флэш-память в своем приложении, используя последовательный интерфейс USART1.

Как только программа будет загружена во флэш-память, вы можете переключить BOOT0 на LOW, чтобы после следующего сброса или включения питания микроконтроллера программа загрузилась из флэш-памяти.

Если вы заметили,  в обоих случаях, т.е. при выборе флэш-памяти и выборе системной памяти в качестве загрузочных пространств, вывод BOOT1 имеет НИЗКИЙ. Только BOOT0 переключается между LOW (флэш-память) и HIGH (системная память).

Для удобства, давайте назовем эти варианты загрузки как режим программирования и рабочий режим. Для режима программирования вывод BOOT0 устанавливается ВЫСОКИМ, а для режима работы вывод BOOT0 — НИЗКИМ (по умолчанию). В обоих режимах контакт BOOT1 остается НИЗКИМ.