Category Archives: ARM. Учебный курс

Контроллеры от GigaDevice GD32F103xxxx. Попытка миграции с STM32F103xxxx

В связи с тем. что последнее время цена на контроллеры растет быстрей чем стоимость битков, а, например, наш основной STM32F103VGT6 стал стоить вместо 500р аж 5000+, да еще с непонятными сроками ожидания от года и более, то мы начали вынужденную миграцию на аналоги. И взгляд пал на GD32, как на наиболее вменяемого и адекватного представителя китайпрома. А главная задача стала сделать универсальную прошивку которая бы одинаково работала как на STM32 так и на GD32. Чтобы можно было не глядя лить в наши машины смерти, не обращая внимания на то на какой архитектуре там мозги.

Купили мы небольшую партию этих чипов на Алиэкспрессе :))) Уже звучит жутко, но вариантов особо не было :)

Итак, на смену STM32F103VGT6 идет GD32F103VGT6 — китайцы не заморачивались вообще с названиями. И то правда. Чего нам париться? Совместимость у него по ногам полная, так что впаиваем его как есть.

А вот дальше начинаются различия. Во первых, памяти у него может быть больше. Аж до трех мегабайт флеша, против мегабайта у STM. Что, впрочем, не более чем потенциальная возможность, в моем случае, т.к. GD32F103VGT6 по объему памяти идентичен STM овскому камню. А еще у китайца тактовая частота выше, 108Мгц против 72Мгц у STM. Подозреваю Errata там тоже исправлена. Но, не факт что это к лучшему :)
(далее…)

Read More »

STM32. Контроллер внешней параллельной памяти FSMC

У микроконтроллеров собственной памяти мало, даже если говорить о каком-нибудь жирном прежирном Corteх, все равно: как волка ни корми, а у медведя, т.е. полноценного компьютера, толще. Поэтому практически все микроконтроллеры, в своем жирном исполнении так или иначе позволяют подцеплять к себе внешнюю параллельную память. Даже древний, как говно мамонта, АТ89С51 это умел. Что уж говорить про AVR и STM32.

▌Параллельная память

Для такой памяти характерны две черты: наличие двух шин: адреса и данных, и разных там стробов. На чтение, запись, тактовых и прочих. А вся суть работы с ними предельно простая. Чтение — мы выставляем на ногах адресной шины (коих обычно от 16 до 32) адрес нужной ячейки, отдельной ногой указываем, что у нас чтение, дергаем стробом и на шине данных (8 или 16 бит, обычно) появляется желанные байты. Запись похожим образом, только тут на шину данных мы выкладываем то, что хотим записать, на адресную шину кладем адрес куда надо записать, расставляем контрольную линию в режим записи и дергаем стробом. Опа, данные в памяти. Поскольку тут не требуется совершать сложных логических действий, то это все работает очень быстро, а реализовать можно даже на логике рассыпной. Естественно, что в разных МК такие интерфейсы были всегда.
(далее…)

Read More »

Удобная работа с GPIO на STM32

Долгое время работая с STM32 все никак не мог определиться как же удобней мне обращаться с портами GPIO. Всякие SPL методы мне категорически не прикалывают, как то громоздко, хотя и читаемо. Опять же помнить как там параметры эти зовутся. Вручную порты тасовать можно, но опять же громоздко выходит. В дефайны оборачивать… тоже чет не то. Пока в одном из проектов не увидел годную реализацию, немного ее усовершенствовал и теперь с удовольствием использую.

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

В общем, суть такова:
(далее…)

Read More »

Контроллер прямого доступа к памяти (DMA) контроллера STM32

Работа с контроллером DMA

▌Что это?
Есть в современных контроллерах такой блок DMA — контроллер прямого доступа к памяти (ПДП). Штука очень простая, несмотря на умное название. Вся ее суть заключается в том, чтобы по команде от периферии или ядра взять и скопировать кусок памяти с одного места на другой.

Для этого мы в настройки DMA загружаем адрес откуда копировать, адрес куда копировать, какой размер блока данных копируемый за раз (байт, два байта — слово, два слова и так далее) и сколько блоков надо скопировать. А дальше контроллер DMA ждет команды или разрешения на работу. Как оно будет получено он фоном, не занимая проц, это все сделает. При этом сам ,если нужно, будет увеличивать адреса, выбирая следующий блок. А по завершении подаст прерывание, махнет флажком, в общем. Как то отчитается о работе.

Что с этим можно делать? Ой да много чего. Можно, задать в качестве источника адрес какой-либо периферии, скажем выходной регистр АЦП, а в качестве приемника адрес массива в ОЗУ, дать приказ DMA по команде завершения оцифровки АЦП хватать результат и пихать в массив. При этом DMA сам скопирует, сам увеличит адрес, а как заполнит буфер, то обнулится и начнет его переписывать по кругу заново.

И вот у нас, автоматически, без работы проца вообще, образуется циклический буфер приема данных с АЦП, которые мы можем тут же прогнать через любую цифровую обработку, да хоть через усреднение, и получить отфильтрованные уже данные. Или то же самое сделать с UART и заставить DMA аккуратно складывать входящие данные в кольцевой буфер.

А можно сделать и наоборот. Сказать DMA что мол вот тебе буфер, там лежит пара сотен байт, возьми и запихай их все в жерло UART и пойти по своим делам, а DMA трудолюбиво отправит в передачу весь буфер.
(далее…)

Read More »

Реализация функции задержки меньше 1мс на FreeRTOS с помощью таймера и Task Notification

Есть в FreeRTOS встроенная функция vTaskDelay которая на N тиков системного таймера отдает управление другим задачам. В результате можно делать тупые циклы с ожиданием чего-либо и не париться по поводу процессорного времени. Очень удобно. Но есть проблема, минимальное время которая эта задержка может организовать составляет 1 тик системного таймера. Обычно это около 1 миллисекунда. Но иногда требуются задержки меньше. Да, можно повысить скорость тиков системного таймера. Даже в 10 или 100 раз, при 72 Мегагерцах какого-нибудь STM32 это вполне себе работает. Правда на переключение контекста будет уходить больше процессорного времени. Впрочем, всегда можно работать в кооперативном режиме, а не вытесняющем. Тут в принципе нет вытеснения, а управление передаешь вручную через функцию taskYIELD или любую другую с ожиданием. Те же Delay, Очереди, Семафоры и мало ли что еще.

Но все равно — решение так себе, особенно если ради какой-нибудь небольшой задачи приходится разгонять процессы во всей операционке. Значит надо сделать свой маленький таймер, который сам по себе будет тикать в прерывании и обеспечит нам работу всех этих выдержек. Что я и сделал.

Таймер взял самый бомжовскйи. На STM32F103C8T6 нет, к сожалению, Basic Timers ТIM6 и ТIM7 — это самые простые, самые примитивные считалки. В них нет ни завата, ни регистров сравнения для ШИМ и их не жалко отдать под такое дело, но они есть либо в самых жирных, либо в самых нищих вариация серии F10x. В моей нету. Ну окей, возьмем другой таймер. Общего назначения. Я взял Timer 2.

Настраиваются таймеры элеменатрно, тут не нужны даже никакие библиотеки. Главное понять откуда берется тактирование, какая величина и что надо включить. Смотрим в RM0008 структуру тактирования таймера 2. Раздел 7.2 Clocks

У меня в системе предделители обычно настроены на максимальную частоту и на этой шине 36 мегагерц. Тактирование нашего дополнительного таймера я хочу видеть с частотой 10 килогерц. Та что делим 36 мегагерц на 36, а потом еще на 100. И получим искомое.

(далее…)

Read More »

FreeRTOS. Пример

Обещал я как то пример программы похожей на реальность, но с использованием FreeRTOS. Обещанного, как водится, три года ждут. Правда прошло уже пять… ой… В общем, ужасно не люблю писать бесполезные примеры. А полезные, которые можно выложить, как то не попадались под руку. И вот оно, нашло таки.

В общем, суть задачи, управление несколькими шаговиками не приходя в сознание. Причем все должно вращаться одновременно и сигнализировать о приходе на точку, а также прерываться по требованию. Да это все можно сделать десятком разных способов. И программно и полуаппаратно. Как угодно, короче. А у меня будет на FreeRTOS. Надо же на чем-то показать :)

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

▌Железо
Ну тут все элементарно. Pinboard II с STM32F103C8T6. Да шаговые драйверы TB6600. У драйверов этих есть сигнал STEP сигнал DIR и сигнал EN. Подаем разрешение на EN, выбираем направление на DIR и гоним тактовые импульсы на STEP. И таких четыре драйвера.

▌Среда
Делаю я все в EmBitz кто то ее в комментариях упомянул. Я попробовал и протащился. Работает НАМНОГО шустрей чем любая монструозная хрень на эклипсе. Так что атолик студио, кокос — все нахер. А внутре у ней тот же GCC.

▌Установка
Как ставить FreeRTOS описывалось в прошлой статье. С тех пор ничего не поменялось. Кинуть файлы в проект и подцепить их в среде. Элементарно. Также бегло пробегитесь по первой статье.

(далее…)

Read More »

Cоздание минимального проекта под STM32 в Atollic True Studio вручную

К моему глубокому сожалению и удивлению несмотря на популярность и развесистость либ, но CoIDE похоже приказала долго жить. Сайт сдох, разработчики молчат. Могли бы и в опенсорц податься, все предпосылки к этому были, но… В общем, кто этих китайцев поймет. Дремучие они.

А жаль, из бесплатных это была пожалуй наиболее юзерфрендли среда для создания проектов под STM32 где можно было родить минимальный проект в три клика, причем реально минимальный. Только CMSIS и все. Никаких тебе монструозных кубов и прочей дичи. Выдающих портянки кода от одного только косого взгляда.

Что делать? Куда бежать? STM, говорят, прикупил Atollic True Studio, вышвырнул оттуда поддержку всех сторонних камней и дал нахаляву. Решил я попробовать это чудо. В конце концов чем оно отличаеться то от CoIDE? Тот же Eclipse…

Оказалось отличается, т.к. о поддержке STM там разве что заголовок в шапке говорит, да темплейты под самые популярные борды. И больше ничего, все придется делать ручками.

Чтож, онанизм так онанизм. Наши руки не для скуки!
(далее…)

Read More »

Простой программный таймер для конечных автоматов

Достался мне тут на доделку один проект. Точнее два, но от одного автора. Управление промышленным оборудованием.

Сам проект ничего особого, простая логика на конечных автоматах. Но мне понравился там как реализован таймер. Я обычно предпочитаю динамический таймер, а идею глобального времени только высказывал, но так и не применил, т.к. в основном все делал на диспетчере или RTOS и там этот подход не особо удобен. Но если логика построена на простом суперцикле с набором функций-автоматов в main цикле, то такая реализация таймера фактически стала классикой. Вот, пользуясь случаем, заполняю этот пробел. Архитектура тут не важна. Главное чтоб был таймер способный давать прерывание раз в тик. Тик обычно 1мс.

▌Принцип работы и использование
У нас есть глобальная переменная TimeMs которая инкрементируется по прерыванию таймера раз в 1мс. Когда мы хотим поставить выдержку, то просто берем текущее значение TimeMs прибавляем к нему нашу выдержку и запоминаем все это в статичной переменной, пусть будет Delay, которая определена непосредственно в той функции автомата которая эту задержку использует. И при каждом следующем входе в автомат она будет проверять нет ли у нас условия Delay >= TimeMs.

То есть автомат мигалка будет выглядеть так:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void Blink (void)
{
 
// Переменные объявленные как static не исчезают после выхода из функции. А сохраняют свое состояние.
static uint8_t blink_state = 0;     // Переменная состояния конечного автомата
static uint32_t Delay;              // Переменная программного таймера мигалки, время моргания
 
switch (blink_state)
  {
  case 0:                           // Первый вход, инициализация и первый поджиг. 
               {
               Delay = MainTimerSet(1000);   // Ставим задержку на 1000мс
               LED_ON();                     // Зажигаем диодик
               blink_state = 1;              //  Переходим в следующее состояние автомата
               break;                        //  Выход из состояния
               }
 
  case 1:                                    // Первая стадия рабочего цикла (Не горим) 
             {            
             if ( !MainTimerIsExpired(Delay) ) break;      // Если 1с не прошла - сразу выходим
                                                           // Функция MainTimerIsExpired проверяет по
                                                           // таймерной переменной TimeMs не
                                                           // стал ли Delay меньше чем TimeMs
 
             LED_OFF();                                    // Если секунда прошла, то гасим диодик
             Delay = MainTimerSet(500);                    // Запоминаем время выключенной фазы 0.5с
             blink_state = 2;                              // Переключаем автомат во вторую стадию
             break;                                        // Выход из состояния
             }
 
case 2:                                    // Вторая стадия рабочего цикла (Горим) 
             {            
             if ( !MainTimerIsExpired(Delay) ) break;      // Если 0,5с не прошла - сразу выходим
 
             LED_ON();                                     // Если секунда прошла, то зажигаем диодик
             Delay = MainTimerSet(1000);                   // Запоминаем время включенной фазы 1с
             blink_state = 1;                              // Переключаем автомат в первую стадию
             break;                                        // Выход из состояния
             }
 
default: break
  }
}

Ну, а в самом Main вызов автоматов разных задач выглядит как то так:

1
2
3
4
5
6
7
8
9
10
void main (void)
{
while (1)
  {
  KeyScan();       //  Автомат отвечающий за сканирование клавы бла бла бла
  LCD_process();   // Автомат работающий с дисплеем бла бла бла
 
  Blink();         // Наша мигалка
 
  }

Теперь немного о реализации самой библиотечки таймера.
(далее…)

Read More »

STM32 CubeMX и Pinboard II. Настройка и тестовый проект-моргалка

У меня тут последнее время часто спрашивают, можно ли через Pinboard II работать с CubeMX и у кого-то возникли даже проблемы с этой приблудой. Так что пришлось запилить видеопример простой моргалки сгенерированный в кубе. Ну, а раз это взлетело так просто, то и остальное должно тоже. Ну и в двух словах описал, что есть HAL, откуда он взялся и что собой заменил.

Read More »

ARM. Учебный курс. IAR EWARM. Создание проекта — часть 3. Подключение Colink: танцы с бубном и без.

В далеком 2010 году товарищ rtxonair чирканул пару статей про ARM + IAR и в какую сторону вообще копать. Статьи получились толковыми, но их было раз-два и все, а информации по IAR как было негусто, так и осталось (даже сегодня, спустя добрых пять лет). А если такая информация и появляется, то чисто обрывочно, в форме «смотрите, я тут опять диодиком помигал». Впрочем, довольно нытья, мы здесь не за этим :)

▌Водная часть
Наглым образом пропустив вопрос «А-почему-IAR?» (ответ: потому-что-не-Keil), обращу сразу внимание, что в комплекте с платой Pinboard II идет отладочный Colink-адаптер на Кокосе:

Автор статьи (DySprozin) предполагает, что вы уже ознакомились хотя бы с первой частью вышеупомянутого курса, а также внимательно прочитали в мануале быстрого старта, как правильно подключать модуль STM32 (чтобы ничего не пожечь) и как правильно его прошить. В общем, если на данный момент вы умеете «помигать диодиком», а программа Flash Loader Demo работает исправно, то вам зеленый свет, движемся дальше!


(далее…)

Read More »

Установка и конфигурация FreeRTOS

На самом деле это скорей интеграция ее в проект. С технической точки зрения выглядит как подключение библиотек. Как той же CMSIS или SPL. Добавляем инклюдники, добавляем файлы в проект и все. Можно взять готовый пример и переколхозить, но в этом случае есть шанс прозевать какие-нибудь детали и получить странные эффекты. Поэтому начну с нуля, в качестве основы будет модуль Pinboard STM32F103C8T6 и Keil uVision. Под него все мы и соберем.
 

▌Качаем ОС
Тащим архив с freertos.org. Это довольно толстая солянка где 99% занимают примеры под разные архитектуры. Вот его примерная структура:

 

Вся ОС по большей части прячется вот в этих нескольких файлах:

  • queue.c — функции очередей и мутексов
  • tasks.c — функции работы с задачами
  • timers.c — функции работы с таймерами
  • croutine.c — функции работы с сопрограммами
  • event_groups.c — функции работы с флагами
  • list.c — тут все для отладки
  • port.c — платформозависимые параметры. У каждого МК этот файл свой
  • portmacro.h — настройки платформы. Тоже индивидуальный для каждого типа МК
  • FreeRTOSConfig.h — настройки ОС. Платформозависимо, а еще зависит от целей и проекта

 
(далее…)

Read More »

FreeRTOS для чайников. Краткое описание.


Бытует мнение, что RTOS это некий хардкор для избранных. Что там все сложно, замудрено и новичкам туда соваться бестолку. Отчасти тут есть доля истины, такие системы крайне сложны в отладке, но и то лишь тогда, когда вы забиваете контроллер под завязку и работаете на пределе оперативной памяти и быстродействия. Тогда да, словить какой-нибудь dead lock или пробой стека можно на раз. И попробуй найти где это случилось в этой асинхронной системе. Но простые задачи на RTOS реализуются еще проще и с меньшим количеством мозга.
 

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

▌FreeRTOS?
Почему именно она? Она популярна, она Free и она портирована на огромное количество архитектур, под нее существуют плагины для Keil и IAR и всякие примочки для PC. При этом она довольно легкая и функциональная.
 

Я не буду вам сейчас тут расписывать все эти прототипы функций, порядок записи, технические тонкости и прочее. Это все есть в технической документации и в замечательном цикле статей Андрей Курница, что был в журнале Компоненты и Технологии в 2011 году. PDF статьи вы найдете в конце.
 

Я лишь на пальцах и псевдокоде быстро распишу те инструменты которыми владеет FreeRTOS, чтобы когда вы будете читать более подробную документацию за деревьями не потеряли лес :)
 

Ну и все сказанное тут справедливо и для большинства других RTOS. Т.к. механизмы в целом все одни и те же и никто ничего нового еще не придумал.
 
(далее…)

Read More »

ARM. Учебный курс. Внешние прерывания

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

У STM32 за внешние прерывания отвечает EXTI контроллер. Его основные возможности:
 

До 20 линий прерываний (в реальности несколько меньше, зависит от контроллера)
Независимая работа со всеми линиями. Каждой линии присвоен собственный статусный бит в спец регистре
Улавливает импульсы длительность которых ниже меньше периода частоты APB2
 

EXTI Может генерировать:

  • Прерывания — это когда происходит переход на обработчик
  • События — когда обработчик не вызывается, просто поднимается флажок. Может разбудить проц или пнуть какую периферию, АЦП, например.
  • Софтверные прерывания — то же самое, что и обычные прерывания, но мы их вызываем вручную, записью бита в регистр.

 
(далее…)

Read More »

ARM Учебный курс. USART

Самый простой и наиболее часто использующийся в быту и производстве :) Куда без него. О нем было много сказано тут, не буду повторяться, дам лишь ссылочки на старые статьи:


 

Вот и у STM32 он есть. Да не один, а целых дофига. В том контроллере, что стоит на Pinboard II в модуле STM32 — STM32F103C8T6 — их три. Обычно хватает и одного. Но три это же лучше! :)
 

Вообще у STM32 сей девайс навороченный и умеет не только байтики в терминалку слать в классических режимах (асинхронном, синхронном, мультипроцессорном), но и кое чего еще. В частности он может работать в
 

  • Однопроводном полудуплексном режиме
  • В режиме SmartCard — т.е. на том же языке на котором общаются с телефоном SIM карты. Вообще там вроде бы протокол отличается только таймингами немного
  • В режиме IrDA — помните на старых телефонах была такая фиговина? Вот это оно. Отличается от обычного протокола тем, что тут данные передаются краткими импульсами. Этакими вспышками. А 0 и 1 ловятся по паузам между ними. Так себя фотоприемники видать лучше чувствуют.
  • Также есть LIN режим. LIN это автомобильная сеть, этакий CAN для бедных. Вон во всяких приорах стекла и сигналки на LIN шине сидят.

 

В общем, полный фарш. Расписывать все не буду. Только самое основное. Иначе это книгу написать можно.
 
(далее…)

Read More »

ARM. Учебный Курс. SysTick — Системный таймер

Продолжаем потрошить кортексы М3. Есть у них у всех, вне зависимости от производителя, такая штука как системный таймер — SysTick. Это часть ядра. Тупейший и примитивный таймер. Он ничего не умеет кроме как генерировать прерывание в заданном промежутке времени. Используется обычно во всяких RTOS для проворачивания диспетчера. К тому же его прерывание имеет высокий приоритет.
 

Краткое описание
Сам таймер 24 разрядный. И тикает вниз от предзагруженного значения до нуля, после чего перезагружается вновь и генерирует прерывание. Управляется он четырьмя регистрами:

 
Таблица из ARM Cortex M3 Reference Manual
 
(далее…)

Read More »

ARM. Учебный Курс. Прерывания и NVIC — приоритетный контроллер прерываний

Стандартной плюхой ядра Cortex M3 является NVIC — контроллер приоритетных векторных прерываний. Сейчас я разжую что это такое и с чем это едят.
 

Прерывания и события
Вообще, если пошерстить мануал, то везде при разборе периферии рассматриваются interrupt/event. Может сложиться ощущение, что это одно и то же. Но это не так.
 

Interrupt — это прерывание. При прерывании обычно программа пакует регистры в стек и бросается по вектору, а оттуда через JMP сигает уже в обработчик прерывания. В кортексах все немного не так. Тут вектора прерывания это просто вектор-адреса лежащие в нужном месте. В виде констант. А при прерывании прога не прыгает на вектор, а берет этот вектор-адрес и сразу же пихает его в програмный счетчик, тем самым переходит сразу на обработчик. Так быстрей, исчезает лишняя операция по переходу на вектор.
 

Event — это аппаратное событие. Опустел буфер UART — держи event, натикал таймер — еще один event. Событие может вызвать прерывание, может запустить какую-либо периферию, например пнуть DMA, чтобы оно выгрузило данные. Но событие далеко не всегда может вызвать прерывание. Каждое прерывание вызывается событием, но не каждое событие вызывает прерывание. Вот. Так что надо отличать.
 

Как и в AVR в STM32 существуют вектора прерываний. Это особые адреса, куда контроллер бросается если происходит прерывание. Они записаны в таблицу и располагаются вначале памяти. Впрочем, система гибкая и переконфигурировав NVIC можно засунуть ее куда угодно. Если вы пишите на Си, то по дефолту, в стартовом файле, вектора прерываний забиты затычками которые ведут в бесконечный цикл. Так что если вызывать прерывание не указав ему обработчик контроллер тупо повиснет. Что является максимизацией ошибки и это хорошо.
 

(далее…)

Read More »

Определение текущей тактовой частоты при отладке

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

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

То в STM32, где описание системы RCC занимает 35 страниц убористого текста, схема не влезает на экран, а куча библиотек, вроде CMSIS и SPL или визардов, наподобие того что есть в CoIDE, генерируют стартовый код, определить текущую тактовую частоту превращается в непростую задачу. Ее и будем решать.
 

Как же понять, что у нас получилось на SYSCLOCK после всех этих HSI, HSE, делителей, мультиплексоров и PLL умножителей?
  (далее…)

Read More »

Работа с STM32F10x Standard Peripherals Library

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

Как это выглядит
Если вы пыталисьи курить STM32, то наверняка смотрели чужие исходники. И наверняка часто видели в них шнягу вида:
 

1
2
3
4
5
6
7
8
9
  /* GPIOD Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
 
  /* Configure PD0 and PD2 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 
  GPIO_Init(GPIOD, &GPIO_InitStructure);

 
Вот это и есть пример работы с STM32 Standard Peripherals Firmware Library, а точнее конфигурация вывода контроллера посредством стандартных функций этой библиотеки.
 
(далее…)

Read More »

ARM. Учебный Курс. Порты GPIO

Над портами инженеры STM поубивались знатно. Такой прорвы настроек и возможных режимо я, честно говоря, даже не ожидал. Порты у STM32F1xx могут работать в режиме*:
 

  • Вход Hi-Z
  • Вход с подтяжкой вверх
  • Вход с подтяжкой вниз
  • Аналоговый вход (для каналов АЦП)
  • Выход с открытым коллектором (стоком, если быть точным)
  • Выход тяни-толкай (push-pull)
  • И альтернативные функции, т.е. работа от периферии. Тут у нас формируется выход вида вида тяни-толкай или открытый коллектор.

 
(далее…)

Read More »

Прошивка ARM Cortex M3 на примере STM32 и LPC1300

Готовую программу надо каким-либо образом запихать в контроллер. Для этого существует множество способов.

JTAG/SWD адаптер
Так как часто для отладки под ARM используется JTAG, то этот метод получается наверное самым популярным. Для этой цели используется какой-либо адаптер. Например я использую CoLinkEX так что показывать буду на его примере. Там все просто — подключаешь адаптер к контроллеру стандартным SWD или JTAG шлейфом. Через линии NRST/TDI/TDO/TCK/TMS для JTAG или через SWO/SWOCLK/SWDIO/NRST для SWD режима. На адаптере моей верси CoLinkEX оба эти разьема выведены на одну колодку, так что получается как бы сразу и JTAG и SWD соединение. А там какое надо такое и выбираешь. Особой разницы в отладке/прошивке между ними нет.

И прошиваешь либо из среды Keil.

Либо используя утилитку CoFlash oт CooCox.com (далее…)

Read More »