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

Плата STM32, которая будет использоваться в этом учебном материале, является не чем иным, как платой разработки на основе микросхемы STM32F103C8T6 на базе микроконтроллера STM32F1, обычно называемой «Blue Pill» в соответствии с синим цветом печатной платы. Blue Pill работает на мощном 32-битном процессоре ARM STM32F103C8T6 с тактовой частотой 72 МГц. Плата работает с логическими уровнями 3,3 В, но ее контакты GPIO были протестированы на устойчивость к 5 В. Хотя она не поставляется с WiFi или Bluetooth, как варианты ESP32 и Arduino, все же она предлагает 20 КБ ОЗУ и 64 КБ флэш-памяти, что делает данное решение достаточным для крупных проектов. Она также имеет 37 выводов GPIO, 10 из которых можно использовать для аналоговых датчиков, поскольку они имеют АЦП, а также другие для SPI, I2C, CAN, UART и DMA. Для платы, которая стоит около 3 долларов это впечатляющие характеристики.
Частота, с которой работает Blue pill, примерно в 4,5 раза выше, чем у Arduino UNO. В качестве примера того, как использовать плату STM32F1, мы подключим ее к TFT-дисплею 1,44 дюймов и запрограммируем ее рассчитать константу «Пи». Мы отметим, сколько времени понадобилось микроконтроллеру, чтобы получить значение, и сравнить его со временем, которое требуется Arduino Uno для выполнения той же задачи.
Схема подключения для этого примера следующая:

Как и в случае с большинством плат, выпущенных не Arduino, необходимо выполнить небольшую настройку, прежде чем плату можно будет использовать с Arduino IDE. Это включает в себя установку файла платы либо через менеджер плат Arduino, либо загрузку из Интернета и копирование файлов в папку оборудования. Маршрут к Board Manager является менее утомительным, и поскольку STM32F1 входит в число перечисленных плат, мы пойдем по этому пути. Начнем с добавления ссылки для платы STM32 в списки предпочтений Arduino. Перейдите в Файл - Настройки, (File - Preferences) затем введите этот URL (http://dan.drown.org/stm32duino/package_STM32duino_index.json) в поле, как указано ниже, и нажмите кнопку ОК.

Теперь зайдите в Инструменты - Плата - Менеджер плат (Tools - Board - Board manager), откроется диалоговое окно с панелью поиска. Найдите STM32F1 и установите соответствующий пакет.

Процедура установки займет несколько секунд. После этого плата должна быть доступна для выбора в списке плат Arduino IDE.
Код будет написан так же, как мы писали бы любой другой скетч для проекта Arduino, с той лишь разницей, что здесь немного иначе ссылаются на контакты. Чтобы иметь возможность легко разработать код для этого проекта, мы будем использовать две библиотеки, которые представляют собой модификации стандартных библиотек Arduino, чтобы сделать их совместимыми с STM32. Мы будем использовать модифицированную версию библиотек Adafruit GFX (https://github.com/rogerclarkmelbourne/Arduino_STM32/tree/master/STM32F1/libraries/Adafruit_GFX_AS) и Adafruit ST7735 (https://github.com/KenjutsuGH/Adafruit-ST7735-Library).
Код для STM32, написанный в Arduino IDE, выглядит следующим образом:
#include <Adafruit_GFX_AS.h> //https://github.com/rogerclarkmelbourne/Arduino_STM32/tree/master/STM32F1/libraries/Adafruit_GFX_AS
#include "Adafruit_ST7735.h" // https://github.com/KenjutsuGH/Adafruit-ST7735-Library
//Обратите внимание, что вам нужно удалить библиотеку Adafruit ST7735 для Arduino
//если она у вас установлена, иначе скетч не скомпилируется
#define cs PA2
#define rst PA4
#define dc PA3
// Определения цветов
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define ITERATIONS 500000L // количество итераций
#define REFRESH_TFT 7500 // обновлять каждые 7500 итераций
#define ACTIVATED LOW
#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
int percent = 0;
int progress = 1;
const int buttonPin = PB9;
int buttonState = 0;
void setup(void) {
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(9600);
tft.initR(INITR_BLACKTAB); //
tft.fillScreen(ST7735_BLACK);
printUI();
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == ACTIVATED) {
removePressKeyText();
drawBar();
startCalculation();
}
else {
}
delay(10);
}
void fillBar(int percent)
{
int counter =60;
percent = map(percent,0,100,5,121);
for(counter = 60; counter<75;counter++)
{
tft.drawFastHLine(5, counter, percent, YELLOW );
}
}
void printUI()
{
tft.setCursor(30,5);
tft.setTextColor(RED);
tft.setTextSize(1);
tft.print("PI BENCHMARK");
tft.setCursor(30,60);
tft.setTextColor(WHITE);
tft.setTextSize(1);
tft.print("PRESS KEY");
tft.setCursor(5,120);
tft.setTextColor(RED);
tft.setTextSize(1);
tft.print("PI:");
tft.setCursor(5,140);
tft.setTextColor(RED);
tft.setTextSize(1);
tft.print("TIME:");
}
void removePressKeyText()
{
tft.setCursor(30,60);
tft.setTextColor(BLACK);
tft.setTextSize(1);
tft.print("PRESS KEY");
}
void drawBar()
{
tft.drawRect(5,60,120,15, YELLOW);
}
void startCalculation()
{
unsigned long start, time;
unsigned long niter=ITERATIONS;
int LEDcounter = 0;
unsigned long i;
float x = 1.0;
float pi=1.0;
Serial.begin(9600);
Serial.print("Beginning ");
Serial.print(niter);
Serial.println(" iterations...");
Serial.println();
start = millis();
for ( i = 2; i < niter; i++) {
x *= -1.0;
pi += x / (2.0f*(float)i-1.0f);
if (LEDcounter++ > REFRESH_TFT) {
LEDcounter = 0;
progress++;
percent = progress*100/(ITERATIONS/ REFRESH_TFT);
fillBar(percent);
}
}
time = millis() - start;
pi = pi * 4.0;
Serial.print("# of trials = ");
Serial.println(niter);
Serial.print("Estimate of pi = ");
String piString = String(pi,7);
String timeString = String(time)+"ms";
Serial.println(piString);
Serial.print("Time: "); Serial.print(time); Serial.println(" ms");
tft.setCursor(40,120);
tft.setTextColor(GREEN);
tft.setTextSize(1);
tft.print(piString);
tft.setCursor(40,140);
tft.setTextColor(GREEN);
tft.setTextSize(1);
tft.print(timeString);
}
Загрузка скетча в STM32f1 выполняется немного сложнее по сравнению со стандартными платами, совместимыми с Arduino. Чтобы загрузить код на плату, нам нужен конвертер данных USB в данные последовательного интерфейса на основе FTDI. Подключите конвертер USB к последовательному порту STM32, как показано на схеме далее.

Затем мы затем изменим положение перемычки состояния платы в положение 1 (как показано на рисунке ниже), чтобы перевести плату в режим программирования. Нажмите кнопку сброса на плате один раз после этого, и мы будем готовы загрузить код.

На компьютере убедитесь, что вы выбрали «Generic STM32F103C board» и выбрали последовательный порт для метода загрузки, после чего вы можете нажать кнопку загрузки. После завершения загрузки установите перемычку состояния в положение «0», это переведет плату в режим работы, и теперь она должна начать работать на основе загруженного кода. В этот момент вы можете отключить FTDI и подать питание на плату через USB. Если код не запускается после включения питания, убедитесь, что вы правильно восстановили перемычку и подали питание на плату.
Вы должны увидеть состояние дисплея, как показано на следующем изображении.

Нажмите кнопку, чтобы начать расчет. Вы должны видеть, как индикатор выполнения постепенно скользит до конца. В конце процесса значение числа Пи отображается вместе со временем, которое потребовалось для расчета.

Тот же код реализован на Arduino Uno. Результат показан на изображении ниже.

Сравнивая эти два значения, мы видим, что «Blue Pill» более чем в 7 раз быстрее, чем Arduino Uno. Это делает ее идеальным для проектов, которые включают в себя тяжелую вычислительную обработку и временные ограничения. Небольшой размер этой платы также служит здесь преимуществом, так как она только немного больше, чем Arduino Nano, и ее можно использовать там, где Nano не будет достаточно быстрым.
© digitrode.ru