stm32-arduino-ide/

Тема программирования микроконтроллеров ранее многократно поднималась в этом блоге, но исключительно в контексте микроконтроллеров AVR и, соответственно, Arduino . Сегодня же речь пойдет о микроконтроллере STM32F103C8T6 на базе ядра ARM 32 Cortex-M3. Вы наверняка слышали об архитектуре ARM — она используется в большинстве современных телефонов и планшетов, а также Raspberry Pi , полетных контроллерах для квадрокоптеров , и много где еще.

Список покупок

Для повторения шагов из сей заметки вам понадобится следующие железки:

К моменту, когда вы будете читать эти строки, ссылки могут устареть. Однако необходимые товары легко находятся по запросам «STM32F103C8T6 Development Board» и «ST-Link v2 Programmer» как на AliExpress, так и на eBay. Плата также известна под названием «STM32 Blue Pill».

Важно! Заметьте, что USB-разъем на этих платах часто не слишком надежно припаян и может быстро оторваться. Первым делом после покупки рекомендуется его подпаять.

О плате Blue Pill

Ниже приведены некоторые характеристики платы и используемой в ней микроконтроллера:

  • Микроконтроллер 32-х битный;
  • Рабочая частота 72 МГц;
  • 64 Кб flash-памяти;
  • 20 Кб оперативной памяти;
  • Мне удалось насчитать 32 GPIO;
  • 12-и битный АЦП, 10 аналоговых пинов;
  • 16-и битный ШИМ, 15 ШИМ-пинов;
  • 3 UART канала, 2 I2C шины, 2 SPI шины;
  • Возможность отладки по SWD ;
  • Плата питается от 3.3 В;

Расположение пинов (кликабельно — GIF, 1082 x 759, 143 Кб):

Расположение пинов на плате Blue Pill

Для сравнения, Arduino Nano стоит столько же и имеет похожий форм-фактор, но работает на 8-и битном микроконтроллере, имеет частоту 16 МГц, меньше пинов, лишь 32 КБ flash-памяти, 2 Кб оперативной памяти, 10-битный АЦП, 8-и битный ШИМ, по одному каналу UART, I2C и SPI, а про отладку он и вовсе слыхом не слыхивал. То есть, за те же деньги мы получаем куда более мощную железку.

Настройка Arduino IDE

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

Для программирования под данную плату нам понадобится кросс-компилятор для ARM, отладчик, стандартная библиотека C и клиент к программатору. В Arch Linux соответствующие пакеты ставятся так:

sudo pacman -S arm-none-eabi-gcc arm-none-eabi-gdb
arm-none-eabi-newlib stlink

Далее учим Arduino IDE работать с нашей платой:

cd ~ / opt / arduino / hardware
git clone https: // github.com / rogerclarkmelbourne / Arduino_STM32.git

Мне дополнительно пришлось поправить Arduino_STM32/STM32F1/platform.txt:

# compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/
compiler.path=/usr/bin/

… ибо сыпались ошибки про то, что Arduino IDE не может найти исполняемый файл arm-none-eabi-g++ .

После этого если открыть Arduino IDE, то в меню Tools → Board вы обнаружите большой выбор плат на базе микроконтроллеров STM32. Выбираем Generic STM32F103C. В Tools → Upload Method выбираем STLink. Четыре пина на плате с подписями 3.3V, IO, CLK и GND подключаем к пинам 3.3V, SWDIO, SWCLK и GND программатора соответственно. Проверяем джамперы на плате. Оба джампера (так называемые boot0 и boot1) должны стоять в положении 0.

Fun fact! Чтобы постоянно не возиться с проводами при подключении программатора, выясняя, провод какого цвета к какому пину платы нужно подключить в этот раз, можно взять кусок макетки и спаять адаптер на базе разъема IDC-10 . Адаптер подключается к плате через четыре угловых гнезда с шагом 2.54 мм, а затем адаптер подключается к программатору через соответствующий шлейф. Больше никакой путаницы!

Пробуем скомпилировать и залить такой скетч:

void setup ( ) {
pinMode ( PC13, OUTPUT ) ;
}

void loop ( ) {
digitalWrite ( PC13, HIGH ) ;
delay ( 100 ) ;
digitalWrite ( PC13, LOW ) ;
delay ( 100 ) ;
}

Fun fact! В плате Blue Pill светодиод стоит между ногой PC13 и VCC ( схема [PDF] ), а не между ногой и землей, как можно было бы ожидать. Поэтому, подавая HIGH на PC13, мы гасим светодиод, а подавая LOW — зажигаем.

Если при прошивке возникает ошибка:

st-flash 1.3.1
INFO src/common.c: Loading device parameters….
WARN src/common.c: unknown chip id! 0xe0042000

… проверьте, не перепутали ли вы пины CLK и IO, а также попробуйте зажать кнопку Reset на плате.

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

Поздравляю, среда разработки настроена!

Более сложный пример

Ниже приведен код посложнее, демонстрирующий использование ШИМ, аналоговых пинов, а также отладочный вывод по UART:

const int LED1 = PB8 ;
const int LED2 = PB9 ;
const int PTNT = PA0 ;
const int BTN = PB7 ;

int selected_led = LED1 ;
bool btn_was_high = false ;

void setup ( ) {
pinMode ( LED1, PWM ) ;
pinMode ( LED2, PWM ) ;
pwmWrite ( LED1, 0 ) ;
pwmWrite ( LED2, 0 ) ;
pinMode ( BTN, INPUT ) ;
pinMode ( PTNT, INPUT_ANALOG ) ;

Serial. begin ( 115200 ) ;
}

void loop ( ) {
delay ( 100 ) ;

if ( digitalRead ( BTN ) == HIGH ) {
btn_was_high = true ;
} else if ( btn_was_high ) {
btn_was_high = false ;
if ( selected_led == LED1 ) {
selected_led = LED2 ;
pwmWrite ( LED1, 0 ) ;
} else {
selected_led = LED1 ;
pwmWrite ( LED2, 0 ) ;
}
}

int ptnt = analogRead ( PTNT ) ;
int ptnt_mapped = map ( ptnt, 0 , 4095 , 0 , 65535 ) ;

Serial. println ( String ( «ptnt = » ) + ptnt + «, ptnt_mapped = » +
ptnt_mapped ) ;

pwmWrite ( selected_led, ptnt_mapped ) ;
}

Соответствующая цепь, собранная на макетной плате:

Моя первая цепь с микроконтроллером STM32

При нажатии на кнопку один светодиод гаснет, а второй загорается. Яркость свечения светодиода регулируется потенциометром. Как видите, код очень мало отличается от обычного кода для Arduino. Отличаются только названия пинов, а также диапазоны значений, с которыми работают процедуры analogRead и pwmWrite.

Еще больше примеров можно найти в File → Examples → A_STM32_Examples.

Сторонние библиотеки

Многие библиотеки уже портированы под STM32 — Wire, Servo , LiquidCrystal , и другие. А что, если попытаться использовать стороннюю библиотеку с GitHub? Для эксперимента я решил попытаться воспользоваться библиотекой LiquidCrystal_I2C , уже знакомой нам по заметке Об использовании экранчиков 1602 с I2C-адаптером .

Добавляем библиотеку в Arduino IDE:

cd ~ / Arduino / libraries
git clone
https: // github.com / fdebrabander / Arduino-LiquidCrystal-I2C-library.git
. / LiquidCrystal_I2C

Заливаем прошивку:

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd ( 0x3F , PB6, PB7 ) ;

void setup ( ) {
lcd. begin ( ) ;
lcd. setCursor ( 0 , 0 ) ;
lcd. print ( «Current time:» ) ;
}

void loop ( ) {
delay ( 100 ) ;

lcd. setCursor ( 0 , 1 ) ;
unsigned long tstamp = millis ( ) ;
int h = tstamp / 1000 / 60 / 60 ;
int m = ( tstamp / 1000 / 60 ) % 60 ;
int s = ( tstamp / 1000 ) % 60 ;

String line = String ( h ) + «h » +
String ( m ) + «m » +
String ( s ) + «s» ;

int len = line. length ( ) ;
while ( len < 16 ) {
line + = » » ;
len ++ ;
}

lcd. print ( line ) ;
}

Любуемся результатом:

Использование библиотеки LiquidCrystal_I2C на STM32

Стоит помнить, что экранчику нужно 5 В, а плата питается от 3.3 В. Поэтому, чтобы все заработало, плату нужно запитать от USB, а экранчик подключить к пину 5V. Экранчик оказался совместим с 3.3-вольтовой логикой, но в более общем случае может потребоваться преобразователь логических уровней.

Само собой разумеется, не всякая библиотека, написанная под Arduino, так просто возьмет и заработает под STM32. Но, по всей видимости, для многих библиотек это действительно так.

Заключение

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

А программируете ли вы под STM32 и если да, то что для этого используете?

Дополнение: Готовим «взрослую» среду разработки под STM32 в Linux

EnglishRussianUkrainian