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

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

Приступим к первоначальной настройке и подготовке 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.

Радиокот :: микроконтроллеры. начало. stm32.

РадиоКот >Статьи >

Микроконтроллеры. Начало. STM32.

Микроконтроллеры для котят

Всем Мяу, котаны 🙂

Как-то раз от меня ушла кошка 🙁 Ну и чем валерьянку лопать, я решил заняться делом, так сказать «на благо Родине». Давно уж хотел цифровыми устройствами заняться, да времени не было (сами понимаете, то спать, то с кошкой по крышам гулять), а тут как раз время-то и появилось. Ну-с начнём..)

Всё как обычно начинается с выбора. Ну вроде выбор-то небольшой PIC, да AVR. Последние мне как-то больше приглянулись. Нужен был ещё и USB программатор за неимением других портов на компьютере, от цены которого у меня чуть хвост не отвалился. Ещё Arduino есть – зверёк такой. Его и программировать по USB можно. Ну, думаю, “то что доктор прописал”. В селе нашем его только через интернет-магазин достать можно. Нашёл, где по-выгодней, чуть не купил и… ОПА! Смотрю – STM32VL-Discovery. Что за зверь такой? Хм, STM32.. Что-то слышал краем уха.. А от характеристик усы дыбом, честно!

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

А лап-то у неё сколько!

Итак, попорядку:

  • У Arduino 14 цифровых портов ввода/вывода и 6 аналоговых входов. У STM32VL-Discovery 45 цифровых входа/выхода 10 из которых по желанию превращаются в аналоговые входы.
  • У Arduino 32 Кб для хранения программы и 2 Кб ОЗУ. У STM32VL-Discovery 64 Кб для хранения программ и 8 Кб ОЗУ.
  • У Arduino тактовая частота 16 МГц у STM32VL-Discovery же 24 МГц.
  • Любой микроконтроллер STM32 можно заменить другим STM32, но с лучшими характеристиками, без изменения схемы
  • STM32 можно программировать без программатора по COM порту (об этом чуть позже)
  • Цена Arduino на момент написания статьи ~1300 рублей, STM32VL-Discovery ~600 рублей. Это ж дешевле более чем в 2 раза!

А что дальше? В STM32VL-Discovery есть встроенный программатор/отладчик, который лёгким движением лапы (снятием перемычек) может программировать и отлаживать (отладка очень уж вещь полезная, но об этом чуть позже) микроконтроллеры STM32 за пределами платы. С Arduino такое не прокатит. То есть используя STM32VL-Discovery мы и деньги экономим и получаем большую производительность и свободу творчества 🙂

Да и сами микроконтроллеры STM32 выглядят привлекательней остальных:

 STM32F100C4T6BATtiny24A-SSUPIC16F688-I/SLSTM32F103RET6ATmega1284P-PUPIC18F4550-I/PT
Средняя цена, руб606560240330220
Тактовая частота, МГц242020722048
Flash память, Кбайт162451212816
RAM, Байт409612825665536163842048
USART, шт252
SPI, шт1131 1
АЦП, шт16x12Bit8x10Bit8x10Bit16х12Bit8x10Bit13x10Bit
ЦАП, шт1x12Bit2х12Bit
Количество линий ввода/вывода, шт371212513235

А ещё STM32 32-х разрядные, а это означает возможность работы с 32-х битными данными за один такт. AVR и PIC этим не похвастаются.

Ну что, котаны, убедил? Тогда начнём курс молодого бойца цифровика!)

Как известно, все коты очень любознательные, а радиокоты особенно!

Микроконтроллер – это микросхема сочетающая в себе функции процессора, периферии, имеющая ОЗУ, flash память. Как компьютер, только меньше!

Проведём аналогию: компьютером управляет операционная система, а микроконтроллером «прошивка», которую пишете Вы; операционная система компьютера хранится на жёстком диске, «прошивка» микроконтроллера в его flash памяти; функции ОЗУ схожи – хранение изменяющихся данных во время выполнения программы. А ещё у МК есть различные периферийные устройства, такие как АЦП и ЦАП например.

МК общается с внешним миром при помощи лап на его корпусе (не таких как у котов, конечно, а металлических). Но не все из них управляются программой, есть выводы питания, вывод сброса, выводы питания периферии, вывод резервного питания. А те, которые управляются программой делятся на группы называемые «порты». Все эти управляемые выводы называются 2-мя буквами и цифрой. Например PA1: P – порт, А – порт «А», 1 – номер вывода этого порта.

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

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

  • Цифровой вход – вход, значение которого (логическая 1 или 0) можно считывать программой. Если напяжение на входе 0, то значение равно 0, если на входе напяжение равное напрядению питания, то значение входа 1. Третьего не дано. Можно сделать с подтягивающим резистором либо к питанию, либо к массе
  • Аналоговый вход  – вход значение которого можно считывать программой, но значений может быть много – целых 4096. А точнее от 0 если на входе напяжение 0 относительно минуса питания микроконтроллера до 4095, если на входе напряжение равное напряжению питания. Все эти преобразования делает АЦП – аналогово-цифровой преобразователь, при помощи его можно например измерять напряжение на терморезисторе и узнавать температуру или измерять напяжение на фоторезисторе и узнавать яркость попадающего на него света… Ну много чего можно придумать, если фантазия есть 🙂 Если питать микроконтроллер от 3В, то 0В = 0, а 3В = 4096, значит 3/4096=0.000732421, т.е. при изменении напяжения на входе на 0.000732421В значение входа в программе меняется на 1. Не так-то всё и сложно, да? Идём дальше
  • Цифровой вход в режиме альтернативной функции – вход для работы с периферией. Например вход для таймера или вход для какого-нибудь интерфейса. Из программы значение этого входа считать нельзя. В программе можно например считать данные полученные по этому выводу каким-нибудь интерфейсом.

А у порта настроенного на выход выводы могут быть в таких режимах:

Но не все выводы можно назначать «как захочется». Для того, что бы узнать, что можно, а что нельзя нужно посмотреть документацию (таблица 4) или воспользоваться программой MicroXplorer.

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

Ещё есть выводы BOOT 0 и BOOT 1. Эти выводы не относятся к портам, они служат для управления загрузкой микроконтроллера. Если во время подачи питания на выводе BOOT 0 логический ноль (вывод соединен с общей точкой), то микроконтроллер выполняет программу загруженную во flash память, т.е. Вашу прошивку. Если во время подачи питания на выводе BOOT 0 логическая еденица (вывод соединен с питанием микроконтроллера), а на выводе BOOT 1 логический ноль, то микроконтроллер выполняет не Вашу прошивку, а записанный на заводе загрузчик. Запомните это! Вы будете часто пользоваться этим в процессе работы с микроконтроллерами STM32! Иногда загрузка записанного с завода загрузчика – единственный способ записать/изменить прошивку микроконтроллера. Это бывает например при конфигурировании в прошивке выводов, к которым подключается программатор или при прошивке микроконтроллера без использования программатора. Так что настоятельно рекомендую при проектировании печатной платы эти выводы (или хотя бы BOOT 0) распологать в удобном месте.

Вот разобрались 🙂 Теперь знаем что такое микроконтроллер, из чего он состоит. Сейчас узнаем ещё о некоторых премудростях и перейдём к самому интересному – практике!

Программа в микроконтроллере выполняется пошагово. Один такт процессора – один шаг программы.

Например пусть перемигивается красная и зелёная лампочки, пока НЕ нажата кнопка. Длительность каждой лампы – 5 секунд. Вот алгоритм:

  1. Проверяем, на входе с кнопкой есть напряжение? (кнопка замыкает вывод микроконтроллера на питания)
  2. Если нет напряжения, то загорается красная лампочка на 5 секунд, зелёная тухнет, если есть напряжение, то начинаем всё сначала
  3. Снова проверяем
  4. Если нет напряжение, то загорается зелёная лампочка на 5 секунд, красная тухнет, если есть напряжение, то начинаем всё сначала
  5. Начинаем сначала
Смотрите про коптеры:  Как поставить пароль на вай фай роутер через телефон или компьютер: пошаговый алгоритм установки пароля для популярных брендов

СТОП! А если я нажму кнопку, пока горит лампочка? То ничего не произойдёт! Потому что программа выполняется пошагово, а шаг с проверкой нажатия кнопки находится в момент переключения лампочек.
Вот именно для таких случаев есть такая вещь, как прерывания

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

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

Ну, котята, пора вставать на лапы! Надеюсь у Вас уже есть отладочная плата? Или хотя бы микроконтроллер? Надеюсь есть 🙂 А если нет, то бежим в магазин! (и желательно не за колбасой. хотя…) Какое же это учение без практики?

Отлично на первых порах иметь отладочную плату, например STM32VL-Discovery, но если жаба душит или всё-таки нехватает на колбасу, то можно обойтись и одним микроконтроллером и преобразователем интерфейсов RS-232 ->UART (напр. MAX3232) или USB ->UART (напр. FT232RL). В этом случае в 100 рублей можно вполне уложиться, но придётся делать печатную плату и паять минимум 48 выводов шириной 0,3 мм с зазором 0,2 мм. Я предупреждал.

Сначала нужно естественно прикошачить отладочную плату или контроллер к компьютеру.

Если у Вас отладочная плата:

С отладочной платой, конечно проще. Берём шнурок Mini-USB и соединяем плату с компьютером, все драйверы должны поставиться автоматически. Увидеть STMicroelectronics STLink dongle в диспетчере устройств – хороший знак! Ну а если что-то пошло не так и ничего не вышло – не надо царапать диван, нужно просто зайти сюда и установить STM32 ST-LINK utility.

Ну а если Вы счастливый обладатель компьютера под управлением Windows 8, то перед проведением вышеописанных действий нужно сделать так: Параметры -> Изменение параметров компьютера -> Общие -> Особые варианты загрузки и выбрать параметр Отключение проверки подписи драйверов.

Если у Вас микроконтроллер:

Если у Вас один микроконтроллер, то у Вас должны быть прямые лапы. Но я в Вас не сомневаюсь!

Перед подключением микроконтроллера к компьютеру его нужно припаять к печатной плате. Для этого кроме микроконтроллера и прямых лап нужна как минимум печатная плата. А тут уж Ваше творчество.

Рабочий минимум на схеме ниже:

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

Но это неинтересный минимум.

Добавьте светодиодов и кнопок (не забудьте про выводы BOOT), например так

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

А вот с пайкой этой блохи могут возникнуть проблемы. Но я надеюсь, не возникнут. Я накошачился паять её своим любимым советским 25 Вт паяльником с шириной жала в 3/4 ширины контроллера. У меня больше проблем с изготовлением печатной платы… ну тут уж у каждого своя технология.

И переходник нужно сделать на UART по документации к той микросхеме, которую купили.

Соединяем выводы TxD и RxD на печатной плате с выводами RxD и TxD соответственно переходника. Не забываем про общую точку и питание всего этого.

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

Ну вот, товарищи, и прикошачили. Дальше будем повелевать этой шайтан-машиной 🙂

Выбор и установка ПО

Пользоваться мы будем средой разработки CooCox IDE, но это не просто так, а по нескольким причинам:

Среда разработки – это программа для написания кода, компилятор, отладчик в одном. Удобненько 🙂 Но если какому-то суровому Челябинскому коту удобнее писать код (в блокноте например), компилировать и прошивать разными программами – я не против, тогда Вам пригодится STM32 ST-LINK utilit для загрузки прошивки в микроконтроллер. Хозяин барин, как говорится.

Эта среда разработки основана на многим известном Eclipse.

Итак:

  1. Идём сюда
  2. Тыкаем Download through CoCenter (Recommend)
  3. Вводим адрес эл.почты (можно от балды, он там «для галочки»)
  4. После загрузки устанавливаем этот самый CoCenter
  5. В первой строчке, где написано CooCox CoIDE тыкаем Download
  6. После того, как загрузка закончится, то вместо Download будет Install. Сюда и жмём
  7. Идём сюда
  8. Справа в колонке Download скачиваем файл который .exe. Устанавливаем его.
  9. Открываем сам CooCox CoIDE, вкладка Project, Select Toolchain Path.
  10. Указываем путь к файлу arm-none-eabi-gcc.exe (это мы установили в п.8, путь приблизительно такой: D:Program Files (x86)GNU Tools ARM Embedded4.7 2022q1bin)
  11. Снова открываем CoIDE, нажимаем View -> Configuration, открываем вкладку Debugger и делаем так [фото]
  12. Радуемся, потому что теперь мы можем написать программу и прошить её в микроконтроллер! Чем мы и займёмся.

Если у Вас вариант без отладочной платы/программатора, то для загрузки программы в МК понадобится программка Flash Loader Demonstrator которая находится здесь

Находим общий язык

Перед тем, как писать свою первую программу нужно найти с МК общий язык. Вряд ли он будет учить наш язык, по этому придется выучить (а может просто вспомнить) язык на котором мы будем общаться с МК, это Си. Понадобятся нам только основы (состав программы, функции, операторы). Если язык этот знаете, то можете сразу перейти к пункту «Первая программа», ну а незнающих я введу в курс дела.

Проект состоит из файлов с расширениями .c и .h. В первых находятся функции во вторых названия используемых функций и константы например. Так уж заведено. Самый главный файл, в котором находится код программы main.c. Для использования различных функций нужно подключать библиотеки с этими функциями. Подключаются они записью #include “название_библиотеки” ну библиотеки естественно должны быть в проекте. Подключают их в самом начале файла.

Функции – это своеобразная часть программы. Вообще программа состоит из одной или нескольких функций. Функция имеет вид:

тип_возвращаемой_переменной имя_функции (тип_переменной)
{
Тело функции
}

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

Перед тем, как использовать функцию, её нужно объявить в самом начале файла. Делают это в таком виде:

тип_возвращаемой_переменной имя_функции (тип_переменной);

Ах, да, забыл самое главное! В конце каждой строки должна быть точка с запятой!

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

При запуске, первой всегда выполняется функция main().

Ну с функциями вроде разобрались, понимание придёт только с практикой.

Выше я упоминал тип переменной. Все переменные могут быть разных типов, вот основные:

Строку (слово, предложение) можно представить как массив из символов типа char. Например:

char stroka[5] = “Слово”;

Здесь квадратных скобках – количество символов в строке, «stroka» – название массива.

Перед использованием переменной её нужно обязательно объявить. (просто указать тип переменной и имя)

Дальше по плану операторы. Операторы – символы при помощи которых производятся какие либо операции над переменными.

Например выражение a=b c значит присвоить переменной a значение суммы значений переменных b и c.

Например выражение a значит увеличить значение переменной a на 1 (то же самое, что и a=a 1)

Например выражение a<b становится истинным, если значение переменной a меньше значения переменной b и ложным, если значения равны или a больше b. Выражение a==b истинно если a равно b и ложно, если a не равно b, НО выражение a=b истинно всегда, потому что это не сравнение, это присвоение переменной a значения переменной b.

Например если a=5, b=3, то значение выражения a%b будет равно 2 (т.к. 5/3=1 (ост.2))

Чуть не забыл рассказать про циклы. Основные:

while(условие) {

тело цикла

}

Тело цикла (всё что в фигурных скобках) выполняется, когда условие истинно (пока условие не станет ложным).

Дальше идёт цикл всех циклов. Цикл со счетчиком. Он выполняется определенное количество раз, выглядит он так:

for (начальное_значение; цикл_выполняется_до, шаг) {

тело цикла

{

Начальное_значение – начальное значение счётчика

Цикл_выполняется_до – до достижения какого значения выполняется цикл

Шаг – с каким шагом счетчик считает

Например

for (i=0; i<10, i ) { 

тело цикла

}

Здесь начальное значение переменной i равно 0, цикл выполняется, пока значение переменной меньше 10, при каждом выполнении цикла к переменной i прибавляется 1. Так же можно изменять значение переменной прямо в цикле.

Дальше по плану «условный переход»:

if (условие){

тело 1

} else {

тело 2

}

 В усовном переходе «тело 1» выполняется, если условие истинно и выполняется «тело 2», если условие ложно. Ещё есть такой вариант:

if (условие 1){

тело 1

} else if (условие 2) {

тело 2

}

В этом случае «тело 1» выполняется, если истинно «условие 1», «тело 2» выполняется, если истинно «условие 2». Таких условий может быть сколько угодно, так же может быть одно else.

Условия могут быть простыми и составными: простые – одно логическое выражение, а составное – несколько логических выражений соединённых знаком & (условия истинно, когда все условия соединённые этим знаком истинны) или | (условие истинно, если хотябы одно условие соединённое этим знаком истинно).

Ещё полезная вещь – комментарии. Помогут разобраться в забытом проекте 🙂 или просто что бы что-то не забыть. Комментировать можно или после знаков // и до конца строки или начинаются знаками /* и заканчиваются */, в таком случае комментарий может быть любое количество строк. На размер программы комментарии не влияют.

Ну вот, из основного вроде всё. На первое время хватит (до написания следующей части статьи)

Не будем отступать от традиций (а то мало ли) и начнём с Hello World. А по пути будем продолжать знакомиться с микроконтроллером и так сказать получать опыт.

Открываем среду разработки:

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

Нажимаем Browse in Repository 

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

Выбираем ST

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

И далее свой микроконтроллер.

Потом мы увидим список подключаемых библиотек.

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

Для нашей простенькой программы нам понадобится: CMSIS core, CMSIS Boot, RCC, GPIO.

Библиотеки CMSIS core и CMSIS Boot – системные, их нужно подключать обязательно

Библиотека RCC для работы с системой тактирования

Библиотека GPIO для работы с портами ввода-вывода

Теперь слева в окне Project открываем файл main.c

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

Сначала нужно подключить наши библиотеки (CMSIS подключать не нужно).

Идём в самое начало программы и добавляем строчки:

#include “stm32f10x_gpio.h”
#include “stm32f10x_rcc.h”

Вот так:

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

Далее нужно сделать функцию задержки (не хотим же мы мигать светодиодом с частотой в несколько МГц?).

Смотрите про коптеры:  Пищим двигателями для быстрого поиска упавшего коптера | RCDetails Blog

void Delay(int i) {
for (; i != 0; i–);
}

Так. Тут по порядку, функция ничего не возвращает, по этому void, название функции Delay, сразу объявляем переменную  типа int. В фигурных скобках тело функции – цикл for. Это его строчная запись. Начальное значение i мы не изменяем, цикл выполняется, пока i не равна нулю (как i становится равна нулю, цикл прекращается, функция «выключаеся»). С каждым выполнением тела цикла (тактом) переменная i уменьшается на 1. Т.е. суть цикла – просто повториться количество раз равное i. Пока выполняется цикл время идёт, происходит задержка.

Далее в главной функции main нужно включить тактирование порта, как это сделать можно посмотреть в файле stm32f10x_rcc.h:

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

Какой порт ответственный за какой вывод можно посмотреть в документации к МК:

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

Для тактирования порта С добавляем строчку:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);

Далее нужно настроить выводы. Смотрим, в файле stm32f10x_gpio.h в какой структуре настраиваются выводы:

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

Добавляем в прогармму строчку:

GPIO_InitTypeDef GPIO_Init1;

Этой строчкой мы объявили структуру GPIO_InitTypeDef – дали ей название GPIO_Init для использования в нашей программе далее.

Какие в этой структуре можно настроить параметры и какой вид они имеют, смотрим всё в том же stm32f10x_gpio.h:

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

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

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

Теперь чтобы настроить параметры выводов при помощи структуры нужно написать её название, поставить точку и появится окошечко в котором эти параметры указаны

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

Дважды щёлкаем по одному из них, и он появляется в строке, далее ставим = (присвоить) и прописываем значение из stm32f10x_gpio.h

Так же поступаем со всеми параметрами. Не забываем точку с запятой в конце каждой строки!

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

Далее нужна строка инициализации (не обязательно, но во избежании неприятностей желательна)

GPIO_Init(GPIOC , &GPIO_Init);

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

Теперь будем мигать! Мигать мы будем циклично, сделаем зацикливание в цикле while. Условие цикла будет 1. Еденица – всегда истина, нуль – всегда ложь.. такова се ля ви..

Чтобы подать ток на вывод нужно установить бит, чтобы выключить вывод нужно сбросить бит. Как это делать – всё в том же stm32f10x_gpio.h:

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

Делаем так:

while (1){

GPIO_SetBits(GPIOC, GPIO_Pin_9);

Delay (200000);

GPIO_ResetBits(GPIOC, GPIO_Pin_9);

Delay (200000);

}

1 всегда истина, значит цикл будет зацикливание.

GPIO_SetBits – функция установки бита

GPIO_ResetBits – функция сброса бита

Delay (200000) – на этой строчке выполнение программы переходит в функцию Delay, в ту самую, в которой цикл for. Число 200000 в скобках – передаётся в эту функцию, как переменная i. (помним строчку void Delay(int i)?) и выполняется тот самый цикл в этой функции, все 200000 раз. Это быстро 🙂 после окончания работы цикла for функция Delay заканчивает свою работу, т.к. она void, то она ничего не возвращает и программа продолжает выполняется дальше.

Т.к. while зациклен, то включение светодиода, задержка, выключение светодиода, задержка будут выполняться бесконечно циклично. Пока не выключится питание или не произойдёт прерывание (об этом в следующей статье).

Ну вот, первая программа готова. Теперь нажимаем F7, программа компилируется.

Теперь если у Вас отладочная плата, то подключаем её при помощи USB шнурка и нажимаем Download Code To Flash. Радуемся выполненной работе и полученным знаниям 🙂

А если у Вас не отладочная плата, то подключите к своей плате переходник сделаный ранее, а переходник к COM-порту компьютера. Далее соедините вывод BOOT 0 c плюсом питания микроконтроллера и включите питание микроконтроллера. Тем самым микроконтроллер войдет в режим прошивки. Вообще процедура прошивки не сложная. Нужно просто следовать указаниям приложения Flash Loader Demonstrator. Сначала указываем номер COM-порта, через который у Вас подключен микроконтроллер и скорость. Для воизбежании сбоев, скорость лучше выбрать поменьше

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

Если программа увидела Ваш микроконтроллер, то появится окно, в котором будет написано, сколько у него памяти

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

После нажатия «Next», Вы увидите страницу с адресацией памяти. Она нам не понадобится.

Следующий шаг самый ответственный. Можно выбрать очистку памяти или прошивку

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

Для прошивки выбираем Download to device и в поле Download from file выбираем компилированный .hex файл, который находится в папке CooCox -> CooIDE -> workspace -> имя_проекта -> имя_проекта -> Debug -> Bin. После снова нажимаем «Next».

После того, как увидим такое окно:

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

Отключаем питание микроконтроллера, закрываем Flash Loader Demonstrator, отключаем переходник, и включаем микроконтроллер в обычном режиме (когда при включении вывод BOOT 0 соединен с минусом питания микроконтроллера). Радуемся!

Итак, теперь мы знаем, чем микроконтроллеры STM лучше других, знаем как работает микроконтроллер, умеем прошивать микроконтроллер в отладочной плате и в своей плате, знаем основы языка Си, которые нужны для программирования STM32, получили опыт работы с микроконтроллером (надеюсь положительный) и самое главное, теперь Вы можете воплотить свои идеи цифровых устройств в жизнь (и поведать о них, на нашем любимом РадиоКоте)! Пусть пока ещё простенькие, но всё навёрстывается с опытом. А я постараюсь в следующих статьях рассказать об АЦП, ЦАП, прерываниях, использовании отладки и других полезностях.

Удачного воплощения идей!

Все вопросы, не стесняемся, пишем на форум

А ещё хочу поздравить РадиоКота с его главным праздником! Пусть время и течёт, как флюс из упавшего флакона, но РадиоКот всегда останется нашим незаменимым помощником и приютом для котов (и котят) с паяльниками. Здоровья тебе (все 7 штук), нечеловечьего счастья и сбычи кошачих мечт!

Соблюдай ТБ 🙂

Файлы:
Проект CooCoxIDE



Все вопросы в
Форум.



Эти статьи вам тоже могут пригодиться:

Встраиваемое по

Напишем встраиваемое программное обеспечение для МК. Открываем Keil (или другую удобную для вас среду разработки: IAR, Eclipse/CubeIDE и др., главное, чтобы был установлен CMSIS), создаем проект и настраиваем для работы с нашей «Blue Pill». Если у Вас это вызывает затруднения, то в помощь статья.

Рис. 3 – Периферия, соединенная с шиной APB1
Рис. 3 – Периферия, соединенная с шиной APB1

Настроем систему тактирования. Смотрим в тех. спецификацию (datasheet) (рис. 3). Будем использовать высокоскоростной внутренний тактовый генератор (HSI). Причины почему именно его нет, да и это не является темой статьи. Главное, настроить так чтобы на шине APB1 была частота 36 МГц.

Если все же интересно как настраивать систему тактирования, то можно ввести в поисковике «stm32 cmsis rcc», в интернете информации огромное количество, или почитать Reference Manual (бред, конечно, но вдруг поможет 😊). Здесь я лишь приведу текст функции настройки тактирования с комментариями, она не идеальна, но на данном этапе с задачей справляется:

uint8_t rcc_init(void){
    /* Using the default HSI sorce - 8 MHz */
    /* Checking that the HSI is working */
    for (uint8_t i=0; ; i  ){
        if(RCC->CR & (1<<RCC_CR_HSIRDY_Pos))
          break;
        if(i == 255)
          return 1;          
    }    
    /* RCC_CFGR Reset value: 0x0000 0000 */
    /* PLLSRC: PLLSRC: PLL entry clock source - Reset Value - 0 -> HSI oscillator clock / 2 selected as PLL input clock */
    /* HSI = 8 MHz */
    RCC->CFGR |= RCC_CFGR_PLLMULL9;     /* 0x000C0000 - PLL input clock*9 */
    RCC->CFGR |= RCC_CFGR_SW_1;         /* 0x00000002 - PLL selected as system clock */
    /* SYSCLK = 36 MHz */
    /*Also you can change another parameters:*/
    /* HPRE: AHB prescaler - Reset Value - 0 -> SYSCLK not divided */
    /* HCLK = 36 MHz (72 MHz MAX) */
    /* PPRE1: APB low-speed prescaler (APB1) - Reset Value - 0 -> 0xx: HCLK not divided */
    /* PPRE2: APB low-speed prescaler (APB2) - Reset Value - 0 -> 0xx: HCLK not divided */
    /* APB1 = APB2 = 36 MHz */
    /* ADCPRE: ADC prescaler - Reset Value - 0 -> PCLK2 divided by 2 */
    /* PLLXTPRE: HSE divider for PLL entry - ResVal - 0 -> HSE clock not divided */
    /* USBPRE: USB prescaler - ResVal - 0: PLL clock is divided by 1.5 */
    RCC->CR |=RCC_CR_PLLON;             /* 0x01000000 - PLL enable */
    for (uint8_t i=0; ; i  ){
        if(RCC->CR & (1U<<RCC_CR_PLLRDY_Pos))
            break;
        if(i==255){
            RCC->CR &= ~(1U<<RCC_CR_PLLON_Pos);
            return 2;
        }
    }      
    return 0;
}

Помещаем прототип функции в начало, само тело прячем в подвал, чтобы не мешалось. В функции main вызываем rcc_init().

Создадим функцию и uint8_t can_init(void). Далее текст в теле функции. Включим тактирование CAN:

RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;

CAN RX и TX по умолчанию находятся на выводах PA11 и PA12, соответственно (см. 31 стр. тех. спецификации). Включаем тактирование порта A:

RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

Настраиваем выводы на альтернативную функцию. Настроим сразу и прием (CAN Rx) , но в этой части он на не понадобится:

/* PA11 - CAN_RX */
GPIOA->CRH	&= ~GPIO_CRH_CNF11;   /* CNF11 = 00 */ 
GPIOA->CRH	|= GPIO_CRH_CNF11_1;  /* CNF11 = 10 -> AF Out | Push-pull (CAN_RX) */
GPIOA->CRH 	|= GPIO_CRH_MODE11;   /* MODE8 = 11 -> Maximum output speed 50 MHz */
/* PA12 - CAN_TX */
GPIOA->CRH	&= ~GPIO_CRH_CNF12;	  /* CNF12 = 00 */
GPIOA->CRH	|= GPIO_CRH_CNF12_1;	/* CNF12 = 10 -> AF Out | Push-pull (CAN_TX) */
GPIOA->CRH 	|= GPIO_CRH_MODE12;   /* MODE8 = 11 -> Maximum output speed 50 MHz */

Теперь нам нужен master control register (MCR) Переводим CAN в режим инициализации:

CAN1->MCR |= CAN_MCR_INRQ;              /* Initialization Request */

Отключим режим автоматической ретрансляции. Ретрансляция сообщения происходит при отсутствии подтверждения сообщения, а т.к. в нашей стенде нам принимать сообщение нечем, следовательно, подтвердить прием тоже некому. Кстати, забегая вперед, когда не приходит подтверждение получения сообщения то в CAN error status register (CAN_ESR) в битах 4…6 LEC[2:0]: (Last error code) возникает Acknowledgment Error. При этом поднимаются 4 и 5 бит (0b011).

CAN1->MCR |= CAN_MCR_NART;

Настроим чтобы CAN автоматически выходил из спящего режима (Automatic Wakeup Mode):

CAN1->MCR |= CAN_MCR_AWUM;

Настроим скорость передачи данных. Помним, мы поставили себе задачу, что скорость составляет 250 кБит/с, т.е длительность одного бита: T_bit = 1/(250*1000) = 4 мкс при этом частота шины APB1 f_APB1 = 36 МГц. Далее я приведу рисунок (рис. 4, взял тут), который пояснит некоторые термины и понятия которые будем использовать далее

Рис. 4 – Период импульсов для CAN
Рис. 4 – Период импульсов для CAN

В нашем случае: System Clock = f_APB1 = 36 МГц. CAN System Clock это частота после пред делителя. Теперь посмотрим на CAN Bit Period. Видим, что один БИТ состоит из 4 частей. Первая часть всегда длительностью 1 квант. Вторая и третья часть объединяются в первый сегмент.

Далее идет точка «захвата» бита (Sample Point) и второй сегмент бита. Количество квантов в сегментах выбирается так чтобы точка «захвата» находилась в районе 87,5% длительности бита для протоколов CANopen и DeviceNet и 75% для ARINC 825. Наш вариант 87,5 %.

Вводим данные и нажимаем «Request Table». Ах да, еще есть величина ширина скачка синхронизации (SJW – Synchronization Jump Width) регулирует битовую синхронизацию по мере необходимости. На расчет она не влияет.

Смотрите про коптеры:  Дрон для любителя: устройство и принципы программирования / Хабр

В результате получим таблицу:

Выбираем 2-ю строку исходя из положения точки «захвата» и получаем, что 1 сегменту у нас длиной 13 квантов, а 2-ой – 2 кванта времени, t_Q = 1/(16*250000) = 250 нс, а пред делитель равен 9. Более того, нам даже подсказывают, что нужно записать в регистр CAN_BTR, мы его рассмотрим чуть более детально.

Второй путь расчёта

Решаем задачку как в школе:

Дано:
Скорость передачи, bps = 250 кБит/с
Точка захвата на 87,5 % длины бита, sp = 0,875
Частота шины APB1, f_APB1 = 36 МГц

Решение:
Знаем, что длительность бита равна:
(x y 1)*t_Q = 1/bps (1)
t_Q – длительность кванта времени
Считаем, что пред делитель равен 1 (PreSc = 1), тогда:
t_Q = PreSc/f_APB1 = 27,78 нс

Найти
Длительность 1 и 2 сегментов (x и y, соответственно)

frac{x 1}{x y 1}=sp, (2)

Решаем систему ур-ий (1) и (2), получаем:

x = 125, y = 18, но если посмотреть в ref. manual, то можно заметить, что x (длительность 1-ого сегмента) может принимать значение от 1 до 16. В цикле увеличиваем значение пред делителя на 1 по порядку и решаем систему уравнений для каждого случая. Выбираем наиболее подходящий для нас вариант.

Ответ: PreSc = 9, x = 13, y = 2

Настроим скорость передачи, для этого пойдем в CAN bit timing register (CAN_BTR). Сбросим биты раздела Baud rate prescaler (BRP[9:0]) и установим: BRP[9:0] = PreSc – 1 = 8:

CAN1->BTR &= ~CAN_BTR_BRP;
CAN1->BTR |= 8U << CAN_BTR_BRP_Pos;

Сбросим биты, отвечающие за 1 временной сегмент и установим: TS1[3:0] = 13 – 1 = 12:

CAN1->BTR &= ~(0xFU << CAN_BTR_TS1_Pos);
CAN1->BTR |= 12U << CAN_BTR_TS1_Pos;

Сбросим биты, отвечающие за 2 временной сегмент и установим: TS2[2:0] = 2 – 1 = 1:

CAN1->BTR &= ~(7U << CAN_BTR_TS2_Pos);
CAN1->BTR |=   1U << CAN_BTR_TS2_Pos;

Биты 24…25 SJW[1:0] не трогаем их состояние т. о. получим что ширина скачка синхронизации t_SJW = 2t_Q = 500 нс.

Также в этом регистре можно настроить CAN в режим отладки (Loop back mode, Silent mode), но это не наш случай.

Настроим почтовый ящик номер 0 предназначенный для отправки (transmit mailbox 0). Чтобы добраться до него в структуре типа CAN_TypeDef есть вложенная структура sTxMailBox типа CAN_TxMailBox_TypeDef.  Сообщения, которые будем отправлять из этого ящика содержат данные (data frame), а не запрос (remote frame), сообщим об этом контроллеру:

CAN1->sTxMailBox[0].TIR &= ~CAN_TI0R_RTR;

Будем использовать стандартный идентификатор для кадра:

CAN1->sTxMailBox[0].TIR &= ~CAN_TI0R_IDE;

Отчистим идентификатор и поставим какой душе вздумается (в диапазоне от 0 до 3777):

CAN1->sTxMailBox[0].TIR &= ~CAN_TI0R_STID;
CAN1->sTxMailBox[0].TIR |= (0x556U << CAN_TI0R_STID_Pos);

Теперь сообщим сколько байт полезной информации будет передавать в одном кадре. CAN позволяет передать от 1 до 8. Эх, гулять так гулять, будем передавать 8. Определим это значение в начале файла, т.к. это значение нам еще пригодится в функции отправки сообщения:

#define DATA_LENGTH_CODE 8

и передадим это значение в регистр:

CAN1->sTxMailBox[0].TDTR &= ~CAN_TDT0R_DLC;
CAN1->sTxMailBox[0].TDTR |= (DATA_LENGTH_CODE << CAN_TDT0R_DLC_Pos);

Все, с настройкой закончили. Естественно, дальше нужно будет настроить и прием, функцию будем допиливать, но это отдельная история. Нас пока интересует передача. Переходим из режима инициализации в «нормальный» режим (normal mode). Завершаем функцию. ссылка на полный код в конце статьи.

CAN1->MCR &= ~CAN_MCR_INRQ;
return 0;
}

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

uint8_t can1_send(uint8_t * pData, uint8_t dataLength);

Нам понадобятся 2 счетчика i и j. Первый используем для перебора байтов, второй в случае, если размер кадра будет меньше количество передаваемых байт.

uint16_t i = 0;
uint8_t j = 0;

Проверим есть ли запросы на передачу для 0 почтового ящика, эта информация хранится в CAN transmit status register (CAN_TSR) а именно в 26 бите (TME0). Если есть, ждем, и если ждать придется слишком долго, то функция вернет 1.

while (!(CAN1->TSR & CAN_TSR_TME0)){
    i  ;
    if (i>0xEFFF) return 1;
}

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

CAN1->sTxMailBox[mailboxNum].TDLR = 0;
CAN1->sTxMailBox[mailboxNum].TDHR = 0;

Далее пишем цикл, который постепенно заполняет каждый байт в регистрах данных TDLR и TDHR и делит данные на кадры если нужно передать больше байт чем настроено в DATA_LENGTH_CODE (мы настроили на 8 байт):

while (i<dataLength){
    if (i>(DATA_LENGTH_CODE-1)){
		    CAN1->sTxMailBox[0].TIR |= CAN_TI0R_TXRQ; /* Transmit Mailbox Request */
		    dataLength -= i;
		    j  ;
		    while (!(CAN1->TSR & CAN_TSR_TME0)){      /* Transmit mailbox 0 empty? */
			      i  ;
				if (i>0xEFFF) return 1;
		    }
		    if (CAN1->TSR & CAN_TSR_TXOK0){}          /* Tx OK? */
		    //else return ((CAN1->ESR & CAN_ESR_LEC)>>CAN_ESR_LEC_Pos); /* return Last error code */
		    i = 0;
		    CAN1->sTxMailBox[0].TDLR = 0;
		    CAN1->sTxMailBox[0].TDHR = 0;
    }
		if (i<4){
		    CAN1->sTxMailBox[0].TDLR |= (pData[i j*DATA_LENGTH_CODE]*1U << (i*8));
		}
		else{
		    CAN1->sTxMailBox[0].TDHR |= (pData[i j*DATA_LENGTH_CODE]*1U << (i*8-32));
		}
		i  ;
}

Далее добавляем запрос на передачу оставшихся данных и проверяем, что данные отправились без ошибок или возвращаем код ошибки (мы про этот регистр упоминали ранее):

CAN1->sTxMailBox[mailboxNum].TIR |= CAN_TI0R_TXRQ; /* Transmit Mailbox Request */
if (CAN1->TSR & CAN_TSR_TXOK0) return 0;
else return ((CAN1->ESR & CAN_ESR_LEC)>>CAN_ESR_LEC_Pos);

Теперь в main до бесконечного цикла вызываем функцию настройки can_init(), инициализируем тестовую строку и переменную для счетчика, который будет использоваться для задержки, а то поднимать таймеры в этой статье не будем, дабы не раздувать объем).

uint16_t counter = 0;
uint8_t * data = “ABCDEFGHIJ9”;

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

can1_send(data, sizeof(data));
while(counter<0xFFFF)
    counter  ;
counter = 0;

Все, наша программа готова.

Полный текст программы

Ик-пульт на stm32

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

Здравствуйте.

Описание библиотеки для считывания, декодирования и последующей отправки инфракрасных сигналов от различных бытовых пультов, с помощью микроконтроллера stm32. За основу взята билиотека IRremote для ардуино, и адаптирована под stm32.

Библиотека использует один таймер, и для приёма, и для отправки сигнала. Приёмник подключается к любому пину (GPIO_Input), а передатчик к одному из каналов таймера работающего в режиме PWM Generation (ШИМ). В примере используется первый канал таймера №4 — PB6 (передатчик) и пин PB5 (приёмник).

Для приёма сигнала таймер работает в режиме прерывания — каждые 50 мкс проверяет состояние входного пина, а при передаче переключается в режим PWM Generation, посылает сигнал, и снова переходит в режим прерывания.

Настройки находятся в файле IRremote.h

extern TIM_HandleTypeDef htim4;

// настройка таймера для приема - переполнение каждые 50 мкс (в данном случае системная частота 72Мгц)
#define MYPRESCALER 71 // получаем частоту 1МГц
#define MYPERIOD 49    // 50 мкс

// настройка таймера для отправки - указать системную частоту таймера
#define MYSYSCLOCK 72000000

// настройка пина для приёма recive_IR
#define RECIV_PIN (HAL_GPIO_ReadPin(recive_IR_GPIO_Port, recive_IR_Pin))

Если будете настраивать другой таймер, то нужно указать соответствующее имя структуры — htim4, и то же самое проделать в файлах IRremote.с и irSend.с. Я поленился дефайнить всё это хозяйство. При выборе другого таймера в Кубе, нужно указать только канал и внутренний источник тактирования…

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

Всё остальное программа настроит сама. Если выбрать другой номер канала, то его тоже нужно переименовать в файле irSend.с.

С остальными настройками думаю всё ясно — исходя из системной частоты (в примере 72МГц) подставляются значения предделителя и переполнения для прерывания каждые 50 мкс. Далее указывается частота и чтение пина.

Ниже есть дефайны, которые определяют задействованные протоколы…

//////////////////////////////////// активированные протоколы ////////////////////////////////////////
#define DECODE_RC5           1 // чтоб отключить декодирование протокола RC5 нужно указать 0
#define SEND_RC5             1 // чтоб отключить отправку сигнала по протоколу RC5 нужно указать 0

#define DECODE_RC6           1
#define SEND_RC6             1
...

Отключение ненужных протоколов уменьшает размер программы. В принципе можно вообще выпилить функции неиспользуемых протоколов и соответствующие файлы (файлы имеют характерные имена).

Программа предельно простая, функция my_decode(&results) декодирует полученный сигнал и выводит код кнопки, тип протокола и длину пакета…

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

Других пультов у меня нет.

Для отправки раскодированного сигнала используется функция с соответствующим названием…

sendSAMSUNG(0x707048b7, 32); 
my_enableIRIn();

Функция my_enableIRIn() нужна обязательно, она отключает ШИМ и переводит таймер в режим приёма. Эта же функция используется для инициализации (перед бесконечным циклом). Из-за этой функции не удастся поймать свой собственный сигнал — это можно решить, но смысла в этом не вижу.

Если не удаётся определить тип протокола…

Учебник STM32 - описание, программирование, отличие от Arduino
… то в этом нет ничего страшного, код кнопки в любом случае получен.

Если нужно не только принимать неизвестный сигнал, но и отправлять его, тогда нужно раскомментировать строчки для «вывода данных в сыром виде»…

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

… и отправлять прочитанные данные с помощью функции sendRaw()…

uint8_t khz = 38; // частоту указать экспериментальным путём, основные используемые от 36 до 40 кГц
unsigned int raw_signal[] = {1300, 400, 1300, 400, 450, 1200, 1300, 400, 1300, 400, 450, 1200, 500, 1200, 450, 1250, 450, 1200, 500, 1200, 450, 1250, 1300};

sendRaw(raw_signal, sizeof(raw_signal) / sizeof(raw_signal[0]), khz); 
my_enableIRIn(); // переинициализирование приёма (нужна обязательно)

У меня отправка в «сыром виде» работает плохо.

В библиотеке используется счётчик DWT для микросекундных задержек. На сколько я знаю он есть не у всех stm32, и возможно что не везде одинаково настраивается. Если у вашего камня нет DWT, то надо что-то придумать на замену в функции custom_delay_usec(unsigned long us) в конце файла irSend.с, настройка в начале.

Это всё.

Библиотека

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

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.

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

Adblock
detector