STM32 + EmBlocks — мигаем светодиодами

Сегодня я покажу от начала и до конца как создать в EmBlocks простой проект для мигания парой светодиодов.
В качестве отладочной платы мы будем использовать кроху на STM32F103C8.
Вот наш стенд:STM32F103C8-Blink
Подключаем аноды светодиодов к пинам PB5 и PB6, катоды через резсторы в 390 Ом к земле.
Итак, если еще не скачали EmBlocks, сделайте это. Распакуйте в любой удобный каталог и запускайте.
Создаем проект, выбрав в меню «File->New->Project…»
В категории Projects выбираем «STmicro-Arm».
NewProject
Называем проект и выбираем папку, в которой он будет создан. В дальнейшем новые проекты будут автоматически сохраняться там же, если не выберете другую.
ProjectName
В окне выбора компилера ничего не трогаем и двигаем дальше.
В окне выбора процессора из первого списка выбираем «STM32F10x_md» т.к. STM32F103C8 принадлежит к семейству F1 и содержит 64к FLASH, что относит его к medium density девайсам.
Если будете использовать ColinkEx, то выбираем в следующем окне конкретное название процессора, это нужно для прошивки утилитой CoFlash. Если будете пользоваться ST-Link, то можно не трогать.
Галка «Create hex file» отвечает за создание .hex на выходе вместо .elf файла. ColinkEx принимает и те и другие, а вот ST-Link Utility только .hex
STM32 CPU selection
Жмем Finish. Мастер предложит выбрать отладчик и настроить его. Причем дважды — для цели Debug, а затем для Release.. Если будете использовать другой, нажмите отмену и выберите другой отладчик. О других отладчиках расскажу как-нибудь в другой раз.
По-умолчанию предлагается ST-Link, нас это устраивает, поэтому жмем Ok в обоих окнах дважды.
Все, болванка проекта готова. Если теперь нажать F7, проект скомпилируется и готов к прошивке с напоминанием, которое уже учтено в настройках Release цели.

Разберем структуру проекта:

Структура проекта Все файлы проекта автоматически раскладываются по папкам Sources, Headers и ASM Sources для ,.h и .S файлов соответственно. В папке Sources у нас есть подпапка cmsis_boot с файлом библиотеки CMSIS.
В подпапке stm_lib\src у нас уже лежит пара файлов, которые нужны практически в любом проекте:
stm32f10x_gpio.c
stm32f10x_rcc.c

Это части StdPeriph Library для работы с GPIO и системой тактирования.

В подпапке Src лежит файл main.c — заготовка для нашей программы.

В папке Headers заголовки, разложенные по точно таким же папкам.

В дальнейшем нужные части StdPeriph Library мы будем добавлять в подпапки stm_lib\inc и stm_lib\src и включать в проект, щелкнув правой кнопкой по названию и выбрав «Add files…» или «Add files recursively…». Но сегодня нам это не понадобится.

За запуск микроконтроллера отвечает файл startup_stm32f10x_md.S, в папке ASM Sources\cmsis_boot\startup.
Скрипт линкера лежит в папке Others и называется gcc_arm.ld

Cо структурой проекта мы бегло познакомились, пора писать код, ради которого и затевали дело.
Окрываем файл Sources\Src\main.c и заменяем текст в нем на такой:

#include <stm32f10x_conf.h>

#include <stm32f10x_rcc.h>
#include <stm32f10x_gpio.h>
#define RCC_GPIO RCC_APB2Periph_GPIOB
#define LED_PORT GPIOB
#define LED1_PIN GPIO_Pin_5
#define LED2_PIN GPIO_Pin_6

void Delay(volatile uint32_t nCount) {
for (; nCount != 0; nCount--);
}

int main(void) {
/* SystemInit() startup_stm32f10x_md_vl.c */

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_GPIO, ENABLE);

GPIO_InitStructure.GPIO_Pin = LED1_PIN | LED2_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init( LED_PORT , &GPIO_InitStructure);

LED_PORT->ODR ^= LED2_PIN;
while (1) {
LED_PORT->ODR ^= LED2_PIN;
LED_PORT->ODR ^= LED1_PIN;
Delay(0x7FFFF);
}
return 0;
}

Мы определили макросы RCC_GPIO, LED_PORT, LED_PIN1 и LED_PIN2, изменив которые, мы можем подключить светодиоды к пинам другого порта.

В функции main() подаем тактирование на GPIOB и заполняем структуру GPIO_InitStructure, настраивая пины PB5 и PB6 порта GPIOB на работу в режиме PushPull с максимальной частотой 50MHz.
Затем инвертируем состояние LED_PIN2, чтобы светодиоды перемигивались и в цикле переключаем их с небольшой задержкой.

Жмем F7, убеждаемся, что проект собрался без ошибок
Build
Подключаем отладчик ST-Link/v2 к плате и подаем на нее питание например через USB, сняв перемычку P2, чтобы ПК не пытался определить плату как USB девайс, а просто подал питание. Жмем F6, чтобы прошить с помощью ST-Link/V2 или выбираем «Tools->Flash w ST-Link/V2», ждем несколько секунд и если все сделали правильно, то светодиоды начнут моргать попеременно:
Blinking
Чего мы и добивались!
Довольно просто, неправда ли?

Весь процесс занимает примерно минуту. Если у вас все же не получилось, скачайте проект и сравните с тем, что получилось у вас.

STM32 + EmBlocks — мигаем светодиодами: 36 комментариев

  1. Отлично, надо присмотреться на замену тормозного и глючного CoIDE.
    Будет хелп на самостоятельное написание скриптов шаблонов?
    И еще, в сборке не свежий GCC сейчас актуален 4.7q2 а тут 4.7q1.

    • Задавайте вопросы, я посмотрю, проще ответить или написать хелп. Я разобрался, конечно, не во всем, но что-то в процессе изучения узнал.
      Насчет Q1 и Q2 думаю не критично 🙂

      • Ну думаю многое станет понятным, если описать например добавление STM32F4xx, по шагам, чтоб так же появлялся шаблон проекта, чем славится CoIDE.

  2. Я извиняюсь, а дальше мигания диодом в публикациях вообще хоть что-то намечается?

    • Зависит от того, насколько интересно это читателям. Я возможно напишу начальный курс, т.к. все известные мне курсы по STM32 ориентированы на тех, кто уже в теме МК.
      Пишите, что бы вы хотели увидеть, от вас зависит, буду ли я писать дальше. Данная статья — только иллюстрация по применению EmBlocks.

      • Все таки думаю интересно в первую очередь это настройка этой IDE под АРМ, так как в сети нет ни чего конкретного про это. Может быть допилить совместно до уровня CoIDE?

        • В том-то и дело, что под ARM ее не нужно пилить.
          То, что я выложил — готовая среда разработки.
          Единственное, что нужно -подредактировать оставшиеся шаблоны проектов под другие категории процов. До CoIDE не хватает только репозитария с библиотекой драйверов. Пока только вручную — нужно кинуть файлики в папку и добавить их в проект. Это чуть-чуть дольше чем в CoIDE. Насчет того, чтобы автоматизировать это скриптами не знаю, можно ли.

          • Может вариант, как дополнительно в tools программу, которая получив путь к проекту и тип процессора добавляет через галочками нужное. В принципе могу набросать такое приложение, только знать бы как входные параметры передаются от IDE.
            Впрочем, можно по умолчанию добавлять все стандартные из SPL, не думвю что это будет плохо.

        • Из SPL можно и сейчас добавить как нефиг делать. Достаточно просто будет комментарии отключать в файле и все. Вопрос в других библиотеках, которые не входят в SPL.

  3. Уважаемый автор, разбирался с Вашим проектом, пытался найти где же вы определили переменный среды. Я нашел в файле проекта :

    Add option=»-DSTM32F10X_MD» /
    Add option=»-DUSE_STDPERIPH_DRIVER» /

    Собственно, облазил все настройки иде, но так и не нашел этого.
    Вы просто добавили эти строки в файл проекта, или я плохо искал?

    • Да, плохо искал:

      Причем эти переменные добавляются визардом создания проекта автоматически

      • Спасибо, я потом уже и сам таки нашел. 🙂 Скачал Вашу версию емблокс, создал проект, там тоже обнаружил эти дефайны, и потом уже нашел , где это у Вас в визард скрипте добавлено. В нативной версии этого нет (юз_ст_др).

        Я вот смотрю на картинку и вижу , что у вас определен ассерт, Вы не смогли настроить без этого дефайна в этом месте?

        Вот уже новая версия емблокс 1.2 вышла. 🙂

        • Да, в одном из проектов FillAssert включать не хотел, а без него не компилировалось. Вот и включил в проект.
          В нативной конечно нет, там много чего не так, как мне нужно. Поэтому и взялся настраивать.
          Версию 1.2 тоже можно донастроить, это не слишком сложно.

  4. Еще есть вопросик. Конечно, вызван он в основном моим малым опытом, и касается более общей темы чем емблокс, но все же буду очень признательным за ответ, либо за направление в поиске ответа.

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

    Вопрос, есть какое то общее правило включение файлов в проект?
    Каким образом кокос находит имплементацию функций, если подключены хедеры?

    • Советую почитать вообще как работает компиляция и сборка.
      Если кратко — сначала файлы обрабатываются препроцессором, разворачивая макросы.
      Потом компилятор обрабатывает файлы, превращая их в объектные файлы — по сути чистый бинарный код.
      Потом линкер собирает из них готовый файл, раскладывая по местам.
      Так вот, директивы #include нужны для компилера, чтобы знать как вызывать функции, которые определены не в текущем файле. Такие определения и помещаются в заголовочные ( .h) файлы.
      А уже .c/.cpp файлы компилируются по списку файлов, включенных в проект и складываются в .o файлы вне зависимости от того нужны они или нет.
      Линкер потом берет эти файлы и по правилам, прописанным в gcc_armюдв собирает .bin.
      Где искать .h файлы прописано на вкладке «search directories» диалога «build options» проекта.

  5. Подскажи пожалуйста, обязательно ли использование отладчиков для прошивки?
    Где-то пишут, что можно прошить через USB, если это так, то, может добавить как вариант такой прошивки в вашу статью?
    Ибо плату заказал, но неохота ещё искать прошивальщики всякие… Если уже есть USB-порт, зачем ещё что-то.

    • Не обязательно. Но и через USB не получится без USB-UART адаптера. Варианты прошивки я описывал — либо через отладчик, либо через встроенный бутлоадер на манер Arduino, только он тут нестираемый и не занимает доступной программисту flash памяти. есть вариант написать DFU бутлоадер, который будет заниматься самопрограммированием по USB, но это существенно сложнее и его все равно придется сначала залить как-то.

  6. Здравствуйте.
    Помогите, пожалуйста, в прошивке этого девайса через USB.
    Вообще это мой первый контроллер, и я в этом совсем новичек. В программировании опыта хватает, с пальяником только в школе дружил. После первой Вашей статьи про STM32 на хабре сразу заказал его (такой же как на фотке STM32F103C8T6) с aliexpress вместе с usb-uart адаптером (на FTDI).
    Подключил четыре провода (rx-tx, tx-rx, gnd-gnd, vcc-5v) от переходника к stm32. Прочитал несколько пошаговых мануалов по прошивке через программу ST Flash Loader Demo, но никак не могу понять, что делать с джамперами boot0, boot1, зачем на плате кнопка s1, и нужно ли подавать питание через usb на плату stm32, или хватит питания от переходника?
    Написано, что для прошивки нужно boot1 соединить с землей (насколько понимаю это ближнее к краю платы положение джампера), а на boot0 подать 3.3В (дальнее от края платы положение). Подключил, замерял тестером, вроде все на месте. Теперь не понятно, что и в каком порядке дальше делать — то ли кнопку s1 нажимать, то ли питание подавать после подключения, и в нужно ли переставлять назад перемычку, в какой момент подключать переходник.
    Перепробовал несколько вариантов, но Flash Loader Demo так и не смог соединиться с девайсом.
    Переходник определяется в системе как USB Serial Port (COM5).
    Выбираю в программе COM5 (пробовал скорости от 2400 до 115200), жму Next и через секунд 5-10 появляется в разных случаях одно из сообщений «No response from the target, the Boot Loader can not be started. …….» или «Unrecognized device… Please, reset your device then try again». Второе сообщение показывается, когда на boot0 — 0, на boot1 — 1. При этом при запущенной программе мигает красный светодиод (RX) на переходнике. Как сделать этот «reset your device» не пойму.

    Сам stm32 в винде определяется как Неизвестное устройство, причем даже при снятой перемычке P2.
    Вот как все выглядит https://drive.google.com/file/d/0B5rwBc9L_ubwRTRlTi1RY0RRTTg/edit?usp=sharing
    В таком положении джамперов появляется второе сообщение (Unrecognized device…) через 1-2 сек. Во всех остальных случаях показывает первое сообщение секунд через 10.

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

    • Все верно написано. Питания от переходника достаточно. Оно все равно заводится что от USB что от ножки 5V в одну точку.
      Кнопка на плате — это Reset. Пользуйтесь при необходимости.
      При подключении FTDI к компу должен загореться светодиод питания, если бут-пины правильно соединены, то FlashLoader Demo сможет подключиться к плате для заливки прошивки. Скорость 115200. Reset — это сбросом.
      Сама плата и не будет определяться, потому что USB блок периферии на ней не настроен. Для этого нужно писать соответствующую прошивку. Но USB шина не самая простая, поэтому новичку не буду советовать разбираться с ней. А у меня сейчас никак не хватает времени на статью по USB HID, которую давно обещал. Саму прошивку написал больше месяца назад еще.
      Прошить то вы через UART прошьете. но проверять идеи каждый раз так заливая прошивку — это то еще удовольствие. Особенно когда нужно что-то поправить в программе и отладить. Поэтому я бы все-таки порекомендовал после того как зальете тестовую прошивку и помигаете светиками разориться на ST-Link v/2 или его клон. благо стоит он всего 25 баксов в Китае. А клон и того дешевле. Зато позволяет отлаживать в реальном времени, заглядывать в проц и все его регистры/периферию на ходу. Ставить breakpoints.

  7. кстати, зачем новичкам взрывать мозг маргинальными примерами?
    если используете библиотечные функции то используйте их везде!

    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_GPIO, ENABLE);
    GPIO_InitStructure.GPIO_Pin = LED1_PIN | LED2_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( LED_PORT , &GPIO_InitStructure);

    можно было заменить двумя строками, такими же не понятными как LED_PORT->ODR ^= LED2_PIN;

    • Не путайте манипуляции битом состояния и настройки пина. Первое умеет каждый, знакомый с С/С++ и написано на википедии. За вторым нужно лезть в документацию и долго ломать голову какие биты в каких регистрах выставить. Я рассказываю об азах использования STM32, а не об азах программирования на С.
      На GPIO_WriteBit к тому же понадобится переменная, которую нужно инвертировать перед записью, что еще больше запутает.
      К тому же пока никто не жаловался на то, что этот момент непонятен. Не стоит думать о новичках, как о дебилах.

  8. Это комплексная проблема. Ваш код просто 1 из 1000 примеров.
    Не редко бывает, что копируешь какой-то код из одного места и другой из другого, и они потом конфликтуют, потому что один человек юзал либы, а второй нет.
    Из-за этого и из-за десятков не совместимых IDE STM32 никогда не достигнет популярности Ардуины, что печально.

    Кстати пытался адаптировать ваш код работы с USB под CooCox.
    При компиляции получаю ошибку, [cc] collect2.exe: error: ld returned 1 exit status
    В чем косяк, не понятно.

  9. Как раз этот вариант полностью совместим с вариантом и без библиотеки и с ней.
    А тащить в кокос проекты из emblocks не нужно.
    Как раз наоборот. Потому что ld скрипт в кокосе нужен свой. Он рассчитан на другой стартовый код.
    Arduino, кстати точно так же ни с чем не совместима. Более того, сам код зависит от wiring , кривой, медленный и тяжелый, но ни с чем больше несовместим. Хотя arduino всего лишь avr процессор с аппаратной точки зрения. А вот стандартный C код на плате arduino работать будет. Наоборот нет.

  10. Добрый день! Пытаюсь освоить Emblocks, и сразу пришлось бороться с некоторыми непонятками. Например, после #define нельзя печатать русскими буквами ни в простом комментарии ни в блоковом.
    А вот с одним глюком я так и не смог справиться, привожу пример:
    #define m1 0x01
    #define m2 0x03
    #if (m1 & m2)
    my code ;//
    #endif
    Строку » my code ;//» в данном примере ни эдитор ни компилятор не видят!!!
    Чтобы все было в порядке, нужно м1 и м2 написать не в HEX, а в десятичном, то есть 1 и 3, и кроме того & одна не прокатит, нужно ставить две &&. А в библиотеках stm32 все дефайны определены в хекс-виде, и условия стоят с одной &. Например в файле usb_istr.c куча таких строк: #if (IMR_MSK & ISTR_CTR)
    которые воспринимаются емблоксом неправильно. Что Вы делаете с такими багами?

    • Не знаю, я с такими глюками не сталкивался. Да и комментарии на русском не пишу практически.

  11. А еще непонятно, как в дебаге переключиться на пошаговую отладку в дизассемблерном окне. И почему-то не видно самих дизассемблерных инcтрукций(HEX).

    • Ну что я могу сказать, стоит изучить среду поподробнее. Или посмотреть видео на сайте EmBlocks. К тому же на форуме достаточно много народу и обычно довольно быстро отвечают на простые вопросы. Я не пишу на ассемблере да и дизассемблирование мне редко когда интересно, важнее удобство работы на С/С++ и компиляции. То есть высокоуровневые сервисы.

  12. Hello RaJa,
    I would like to use your RHIDdemo for an infrared remotecontrol receiver, which I would like to publish under GPLv2. It is a free project, there is no money making involved.
    Is it ok, to use, modify and redistribute your code?
    Or would you be willing to put it under GPLv2 yourself?
    In your github, there is no licence.
    Regards, JoJo

    Привет Раджа,
    Я хотел бы использовать свой RHIDdemo по крайней инфракрасный приемник дистанционного управления, который я хотел бы опубликовать под GPLv2. Это бесплатный проект, нет прибыльной участие.
    Разве это нормально использовать, модифицировать и распространять код?
    Или вы готовы поставить его под GPLv2 самостоятельно?
    В вашем GitHub, нет лицензии.
    С уважением, ЙоЙо

  13. Здравствуйте, сделал всё по вашему уроку, но в новой версии EmBitz нет такого инструмента как Flash w ST-Link/V2, или я не нашёл, как его подключить. Не могу прошить свою плату Discovery с ядром F100RB. F6 как функциональная клавиша вовсе отсутствует. Заранее спасибо.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.