Обвязка stm32 описание и инструкция по программированию. Быстрое освоение микроконтроллеров STM32. комментариев на « Подключение COG LCD дисплея на ST7565R контроллере»

В последнее время на хабре появилось много статей по STM32 (). В комментариях неоднократно упоминается сложность STM32 по сравнению с AVR. Эта тема особенно влияет на новичков, которые хотят начать изучение микроконтроллеров, и, видя такое мнение, выбирают для изучения AVR. Давайте разберемся, так ли сложен этот зверь - STM32?

Для этого выберем недорогой вариант платы и напишем прошивку в десяток-другой байт (да-да, мигание светодиодом в 2 килобайта сродни «Hello world» в сотни килобайт x86 для неумех). Также научимся писать программы на любом языке программирования для STM32.

Вступление

Какой тип микроконтроллеров изучать? Этот вопрос, по-моему, аналогичен вопросам типа «Какой язык программирования изучать?», «Какой иностранный язык учить?». ИМХО, изучать нужно тот, который нужнее в данную минуту, для данной задачи. Когда знаешь что-то одно, изучение второго дастся намного легче, а на счет третьего и не задумаешься.

Итак, в чем же сложность STM32? Наиболее часто звучит мнение о сложности программирования его периферии. Количество и тип периферии STM32 и AVR примерно одинаков. Конфигурирование ее также не сильно отличается. Так в чем же сложность? В микроконтроллерах STM32 всю периферию нужно предварительно включать. Вот и вся сложность.

Я сравниваю AVR с общественными зданиями: все двери нараспашку, везде мониторы сверкают рекламой и свет горит, а STM32 с личным домом: хочешь телевизор посмотреть - включи сначала, потом переключай каналы, захотел пи-пи - открой дверь и включи там свет, руки помыть - открой воду, и так далее. Не верите? Убедимся вместе.

Обзор платы

Я выбрал самую дешевую плату из предложенных на aliexpress (рисунок выше). Чуть дороже $2, 180 рублей в декабре 2015. На борту минимальная обвязка: два кварцевых резонатора - высокочастотный на 8МГц и часовой на 32.768Гц, кнопка «сброс», два джампера выбора режима загрузки, пара светодиодов - на питание и на ножке PC13 и набор разъемов: microUSB, отладочный, две гребенки для всех выводов микроконтроллера.

Дешевле только купить все детали, сделать самому плату и спаять. Чем шить и отлаживать? Если есть ST-LINK, то лучше им, нет - не беда, есть еще несколько вариантов, например через USB-USART переходник, нет и его - можно напрямую через USB, правда нужно самому написать драйвер для такого случая, никто пока не озаботился. ST-LINK достаточно дешев, да и входит во все платы серии DISCOVERY. Вот и я воспользовался таким.

Подключаем питание, светодиод весело мигает, плата исправна. Скачиваем и устанавливаем программу-программатор (масло-масляное) «STM32 ST-LINK Utility» (все программы и документы берем на сайте производителя). Пытаемся считать прошивку… Программа защищена от чтения. Видимо, недаром все говорят о сложности написания программ для STM32, даже китайцы защитили эту сверхсложную программу от взлома. Или там спрятана закладка-вирус? Разбираться не будем, снимаем защиту и получаем девственно чистый микроконтроллер STM32F103C8T6.

Первая программа

Давайте тоже помигаем светодиодом, сделаем, так сказать, реверс-инжиниринг в уме родной прошивки. Чем? Чтобы не городить споры по выбору среды разработки, я это сделаю в родной Visual Studio Community. Мне кажется, для Windows лучше для мужчины нет.

Как там программа мигания для ардуины? Конфигурируем ножку на выход и в цикле переключаем ее с нуля на единицу и обратно.
А как будет выглядеть она же для STM32? Намного сложнее. Сначала включим свет в комнате конфигурации ножек микроконтроллера, а затем «Конфигурируем ножку на выход и в цикле переключаем ее с нуля на единицу и обратно». Я понимаю, сложно… Но мы справимся.

В документе «RM0008. Reference Manual» на наш микроконтроллер посмотрим карту памяти для нужных нам регистров.

- Пойдем простым и логическим ходом.
- Пойдем вместе.

1. Включим тактирование порта C (наш светодиод висит на ножке 13 порта C). Смотрим документ. Нужный нам регистр RCC_ABP2ENR (переводим: регистр сброса и тактирования - вторая низкоскоростная шина периферии). Адрес порта - 0x40021018, нужный бит IOPCEN (порт ввода-вывода C - бит разрешения) четвертый - 0x00000010.

Отступление

У микроконтроллеров все как у взрослых процессоров. Есть высокоскоростная шина AHB aka «Северный мост» и низкоскоростная APB aka «Южный мост». Сам процессор микроконтроллера умеет все для ускорения работы: имеет предвыборку команд, конвейер выполнения команд. Нет кеша, но процессор не намного быстрее памяти, и чтение-запись в память успевает выполняться за один такт. Так что, можно сказать, вся память микроконтроллера - это один большой кеш. Ладно-ладно, не один и не большой. Два маленьких кеша.
Вся периферия отображена (маппирована) на адресное пространство. По сравнению с x86 нет команд in-out, но и Intel оставил их только для совместимости, сейчас они практически не используются.


2. Сконфигурируем ножку на вывод. Смотрим документ. Нужный нам регистр GPIOC_CRH (переводим: регистр порта ввода-вывода C - конфигурационный регистр для старшей половины ножек). Адрес порта - 0x40011004, за конфигурацию каждой ножки отвечают 4 бита, значение для переключения ножки на выход - 0001b, для ножки 13 значение - 0x00100000.

3. Как переключить логическое значение на ножке. Смотрим документ. Нужный нам регистр GPIOC_ODR (переводим: регистр порта ввода-вывода C - регистр вывода данных). Адрес порта - 0x4001100С, его значение напрямую выводится в ножки микроконтроллера, для ножки 13 значение - 0x00002000. Все готово для написания программы (не забыть выложить проект на github):

Int main(void) { *((int*)0x40021018) = 0x00000010; // RCC_APB2ENR = RCC_APB2ENR_IOPCEN *((int*)0x40011004) = 0x00100000; // GPIOC_CRH = MODER_OUTPUT_13 while(1) { *((volatile int*)0x4001100C) ^= 0x00002000; // GPIOC_ODR ^= BIT_13 int i; for (i=1000000; i>0; i--) ; } } extern int _eram; __attribute__ ((section(".isr_vector"))) int g_pfnVectors = { (int)&_eram, // начальное значение стека (int)main // Reset Handler };
С векторами прерываний, надеюсь все понятно? Мы используем только два из них, поэтому незачем занимать память пустышками. Все остальные прерывания включаются программно, не включали - значит они никогда не сработают. Исключение - третий вектор HardFault, если случилось - микроконтроллер неисправен или сбоит, для простых проектов (не космос-авиация, не медицина) можно не обрабатывать.

Это учебный проект, конечно следует оформить все адреса как символические константы в отдельный h-файл с большим количеством дефайнов, как это сделано в CMSIS. Можно взять их и приспособить для своих нужд. Для компиляции использую gcc, прошивка с помощью «STM32 ST-LINK Utility». Прошивка заняла 56 байт (привет, ассемблер).

Еще отступление

Еще одно утверждение о сложности STM32 - мало документации на русском языке. Спорно. Необходимы только два документа - Datasheet и Reference Manual на нужный микроконтроллер. Язык на котором он написан сложно назвать английским. Я изучал язык по непереведенным игрушкам, уровень английского остался на том же уровне, но даташиты я читаю без проблем, незнакомые термины понятны из контекста.



Вроде много получилось, тогда на сегодня все.

Во второй половине расскажу о программировании STM32 на любом языке программирования.

Теги: STM32, микроконтроллеры-это-просто, ардуино-не-надо

Программатор

Для заливки прошивки в память микроконтроллера и отладки программы используется интерфейс SWD, который требует вывода 4 линий:

  • GND - нужно объединить земли устройства и программатора;
  • SWDIO - линия, по которой передается побитово прошивка и осуществляется отладка;
  • SWSCK - синхронизирующий сигнал, необходим для отправки прошивки;
  • RESET - необходимо перезагрузить МК после заливки прошивки.

Ножки данных линий вы также можете найти в в соответствующем разделе.

Причиной перезагрузки МК могут служить следующие причины:

  • сброс;
  • низкий уровень NRST;
  • не хватка напряжения питания.

Обычно для внешней цепи сброса требуется подтягивающий резистор, однако МК STM32F1xx не нуждается во внешнем подтягивающем резисторе для сброса (ножка NRST). Рекомендуемая величина времязадающего конденсатора - 100 нФ.

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

Данная статья, которая является еще одним "быстрым стартом" в освоении ARM-контроллеров, возможно поможет сделать первые шаги в освоении 32-битных контроллеров ARM на базе ядра Cortex-M3 - STM32F1xxx серии. Возможно данная статья (которых на эту тему появляется как грибов после дождя) станет для кого-то полезной.

Введение

Почему ARM?
1. Есть из чего выбрать (разными производителями сегодня выпускается более 240 ARM-контроллеров)
2. Низкая цена (например за 1$ можно получить 37хI / O, 16K Flash, 4K RAM, 2xUART, 10x12bitADC, 6x16bitPWM).

А начнем нашу работу с контроллеров фирмы ST Microelectronics. Контроллеры на основе ядра ARM Cortex-M3 характеризуются широким набором периферии, высоким уровнем рабочих характеристик, низкой цене
P.S. В самом начале создается впечатление, что ARM"ы это какие-то страшные (в пайке, разводке, программировании) существа. Но это только на первый взгляд:) и вы в этом сами убедитесь.

Итак, изучать ARMы будем на примере контроллеров STM32F1. Одновременно эта серия имеет несколько линеек:

  • Value line STM32F100 - 24 МГц CPU, motor control, CEC.
  • Access line STM32F101 - 36 МГц CPU, до 1 Mб Flash
  • USB access line STM32F102 - 48 МГц CPU with USB FS
  • Performance line STM32F103 - 72 МГц, до 1 Mб Flash, motor control, USB, CAN
  • Connectivity line STM32F105/107 - 72 МГц CPU, Ethernet MAC, CAN, USB 2.0 OTG

Также существует следующая классификация:

Контроллеры STM32 можно заставить загружаться с 3-х областей памяти (в зависимости от состояния ножек BOOT0 и BOOT1 при старте контроллера или после его сброса). Записать программу в память контроллера можно следующими способами:

1 способ:
Используя загрузчик (он уже записан в системную память) и USART1 (USART2 remaped): использует внутренний тактовый сигнал 8 МГц. Чтобы запустить встроенный загрузчик, зашитый в контроллер производителем, достаточно просто бросить на лапки контроллера TX1, RX1 сигнал с преобразователя RS232-3.3В (например на базе FT232RL) и выставить перед этим BOOT0 = 1 и BOOT1 = 0 жмем RESET и можем шить программу в контроллер. А зашивается она в программе Flash Loader Demonstartor от STM (для Windows).

PS. Если вы сидите под LINUX и не имеете отладочной платы типа дискавери, можно заливать прошивку в контроллер через всеми любимый rs-232 (собственно - через преобразователь rs-232-3,3В). Для этого нужно использовать python-скрипт (Ivan A-R) (для LINUX или MACOSX).
Для начала у вас должен быть установлен Python 2.6 версии и библиотека для работы с последовательным портом - PySerial library.
Теперь, чтобы запустить скрипт stmloader.py (из терминала, разумеется) нужно его немного подправить под свой компьютер: откроем его в текстовом редакторе.
Набираем в командной строке
~$ dmesg | grep tty
чтобы увидеть все последовательные порты ПК.
и после набора...
~$ setserial -g /dev/ttyS
мы узнаем путь к нашему 232-му порту. Если система ругается на setserial, установим его
~$ sudo apt-get install setserial
мы узнаем путь к нашему физическому порту (например, у меня - /dev/ttyS0). Теперь нужно записать этот путь в файл скрипта stm32loader.py вместо дефолтного «/dev/tty.usbserial-...». Набираем в терминале
~$ python stm32loader.py -h
...для вызова справки и заливаем прошивку в наш контроллер.

2 способ:
Через USB OTG, используя DFU-режим, требует внешнего кварца на 8 МГц, 14.7456 МГц или 25 МГц (этот загрузчик есть не у всех контроллерах с USB OTG надо внимательно смотреть на маркировку вашего контроллера)

3 способ:
JTAG/SWD. Ну и для тех, кто имеет демоплату типа Discovery или самопальный JTAG/SWD программатор, можно заливать код и уже отлаживать свой микроконтроллер этим способом. Для JTAG в микроконтроллере отведено 6 лапок (TRST, TDI, TMS, TCK, TDO, RST) + 2 на питание. SWD использует 4 сигнала (SWDIO, SWCLK SWO, RESET) и 2 на питание.

PS. В среде EAGLE я набросал несколько схем-заготовок для 48-ми, 64-х и 100-ногих контроллеров (папка eagle), а stm32loader содержит скрипт stm32loader.py

Отладочная плата STM32 Discovery предназначена для изучения возможностей и принципов программирования 32-разрядных ARM микроконтроллеров серии STM32 от фирмы STMicroelectronics . На плате установлены все необходимые элементы для начала работы с данными микросхемами. Структура платы разделена на две части – отладчик ST-Link и непосредственно сам микроконтроллер.

Микроконтроллер

На плате STM32 Discovery установлен микроконтроллер STM32F100RBT6B, являющийся одним из наиболее простых в серии STM32. STM32F100RBT6B представляет собой 32-разрядный процессор с ядром ARM, серии Cortex-M3. Объем встроенной памяти составляет 128кБ Flash-памяти и 8кБ ОЗУ. Микросхема выполнена в 64 выводном корпусе LQFP для поверхностного монтажа.

Из периферийных устройств в STM32F100 реализованы:

  • 5 портов ввода вывода
  • 12-битный АЦП
  • 2 12-битных ЦАП
  • 3 интерфейса USART
  • интерфейс SPI
  • два интерфейса I2C
  • таймеры

Обвязка микроконтроллера

Помимо микроконтроллера на плате STM32 Discovery специалистами STMicroelectronics предусмотрены следующие устройства:

  • два пользовательских светодиода
  • пользовательская кнопка
  • кнопка сброс
  • кварцевый резонатор на 8 МГц
  • резонатор на 32768 Гц для работы часов реального времени и сторожевого таймера

Все линии портов микроконтроллера выведены на штыревые разъемы, расположенные по краям платы. Большим плюсом является доступность этих разъемов с обеих сторон.

Для питания МК используется напряжение 3.3В. Питание внешних устройств возможно от встроенного стабилизатора напряжения 5В.

Отладчик

STM32 Discovery оснащен фирменным отладчиком от STMicroelectronics, под названием ST-Link. Данная модель не совместима с изделиями от других производителей. Отладчик реализован на микроконтроллере STM32F103 и позволяет записывать программу в базовый МК и отслеживать ее работу. Для связи с компьютером используется разъем типа Mini-USB, который также позволяет питать устройства на плате. Для индикации работы отладчика используются два светодиода красного цвета. Один горит при включении питания, второй при работе отладчика.

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

Программное обеспечение

Для работы с STM32 Discovery можно использовать несколько различных IDE. STMicroelectronics предлагает собственную среду разработки под названием Atollic True STUDIO. В версии LITE данная среда поставляется бесплатно. Также микроконтроллеры STM32 поддерживают такие, широко известные пакеты, как IAR, Keil, CODE RED. Прошивку целевого микроконтроллера возможно выполнить с помощью бесплатной утилиты ST-Link Utiliuty.

You have no rights to post comments

Решил написать книгу …
… про реальную разработку устройств на stm32. Поэтому думаю обновления если и будут, то нерегулярным и в основном в виде кусочков из книги.
Что бы не было скучно, вот вам малюсенький кусочек, можно сказать бета-версия про кварцевые резонаторы и вообще частоты.

Сами по себе микроконтроллеры работать не умеют. Им нужны всякие сопутствующие элементы. Вот к примеру, STM32L05 умеет работать с USB без всяких внешних кварцевых резонаторов, а STM32L152 - нет. Если мы планируем использовать более-менее точное время в наших проектах, то нам жизненно необходим внешний часовой кварцевый резонатор. Без него уход времени на 5-10 минут в сутки станет совершенно нормальным. И более того, он будет не постоянным и зависеть от температуры, напряжения питания и кучи других вещей.

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

Клоки, тайминги и шины

Одна из самых распространенных причин неработоспособности чего-либо - неправильная конфигурация частот и всего, что с этим связано. Наступило время раскрытия еще одной вкладки в кубе - Clock configuration. Я открыл новый проект, взял выбранный микроконтроллер, и включил rtc, usb и пару uart. Просто для примера. Открываем вкладку и видим примерно следующее

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

Давайте начнем слева. У stm32 могут быть источники тактовых сигналов высокой (HS) и низкой (LS) частоты. Они могут быть внутренними (I) или внешними (E). Те, что сейчас в работе - подсвечиваются синим. Например, сейчас используется два источника - на 37 килогерц и на 16 мегагерц.

Теперь ваша задача пройти лабиринт, выставив все в нужных положениях. Задача осложняется тем, что можно выставить все в § «зеленое», но потом обнаружить, что частоту uart нельзя будет поднять больше 300бод. В общем, у программистов ST получилась этакая игрушка для взрослых. А теперь представьте, что раньше все это надо было рассчитывать руками, после неоднократного чтения документации и выяснить, будет ли это работать можно было только экспериментально.

В нашем случае все просто: изменив пару параметров в PLL (программируемый множитель), я легко добился исчезновения «красного». Почти.

Данной красной точкой авторы куба отсылают нас к документации, которая однозначно говорит, что без внешнего кварцевого резонатора не видать нам USB как своих ушей. Слишком «плавает» внутренний генератор, а использовать тактирование со стороны USB этот микроконтроллер не умеет.

Ок, идем на первую вкладку и около RCC видим такую картину

Disable - это понятно, выключено. Bypass - это прием тактового сигнала с внешнего источника. Ведь с stm можно сделать так, что бы куча микроконтроллеров работала в одном ритме, ибо это очень сильно облегчает вопросы взаимодействия чипов между собой. Например, так сделано на всех discovery платах, что я видел. Там в «программаторской» части стоит кварцевый резонатор, который «питает» чип программатора, а тот в свою очередь отдает тактовый сигнал чипу на плате. И ну последний пункт - это свой, так сказать, персональный кварцевый резонатор.

Так как у нас тестовый проект «на побаловаться», включаем оба на «резонатор» и смотрим, что получилось.

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

Открываем даташит (я его на всякий случай положил в 02_switch) и ищем требования к кварцам. У кварцевых резонаторов, кроме частоты, есть еще два параметра – емкость и частота увода. Емкость в pF, нужна для расчета «запускающих» конденсаторов, а с ppm немного сложнее

Аббревиатура ppm означает parts per million или количество миллионных частей от основной частоты. Говоря иначе, погрешность 100 ppm для 100 МГц означает уход частоты на 100/1000000 часть от 100 МГц. Таким образом, частота может уйти на 100000000 * 100 / 1000000 = 10000 Гц (10 кГц, или 0.01 МГц), то есть финальная частота может быть любой в диапазоне 99.99 ... 100.01 МГц. Или говоря другими словами чем меньше ppm, тем лучше. Итак, смотрим в даташит и находим следующую табличку

Согласно ей у нас «высокоскоростной» кварц может быть от 0 до 32 мегагерц. Куб считает, что только до 24 можно (да и в других местах тоже идет речь про максимальную частоту в 24 мегагерца). Но я искренне рекомендую использовать параметры из Typ(ical) или «типичного» столбца. Как показывает моя практика, это наиболее беспроблемные цифры.

Говоря же про кварцы, то можно поиграться «соседними» по степени двойки частотами. То есть посмотреть на 2, 4, 8 и 16 мегагерц. Поиск осуществляем по уже описанной методике: дешевле, лучше и можно запаять руками.

Нашли? А теперь смотрим уже в даташит на кварцевый резонатор и ищем там параметр нагрузочная емкость. А потом снова в даташит, но уже процессора.

Как видно, там нужны с нагрузочной емкостью 20pF. А вот мне попадались либо 16, либо 32. Чего делать? Как обычно, читать даташит и смотреть на строчку «AN2867 "Oscillator design guide for ST microcontrollers"» (можно взять там же, где и остальные дополнительные файлы к книге).

Если кратко, то там есть следующая схема

и вот такая вот сложная формула

Воспользовавшись знаниями математики за 5 класс среднеобразовательной школы (хотя могу и ошибаться), решим это сложнейшее уравнение:
16 = (Х*X)/(X+X)+3
16-3=X*X/2*X
13=X/2
X=26
Итак, ответ ответ – конденсаторы CL1/2 должны быть 26pf. Таких в природе нет, зато есть 27pF, что нам более чем подходит.
Теперь надо подсчитать, запустится ли генератор. Там чуть дальше есть формула

Считаем
G=4*60*(2*3.14*(8*(10^6))^2*((7+16)*10^(-12))^2)
Возведение в степень я обозначил как ^, её же использует и excel.
Запутаться очень легко, поэтому я сделал простую считалку в excel (файл называется resonator)

Туда подставляем найденные значения и смотрим на значение в ячейке Gain. Согласно документации, оно должно быть больше 5. И чем больше, тем лучше. У меня вот получилось. Хотя если брать резонатор с нагрузочной в 32pF, то будет меньше. Аналогичную процедуру надо будет проделать и с «часовым» кварцем. Возвращаемся к кубу и выставляем значения, попутно щелкая переключателями, что бы нигде красного не было.

Как видим, везде все стало хорошо и микроконтроллер будет работать на максимальной для него частоте - 32 мегагерца.

А проверить?

Но вот гложет меня, правильно ли я подсчитал все. Надо провериться. Достаю описание на stm32l-discovery и открываю там схему. Нахожу часть с резонатором

Да и вообще, рассматривание схем чужих, гарантированно рабочих и предназначенных для огромных тиражей плат способно сильно продвинуть в решении вопросов «как это сделано».

Продолжение следует...