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

    Как и просили в комментариях к предыдущей статье о EmBlocks, сегодня я покажу от начала и до конца как создать в EmBlocks простой проект для мигания парой светодиодов.
    В качестве отладочной платы мы будем использовать кроху на STM32F103C8.
    Вот наш стенд:

    Подключаем аноды светодиодов к пинам PB5 и PB6, катоды через резсторы в 390 Ом к земле.

    Итак, если еще не скачали EmBlocks, сделайте это. Распакуйте в любой удобный каталог и запускайте.
    Создаем проект, выбрав в меню «File->New->Project...»
    В категории Projects выбираем «STmicro-Arm».

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

    В окне выбора компилера ничего не трогаем и двигаем дальше.
    В окне выбора процессора из первого списка выбираем «STM32F10x_md» т.к. STM32F103C8 принадлежит к семейству F1 и содержит 64к FLASH, что относит его к medium density девайсам.
    Если будете использовать ColinkEx, то выбираем в следующем окне конкретное название процессора, это нужно для прошивки утилитой CoFlash.
    Если будете пользоваться ST-Link, то можно не трогать.
    Галка «Create hex file» отвечает за создание .hex на выходе вместо .elf файла. ColinkEx принимает и те и другие, а вот ST-Link Utility только .hex

    Жмем Finish. Мастер предложит выбрать отладчик и настроить его. Причем дважды — для цели Debug, а затем для Release… Если будете использовать другой, нажмите отмену и выберите другой отладчик. О других отладчиках расскажу как-нибудь в другой раз.
    По-умолчанию предлагается ST-Link, нас это устраивает, поэтому просто жмем Ok дважды для каждой цели (Debug, Release)
    Все, болванка проекта готова. Если теперь нажать 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.h>
    #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.S */
    
    	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() заполняем структуру GPIO_InitStructure, настраивая пины PB5 и PB6 на работу в режиме PushPull с максимальной частотой 50MHz.
    Затем инвертируем состояние LED_PIN2, чтобы светодиоды перемигивались и в цикле переключаем их с небольшой задержкой.

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


    Довольно просто, неправда ли?

    Весь процесс занимает примерно минуту. Если у вас все же не получилось, скачайте проект и сравните с тем, что получилось у вас.
    Для другой платы изменится только выбор процессора из списка, если он отличается и макроопределения светодиодов, если он подключены к другому порту.
    Например, для STM32VLDiscovery:
    #define RCC_GPIO RCC_APB2Periph_GPIOC
    #define LED_PORT GPIOC
    #define LED1_PIN GPIO_Pin_8
    #define LED2_PIN GPIO_Pin_9
    
    Share post

    Similar posts

    Comments 35

      +1
      ниочем…
      Хоть бы привели в чем плюсы по сравнению с другими ide.
        +2
        Уже писал об этом. Эта статья для тех, кто хотел пример ее использования. Основная проблема с Eclipse и другими IDE — более сложная настройка проекта. А CooCox не поддерживает С++ и намного медленнее.
        +2
        Мне вот в кокосе нравятся репозитории для stm32f1xx, когда в начале отмечаешь, какую из периферии хочешь юзать (или из репозиторных библиотек), а ИДЕшка подключает нужные либы и заодно дает справку по ним и код примеров.
        Мелочь, конечно, но приятная, чтобы не вспоминать каждый раз где там что. Тут такого нет?
          +1
          Да, мне тоже. Кстати, все эти репозитарии совместимы с EmBlocks — достаточно кинуть их в папку проекта и включить в состав проекта. К сожалению, тут такого визарда нет. Надо подумать, возможно это можно сделать скриптами.
          В любом случае, это более универсальная среда — она подходит не только для STM32 и вообще не только для ARM, но и для AVR, к примеру. Поэтому и не так сильно заточена под ARM.
          0
          Скажите, а программатор где/по чем? Ценовой порог вхождения какой и можно ли программатор на коленке паять, как для Атмеловских?
            0
            И еще вопрос начинающего ламера. Вижу впаянный кварц на 8 МГц. В Вашей статье написано — можно до 72. Скажите, пожалуйста, как наиболее просто и дешево поднять частоту хотя бы до 50 МГц.
              +1
              Встроенными средствами процессора — модуль PLL (ФАПЧ) выполняет умножение частоты, например 8*9=72.
              PS или дешево вы имеете ввиду вообще без кварца?
                0
                Спасибо
                +1
                Оно и работает на 72МГц сейчас. Как сказано в комментарии ниже — с помощью умножителя частоты МК тактируется на 72 МГц от кварца на 8МГц. Можно использовать и другие частоты.
                Эта плата — полноценный девайс на полной скорости и все порты выведены на гребенки.
                  0
                  Спасибо и Вам :)
                +1
                Программатор для прошивки вообще не нужен — достаточно USB-UART переходника за 2 бакса (на CP2102, например или из шнурка от старого телефона). В STM32 есть встроенный бутлоадер, я об этом писал.
                Ценовой порог вхождения — $10. Столько стоит плата, которая на фото. Ее функционал я описывал. Больше кроме USB-UART переходника для начала ничего не нужно.
                Отладчик на фото для прошивки и аппаратной отладки из IDE стоит в районе $25. Есть и за 6-7 баксов, но я их не тестил, поэтому не могу сказать, работают ли.
                Ссылки и цены я давал в комментариях у себя на сайте.
                  0
                  Понял, спасибо. Интересует именно вариант с отладкой. Для атмеловской меги сами собирали jtag-программатор. Тут, видимо, надо 25 баксов просто платить — и голову не морочить.
                    +2
                    Конечно, самый простой вариант — купить ST-link/V2 или Discovery плату — не ней уже есть дебаггер, который можно использовать в своих проектах.
                    Также можно и самому собрать. Например ColinkEx. Схемотехника открытая, прошивка лежит к нему открыто. Поддержку ColinkEx я в EmBlocks добавил (им правда пользоваться не так удобно, как ST-Link, если надо отлаживать платы на разных процессорах).
                      0
                      Подскажите, пожалуйста, а что с точностью тактирования? А то когда мы на меге на 16 МГц собирали счетчик, за 4 мс набегала погрешность более 2 тактов…
                        0
                        Точность тактирования достаточна, для того, чтобы корректно работал UART и USB, которые довольно чувствительны к уплываниям частоты. Но в штуках не могу сказать, у меня такого осциллографа нет. Только Oscill и логический анализатор saleae logic.
                    0
                    Хотелось бы спросить на счет питания от сети 220. Вроде бы написано, что на плате есть стабилизатор на 3.3 вольта и что можно питать 5 вольтами. Значит ли это, что можно использовать любой не стабилизированный блок питания или вообще взять зарядку от телефона с выходом на usb?
                      0
                      Легко. Я проверял на зарядке от планшета с miniUSB выходом.
                      0
                      А Вы могли бы показать, как прошивать микроконтролллер с помощью встроенного бутлоадера, или сами ещё не пробовали это сделать?
                        0
                        Делал, очень просто. BOOT1 замыкаем на VCC(3V3), подключаем к USART1 переходник USB-UART. Запускаем STM32 Flash demo loader и дальше все и так понятно — там просто подсунуть файлик прошивки, он все сделает сам. Затем возвращаем BOOT1 в 0 (замкунть на GND) и сбросить МК.
                          0
                          Т.е. загрузчик не работает с имеющимся на плате USB разъёмом?
                            +1
                            Конечно нет, этот USB разъем для имеющегося в составе МК периферийного модуля USB-FS. Встроенный бутлоадер работает с UART. Но есть возможность написать прошивку, которая будет поддерживать DFU — самопрограммирование по USB, но это непросто и нестираемой она не будет.
                            У меня есть плата, которая имеет на борту FTDI чип, который подключен к USART1 и там все совсем просто — подключаем в USB и заливаем.
                              0
                              А Вы можете рассказать (или отдельную статью заделать) про работу со встроенным USB-FS для STM32F103C8? Очень заинтересовала платка. Там использование такое же как и у чипов FT, или полноценный USB 2.0? В приборе сейчас у меня работа по принципу USB-to-COM и на Rx Tx AtMega162.Но хочется побыстрее и камень, и обвязку.
                              Спасибо.
                                0
                                Вообще есть такая мысль, но дело в том, что USB — шина с огромными возможностями и описать их в пределах одной статьи совершенно нереально. Потребности у всех разные и соответственно метод работы тоже разный.
                                Я для себя использую пакетный обмен с ПК, потому что поток мне неудобен — нужно распознавать заголовки и куча других неудобств.
                                Второе условие — отсутствие необходимости писать USB драйвер или использовать какие бы то ни было dll для работы с девайсом. Поэтому я выбрал для себя релизацию HID, которая не требует дополнительных драйверов. Есть ограничение на размер пакета в 64 байта и частота опроса примерно в 1 кГц, что дает примерно 64 кБ в секунду, мне этого достаточно, поэтому описывать буду именно такой вариант. Подойдет он разумеется не всем.
                                По поводу реализации — вы можете сделать реализацию виртуального COM порта — VCP или CDC. Можете сделать HID, или что-то свое. На МК есть соответсвтующий аппаратный модуль USB-FS, который как настроите так и будет работать. Но это нетривиальная задача, поэтому я для себя сделал шаблон с USB-HID и пользуюсь им, слегка модифицируя его.
                                  0
                                  Ну меня такой вариант более чем устроит: как минимум выигрыш в компактности получаем — все что надо есть на плате — по сравнению с использованием FT232. Да и объем передаваемых данных небольшой и к скорости требований жестких нет
                                  Так что жду с нетерпением :)
                                    0
                                    Ну значит требования примерно как у меня.
                                    Статью пока не знаю где буду размещать. Может на хабре, если подойдет по формату, может у себя на сайте.
                                      0
                                      это не суть важно. Кто захочет — найдет ;)
                    0
                    Скажие, а шилдики есть под эту штуку? Беглый поиск по Алиэкспрессу результатов не дал…
                      +1
                      Какие сделаете :) Это не стандарт и не Arduino. Хотя и можно сделать самим что угодно. Лично мне такой формат нравится больше, чем Arduino с ее кривым промежутком между пинами.
                      Эта плата — продвинутый конструктор для тех, кто вырос из Arduino.
                      Но я уже думал на тему того, чтобы выпускать к ней шилды. Есть какие-то конкретные пожелания?
                        0
                        Спасибо за информацию. Пожеланий нет, просто искал монтажку с готовыми стыковочными разъемами. Придется значит самому руками делать. Надо специфическую обвеску под свои задачи на входы лепить.
                      0
                      Что-то я не могу выбрать в визарде STM32F103RB, плата, если что, вот такая. Надо куда-то библиотеки подсовывать?
                        0
                        Открываем даташит, видим «STM32F103xB medium-density performance line microcontrollers».
                        а значит нужно выбрать STM32F10x_md (что и означет medium density).
                        image
                        второе поле нужно только, если вы используете CoolinkEx в качестве отладчика или для прошивки. Я добавил это поле для удобства работы с ним. Для компиляции или при работе с ST-Link оно не имеет значения.
                          0
                          О, спасибо! Я испугался что камень не тот (C8, а не RB). Для J-Link'а же тоже не важно?
                            0
                            Насколько я знаю нет, но J-Link у меня пылится на полке из-за неудобства работы с ним и кривых дров — новые версии банят китайские копии по серйиникам )
                              0
                              Оу, не знал, спасибо! Буду делать снепшот перед обновлением. А что с ним не так? У меня в кококсе дебаг без нареканий работает. Дрова да, пришлось поискать, и я, похоже, спалил им китайский серийник. =(
                                0
                                Нужно держать его сервис запущенных, он медленнее стартует и медленно работает. Еще какие -то мелочи всплывают, но и проблем с лицензией и сервисом мне хватило, чтобы отказаться в пользу беспроблемного st-link

                      Only users with full accounts can post comments. Log in, please.