Ознакомительное руководство по arm микроконтроллерам cortex m3

Предисловие

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

Почему ARM?

STM32

Технический прогресс не стоит на месте, появляются различные все более сложные устройства, и соответственно производители микроконтроллеров спешат не отстать от технического прогресса, разрабатывая все более мощные и «навороченные» микроконтроллеры, при этом постоянно снижая цены на них. В последнее время наметился рост популярности ARM микроконтроллеров, а с приходом бюджетных контроллеров с ядром Cortex-M цена стала настолько доступной, что уже может спокойно конкурировать с 8 и 16 битными контроллерами, такими как AVR, PIC, MSP430 и т.п., а зачастую она даже бывают меньше цены своих восьмибитных собратьев. Помимо этого для ARM микроконтроллеров существует множество средств отладки и программирования, цены на которые, вполне доступные даже для покупки «для домашнего использования». Так, например, официальная отладочная плата STM32VL Discovery имеющая на борту внутрисхемный отладчик ST-LINK и отлаживаемый микроконтроллер STM32F100RBT со 128 кБайт флеш памяти, 8 кБайт ОЗУ и 24МГц тактовой частотой в розницу стоит 10-15 долларов.

Для сравнения возьмем несколько популярных контролеров находящихся примерно в одной ценовой категории и сравним их с ARM контроллером STM32F100C4T6B продающимся по цене менее 1 доллара.

Таблица 1. Сравнительная таблица параметров распространенных микроконтроллеров

Параметр

STM32F100C4T6B

ATmega48PA-PU

ATtiny13A-SSU

PIC16F505-I/SL

Средняя цена

30 руб.

55 руб.

30 руб.

35 руб.

Объем флеш памяти (ROM, памяти программ)

16 КБайт

4 КБайта

1 КБайт

1 КБайт

Объем оперативной памяти (RAM, памяти данных)

4096 Байт

512 Байт

64 Байта

72 Байта

Тактовая частота

24 МГц, 30 DMIPS

20 МГц

20 МГц

20МГц

Линий ввода/вывода

37

23

6

12

АЦП

16-каналов

12-бит

8-каналов

10-бит

4-канала

10-бит

0

ЦАП

12–битный

0

0

0

USART

2

1

0

0

SPI

1

1

1

0

I2C

1

1

0

0

Количество таймеров

5

3

1

1

DMA

7 каналов

0

0

0

Из таблицы явно видно, что ARM микроконтроллер STM32F100C4T6B по всем параметрам оставляет своих 8-и битных собратьев далеко отстающими. Помимо указанных в таблице особенностей следует также принять во внимание тот факт, что ARM контроллеры являются 32 разрядными, что означает возможность работы с 32 битными данными за один такт процессора, для 8 битных же процессоров для этого требуется гораздо большее количество тактов.

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

Как мы уже убедились, ARM микроконтроллеры имеют гораздо более высокие технические характеристики и возможности. Мы провели сравнение на самом младшем микроконтроллере STM32, на текущий момент самым «навороченным» из этой серии можно назвать микроконтроллеры STM32F407, имеющий 1 мегабайт ROM памяти, 192 килобайта RAM памяти и работающем на частоте до 168 МГц, при этом выполняя до 210 миллионов операций в секунду.

Данный микроконтроллер включает в себя такие модули как:

  • интерфейс камеры;
  • крипто/хеш аппаратный процессор;
  • Ethernet MAC10/100 с IEEE 1588 v2;
  • 2 USB OTG;
  • отдельный аудио PLL и 2 полнодуплексных I²S;
  • до 15 коммуникационных интерфейсов включающих:
    —  6x USART;
    —  3x SPI;
    —  3x I²C;
    —  2x CAN;
    —  SDIO
  • 2x 12-bit АЦП;
  • 3x 12-bit ЦАП;
  • до 17 таймеров 16 и 32 битных работающих до 168 МГц;
  • Шина (FSMC) подключения внешних RAM, ROM, NandFlash;
  • Контроллер DMA используя его можно легко и непринужденно пересылать блоки данных между периферией и памятью без использования процессора.

Такому богатому набору периферийных модулей, пожалуй, может позавидовать любой 8и битный микроконтроллер.

Вопрос отладки и программирования также не является проблемой, поскольку за 10-15 долларов можно приобрести официальную отладочную плату STM32VL Discovery (см. рис. 1), имеющую выход для программирования внешних микроконтроллеров.

STM32VLDiscovery
Рис. 1 Фотография STM32VLDiscovery

Но даже если у Вас нет такой платы, то Вы всегда сможете запрограммировать микроконтроллер, через имеющийся в нем заводской загрузчик (bootloader), подключив его через USART или USB к своему ПК, для этого не потребуется каких либо аппаратных программаторов. Для программирования микроконтроллера имеющего встроенный USB бутлоадер, достаточно скопировать файл прошивки на контроллер, как на USB-накопитель. Для программирования микроконтроллера через USART, необходимо произвести его подключение к ПК с помощью преобразователя уровней USART-RS232 либо USART-USB преобразователя и воспользовавшись программой Flash Loader Demonstrator произвести загрузку файла прошивки во флеш память микроконтроллера. Программу Flash Loader Demonstrator можно взять с официального сайта компании ST.

Кроме этого у микроконтроллеров с ядром ARM Cortex-M3, по сравнению, например с ATMega и т.п. нет фьюзов, все управление осуществляется полностью программно, таким образом, отсутствует вероятность испортить микроконтроллер неправильным программированием фьюз битов.

Так почему же, при всех этих преимуществах, ARM микроконтроллеры еще не вытеснили другие контроллеры? Причин этому несколько. Во первых ядро ARM Cortex-M3, благодаря которому появились столь дешевые микроконтроллеры серии ARM, появилось относительно недавно и как следствие пока существует не так много примеров программ и библиотек, но их количество постоянно увеличивается с очень большой скоростью, в том числе большой вклад в это развитие вносят и сами производители микроконтроллеров ST и NXP, создавая различные апноуты и библиотеки. Другим фактором является лень многих людей осваивать новую для них архитектуру, а также необходимость приобретения средств для отладки, ведь им зачастую хватает и восьми битных микроконтроллеров, при этом они очень много сил и времени тратят на то, чтобы уложиться в имеющиеся в микроконтроллере ресурсы. Для начинающих же такое обилие имеющийся периферии и настроек пугает кажущейся сложностью в освоении, но в действительности это является заблуждением, поскольку производители микроконтроллеров позаботились и создали удобные библиотеки для работы с периферией, позволяющей практически не открывая даташит настроить основные периферийные модули. Также сдерживающим фактором на применение микроконтроллеров ARM Cortex-M3 в «домашних условиях» является наличие микроконтроллеров в корпусах LQFP с шагом ножек 0.5 мм, но тем не менее, такую плату при определенной сноровке изготовить ЛУТом не составит большого труда.

Таким образом, рассеяв последние опасения, и убедившись в том, что STM32 на ядре ARM Cortex-M3 это действительно достойный для изучения и применения микроконтроллер, можно смело переходить к первому шагу. Для начала нам потребуется скачать и установить необходимые для работы программы, справочные материалы и библиотеки. Поскольку большинство пользователей, работают под операционной системой Windows, то я буду рассматривать описание программ только для данной операционной системы, но хочу заметить, что пользователи других операционных систем также имеют возможность заниматься разработкой программ для МК ARM STM32. Для этого им необходимо использовать ПО для своей операционной системы, например все необходимое ПО для Linux можно скачать здесь. Но в любом случае описанные мною программы для Windows. возможно запустить под Wine, за исключением возможности внутрисхемной отладки и программирования.

-Flash Loader Demonstrator — программа необходима для загрузки микропрограммы во флеш контроллер, через встроенный бутлоадер;

-ST-LINK Utility – программа для записи/чтения флеш памяти микроконтроллера через отладчик ST-LINK;

-ST-LINK USB – драйвер для отладчика ST-LINK;

-UM0627: ST-LINK in-circuit debugger/programmer for STM8 and STM32 microcontrollers – документ описывающий какие выводы и как подключать к программатору/отладчику;

-UM0919: STM32VLDISCOVERY STM32 value line Discovery — описание отладочной платы STM32VL Discovery, включающее в себя назначение выводов платы и схему электрическую принципиальную;

-DS6517: Low & medium-density value line, advanced ARM-based 32-bit MCU with 16 to 128 KB Flash, 12 timers, ADC, DAC & 8 comm interfaces – описание аппаратной части микроконтроллера STM32F100;

-RM0041: STM32F100xx advanced ARM-based 32-bit MCUs – описание всех регистров микроконтроллера STM32F100;

-STM32F10x standard peripheral library – стандартная библиотека для работы с периферией от компании ST;

IAR Embedded Workbench for ARM — мощная и эффективная среда разработки для ARM микроконтроллеров на языке C. Поскольку программа является платной, то ссылку для скачивания не указываю, но хочу заметить, что помимо платной версии также существуют и бесплатные версии с ограничением по времени работы программы. Официально бесплатные версии можно скачать с сайта производителя http://www.iar.com, пробная 30 дневная версия доступна по ссылке.

Официальная утилита для конфигурирования периферии microxplorer — Пока что данная программа находится на этапе разработке и в ней реализованы еще не все задуманные функции.

STM32 Генератор программного кода – бесплатная программа для наглядного создания кода настройки микроконтроллера. Данная программа пока что еще является развивающейся и содержит много недоработок, но автор работает над данной программой, постоянно исправляя ошибки, совершенствуя программу и добавляя новые возможности.

Ознакомительное руководство по ARM-микроконтроллерам Cortex-M3– Данное руководство будет полезно для ознакомления со структурой микроконтроллеров семейства STM32 Cortex-M3.

STM_DOC_RU — содержит переводы трех документов с сайта фирмы ST:
Частичный перевод файла «STM32F10xxx Cortex-M3 programming manual.PDF» ревизия 2 от 18.01.2010.
Частичный перевод файла «STM32F105_107_Reference manual.pdf» ревизия 9 от 14.09.2009.
Полный перевод файла «Errata_stm32f107.pdf» ревизия 3 от 14.01.2010.

Работа с данными программами (за исключением IAR Embedded Workbench) довольна простая и не должна вызвать затруднения. О работе в среде программирования IAR Embedded Workbench будет рассказано в третьей части.

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

Что такое микроконтроллер ARM STM32 и как он устроен?

Для начала выясним, что же такое микроконтроллер. Микроконтроллер (англ. Micro Controller Unit, MCU) — микросхема, предназначенная для управления электронными устройствами. Типичный микроконтроллер сочетает в себе функции процессора и периферийных устройств, содержит Оперативное Запоминающее Устройство (ОЗУ) или Постоянное Запоминающее Устройство (ПЗУ). По сути, это однокристальный компьютер, способный выполнять простые задачи. Как и компьютер, микроконтроллер — это электронное устройство, работой которого управляет программа — последовательность команд, заранее загруженная в память. В отличие от микропроцессоров, используемых в персональных компьютерах, микроконтроллеры содержат встроенные дополнительные устройства (такие периферийные модули как таймеры, SPI, USART и т.п.).

Для хранения исполняемого кода программ используется flash память, называемая также ROM памятью или памятью программ. Данная память является энергонезависимой, а количество циклов записи/стирания ограничено порядка 10 000 раз. Данная память является неким подобием жесткого диска компьютера.

Для хранения различных изменяющихся данных, используемых во время выполнения программы, предназначена оперативная память (RAM), или её также называют памятью данных. Эта память может быть записана/стерта любое количество раз, но данные в этой памяти могут сохраняться только пока на микроконтроллер подано питание. Данная память является подобием оперативной памяти компьютера.

Для сохранения редко изменяющихся данных и хранения их во время, когда питание микроконтроллера отключено, используется EEPROM память. Данная память имеется у некоторых видов микроконтроллеров, но в виду её отсутствия в микроконтроллерах ARM Cortex данный вид памяти эмулируется программно, и в качестве физической памяти для сохранения данных используется flash память.

Разумеется, любая выполняющаяся программа на любом микроконтроллере должна «общаться» с внешним миром, для этого у всех микроконтроллеров существуют группы выводов, называемых портами ввода/вывода. Для обозначения выводов портов используется буквенно-цифровое обозначение, такое как А0, А1, А5, В4 и т.п. Буквой обозначается имя самого порта, а цифрой указывается конкретный вывод данного порта. Все выводы одного порта могут быть одновременно изменены на требуемое состояние, выводы разных портов только поочередно, сперва изменяется состояние всех нужных выводов одного порта, затем другого порта. Количество выводов одного порта может насчитывать до 16шт, нумерация выводов начинается с нулевого.

Для примера рассмотрим микроконтроллер STM32F100Cxx. Данный микроконтроллер изготовлен в корпусе LQFP48, и имеет 48 выводов, 37 из которых могут использоваться как порты ввода/вывода. Этот микроконтроллер имеет 4 порта, два из которых, порт А и порт В полные, т.е. содержат все 16 выводов, и два не полных порта, это порты С и D, содержащие только 3 и 2 вывода соответственно.

Оставшиеся выводы задействованы для других функций, таких как питание самого микроконтроллера, выводы Vdd и Vss, питание аналоговой части Vdda и Vssa, вход батарейного питания Vbat, для работы встроенных часов реального времени и вход BOOT0, для выбора загрузки встроенного бутлоадера.

Расположение выводов микроконтроллера STM32F100Cxx
Рис. 2. Расположение выводов микроконтроллера STM32F100Cxx

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

  • аналоговый вход (для выводов, на которые выведен вход АЦП, аналогового компаратора) (см. рис 3);
  • цифровой вход, для непосредственной работы с портом (может иметь верхний (к питанию) и нижний (к общему проводу) подтягивающий резистор) (см. рис. 4);
  • цифровой вход в режиме альтернативной функции (используется как вход для различных периферийных модулей) (см. рис. 6).
  • В режиме работы на выход, выводы порта могут быть настроены следующим образом:
  • выход с непосредственным программным управлением с симметричным выходом (push-pull) (см. рис. 5);
  • выход с непосредственным программным управлением с открытым стоком (см. рис. 5);
  • выход в режиме работы альтернативной функции (выход для различных периферийных моделей, таких как SPI, USART, ШИМ (PWM) и пр.), с симметричным выходом (push-pull) (см. рис. 6);
  • выход в режиме работы альтернативной функции, с открытым стоком (например, выход ШИМ) (см. рис. 6).

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

Режим работы вывода порта в качестве аналогового входа
Рис. 3 Режим работы вывода порта в качестве аналогового входа

Режим работы вывода порта в качестве цифрового входа
Рис. 4 Режим работы вывода порта в качестве цифрового входа

Режим работы вывода порта в качестве цифрового выхода
Рис. 5 Режим работы вывода порта в качестве цифрового выхода

Режим работы вывода порта в качестве цифрового входа/выхода в режиме альтернативной функции
Рис. 6 Режим работы вывода порта в качестве цифрового входа/выхода в режиме альтернативной функции

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

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

Таблица 2. Периферийные интерфейсные модули

Название интерфейса

Описание

FSMC

Интерфейс подключения внешней SRAM, PSRAM, NOR, NANDROM, RAM, NandFlash, Compact Flash памяти, а также для подключения LCD дисплеев с параллельной шиной.

Ethernet

Интерфейс для подключения к компьютерной сети.

SPI/(I2S)

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

I2C

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

USART

UART

Стандартный универсальный синхронный (асинхронный) приемо-передающий интерфейс, служит для обмена данными с другими устройствами через RS-232, RS-485 шины и т.п..

USB

Современный компьютерный интерфейс передачи данных, предназначен для подключения к микроконтроллеру USB клавиатур, flash накопителей, а также для подключения микроконтроллера к ПК, может работать как в режиме устройства (Device), так и в режиме хоста (Host).

CAN

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

Camera interface

Специализированный интерфейс, предназначенный для подключения высокоскоростной цифровой камеры, с 8-, 10-, 12- или 14-битной параллельной шиной данных

SDIO

Интерфейс для высокоскоростного подключения SD карт памяти.

HDMI

Мультимедийный интерфейс высокой четкости

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

Помимо периферийных модулей, отвечающих за обмен данными с внешними устройствами, существуют также и другие различные периферийные модули, значение которых не менее важное, чем интерфейсных модулей. Список этих периферийных модулей приведен в таблице 3.

Таблица 3. Периферийные модули

Название модуля

Описание

Таймер

Очень важный модуль, позволяющий точно отмерять интервалы времени, генерировать выходной ШИМ сигнал, подключать энкодер, подсчитывать период входного сигнала и др.

ADC (АЦП)

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

DAC (ЦАП)

Цифро-аналоговый преобразователь выдает на выходе аналоговый сигнал соответствующий заданному цифровому значению.

CRC

Модуль подсчета CRC

RTC

Часы реального времени

DMA

Модуль прямого доступа к памяти

JTAG

Модуль внутрисхемной отладки программы

Прерывания

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

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

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

Ядра микроконтроллера (в нашем случае ARM Cortex-M3), выполняющего программные команды;

Flash памяти для хранения кода выполняемой программы;

RAM памяти, для хранения переменных данных;

Портов ввода/вывода, для «общения с внешним миром»;

Периферийных модулей, выполняющих программные и/или аппаратные действия;

Контроллера вложенных векторизованных прерываний, позволяющего по определенному событию прервать выполнение основной программы и перейти к выполнению другой подпрограммы;

Шины данных, соединяет всё вышеперечисленное в единое целое устройство.

Устройство микроконтроллера

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

Для начала рассмотрим схему включения микроконтроллера STM32F100RBT6B в отладочной плате STM32VLDiscovery (см. рис. 7).

Схема электрическая принципиальная включения отлаживаемого микроконтроллера платы STM32VLDiscovery
Рис. 7. Схема электрическая принципиальная включения отлаживаемого микроконтроллера платы STM32VLDiscovery

Как видно из схемы на рисунке 7, все выводы портов микроконтроллера выведены на внешний разъем, это сделано для возможности использования подключения к данному контроллеру внешних устройств и элементов.

На данной плате также имеется пользовательская кнопка В1, подключенная к нулевому выводу порта А (РА0). В свободном состоянии кнопка разомкнута и через резистор R21 вход порта подтянут на землю, конденсатор С22 защищает вход от внешних наводок. При нажатии на кнопку, вход микроконтроллера РА0 замыкается на плюс питания, таким образом на микроконтроллер подается логическая единица.

Кнопка В2 замыкает вывод микроконтроллера RESET на общий провод, таким образом, это приводит к аппаратному сбросу программы. По отпускании кнопки, через подтягивающий резистор R24, вход RESET подтягивается к +3,3В, и контроллер начинает выполнение программы с самого начала.

Вывод микроконтроллера BOOT0, разрешающий запуск встроенного загрузчика (бутлоадера), через резистор R14 и перемычку SB16 подключен к общему проводу, таким образом, он запрещает запуск встроенного бутлоадера. Для разрешения запуска встроенного бутлоадера необходимо замкнуть вывод BOOT0 на +3,3В. Если в момент сброса на BOOT0 окажется низкий логический уровень, то не зависимо от того, какой уровень на BOOT1 МК грузится из внутренней флеш памяти (запускается написанная нами программа). В случае если на BOOT0, во время перезагрузки/включения, окажется высокий уровень, тогда анализируется вход BOOT1, чтобы определить вариант дальнейшей загрузки, т.е. грузиться микроконтроллеру из внутреннего бутлоадера или из оперативной памяти.

К выводам 3  микроконтроллера (OSC32_OUT) и 4 (OSC32_IN) подключен кварцевый резонатор Х3, с рабочей частотой 32768Гц. Данный кварцевый резонатор предназначен для тактирования встроенных часов реального времени. Для тактирования самого микроконтроллера установлен кварцевый резонатор Х2, работающий на частоте 8МГц. Этот кварц установлен в специальную панельку и без проблем может быть заменен на другой либо убран.

К выводам 8 и 9 порта С через токоограничительные резисторы подключены зеленый LD3 и синий LD4 светодиоды.

Выводы 46 (TMS/SWDIO) и 49 (TCK/SWCLK) контроллера подсоединены к установленному на этой же плате ST-Link программатору-отладчику и используются для программирования и внутрисхемной отладки микроконтроллера.

Установленный микроконтроллер имеет следующие характеристики:

  • ROM 128кБайт,
  • 8кБайт RAM,
  • 7 таймеров,
  • 2 SPI интерфейса,
  • 2 I2C интерфейса,
  • 3 USART интерфейса,
  • Один 16-и канальный, 12-и битный АЦП,
  • Два двухканальных 12-и битных ЦАП,
  • 7-и канальный DMA контроллер,
  • 51 линию ввода/вывода
  • Максимальная тактовая частота 24МГц,
  • Диапазон питающих напряжений 2.0-3.6В

Расположение выводов микроконтроллера, с кратким описанием некоторых из них приведено в таблице 4.

Таблица 4. Назначение выводов микроконтроллера STM32F100RBT6B

№ вывода

Название основной функции
(описание)

Альтернативная функция

Перенаправление

1

Vbat (вход питания для часов от резервной батареи)

   

2

PC13

TAMPER-RTC

 

3

PC14 (выход для подключения кварцевого резонатора)

OSC32_IN (вход для подключения часового кварцевого резонатора (32768Гц))

 

4

PC15

OSC32_OUT (выход для подключения часового кварцевого резонатора)

 

5

OSC_IN (вход для подключения кварцевого резонатора)

PD0

 

6

OSC_OUT (выход для подключения кварцевого резонатора)

PD1

 

7

NRST (вход аппаратного сброса)

   

8

PC0

ADC1_IN10 (вход АЦП)

 

9

PC1

ADC1_IN11

 

10

PC2

ADC1_IN12

 

11

PC3

ADC1_IN13

 

12

VSSA (минус питания аналоговой части (аналоговая «земля»))

   

13

VDDA (+3,3В питание аналоговой части)

   

14

PA0

WKUP / USART2_CTS/ADC1_IN0 / TIM2_CH1_ETR

 

15

PA1

USART2_RTS/ADC1_IN1/TIM2_CH2

 

16

PA2

USART2_TX/ADC1_IN2/
TIM2_CH3/TIM15_CH1

 

17

PA3

USART2_RX/ADC1_IN3/

TIM2_CH4/TIM15_CH2

 

18

VSS_4 (минус питания цифровой части)

   

19

VDD_4 (+3,3В питание цифровой части)

   

20

PA4

SPI1_NSS / ADC1_IN4

USART2_CK / DAC1_OUT

 

21

PA5

SPI1_SCK /ADC1_IN5 / DAC2_OUT

 

22

PA6

SPI1_MISO /ADC1_IN6 / TIM3_CH1

TIM1_BKIN / TIM16_CH1

23

PA7

SPI1_MOSI /ADC1_IN7 / TIM3_CH2

TIM1_CH1N /

TIM17_CH1

24

PC4

ADC1_IN14

 

25

PC5

ADC1_IN15

 

26

PB0

ADC1_IN8/TIM3_CH3

TIM1_CH2N

27

PB1

ADC1_IN9/TIM3_CH4

TIM1_CH3N

28

PB2/BOOT1

   

29

PB10

I2C2_SCL / USART3_TX

TIM2_CH3 / CEC

30

PB11

I2C2_SDA / USART3_RX

TIM2_CH4

31

VSS_1 (минус питания цифровой части)

   

31

VDD_1 (+3,3В питание цифровой части)

   

33

PB12

SPI2_NSS / I2C2_SMBA /

TIM1_BKIN / USART3_CK

 

34

PB13

SPI2_SCK/TIM1_CH1N/USART3_CTS

 

35

PB14

SPI2_MISO/TIM1_CH2N/USART3_RTS

TIM15_CH1

36

PB15

SPI2_MOSI/TIM1_CH3N/TIM15_CH1N

TIM15_CH2

37

PC6

 

TIM3_CH1

38

PC7

 

TIM3_CH2

39

PC8

 

TIM3_CH3

40

PC9

 

TIM3_CH4

41

PA8

USART1_CK / MCO / TIM1_CH1

 

42

PA9

USART1_TX / TIM1_CH2

TIM15_BKIN

43

PA10

USART1_RX / TIM1_CH3

TIM17_BKIN

44

PA11

USART1_CTS / TIM1_CH4

 

45

PA12

USART1_RTS / TIM1_ETR

 

46

PA13

   

47

VSS_2 (минус питания цифровой части)

   

48

VDD_2 (+3,3В питание цифровой части)

   

49

PA14

   

50

PA15

 

TIM2_CH1_ETR/ PA15/ SPI1_NSS

51

PC10

 

USART3_TX

52

PC11

 

USART3_RX

53

PC12

 

USART3_CK

54

PD2

TIM3_ETR

 

55

PB3

 

TIM2_CH2 / PB3

TRACESWO

SPI1_SCK

56

PB4

 

PB4 / TIM3_CH1

SPI1_MISO

57

PB5

I2C1_SMBA / TIM16_BKIN

TIM3_CH2 /

SPI1_MOSI

58

PB6

I2C1_SCL / TIM4_CH1 / TIM16_CH1N

USART1_TX

59

PB7

I2C1_SDA / TIM17_CH1N / TIM4_CH2

USART1_RX

60

BOOT0 (вход выбора встроенного загрузчика (бутлоадера))

   

61

PB8

TIM4_CH3 / TIM16_CH1 / CEC

I2C1_SCL

62

PB9

TIM4_CH4  / TIM17_CH1

I2C1_SDA

63

VSS_3 (минус питания цифровой части)

   

64

VDD_3 (+3,3В питание цифровой части)

   

Некоторые периферийные модули в своих настройках позволяют изменить свои выводы на другие ножки микроконтроллера. Варианты ножек на которые возможно сделать такое перенаправление, для каждого конкретного модуля, указано в в столбце «Перенаправление» таблице 4. Возможность такого перенаправления выводов периферийных модулей позволяет более эффективно использовать имеющуюся на борту периферию, а также облегчает процесс трассировки платы, во время разработки устройства. Таблицу назначения выводов и возможных вариантов переназначения функций выводов для конкретного контроллера необходимо смотреть в разделе 3 «Pinouts and pin description» даташита на конкретный контроллер.

Управление контроллером

Для управления любым периферийным модулем микроконтроллера необходимо произвести запись соответствующих настроек в регистр данного периферийного модуля. Регистры микроконтроллера представляют собой специальные элементы памяти, предназначенные для организации управления (управление прерываниями, таймерами, интерфейсными модулями и т.д.) и ввода/вывода данных (регистры данных портов, интерфейсных модулей и т.д.). У каждого периферийного модуля имеется свой определенный набор регистров, каждый регистр представляет собой 32-х битное число. Описание всех регистров с возможными вариантами настройки находится в файле «RM0041 Reference manual.pdf», приводить полный список регистров и тем более их описания не вижу смысла, поскольку во первых это описание занимает более 600 страниц, и во вторых при написании нами программ, в последних частях данного цикла статей, я познакомлю вас работе с библиотеками от ST для периферии и ядра, делающих работу с микроконтроллером существенно нагляднее и понятнее. А сейчас рассмотрим основы работы с регистрами, для понимания принципов работы с настройкой микроконтроллера.

Любое устройство на микроконтроллере должно выполнять некоторое заложенные программой функции и в соответствии с этим алгоритмом управлять внешними элементами. Для возможности такого управления необходимо настроить соответствующие выводы порта на выход. В качестве примера можно включить светодиоды LD3 и LD4.

Перед настройкой любого периферийного модуля необходимо разрешить тактирование шины, на которой находится данный модуль. После включения микроконтроллера, все эти шины отключены от тактирования, это сделано для минимизации энергопотребления микроконтроллера. Светодиоды LD3 и LD4 подключены к порту С. За тактирование порта С отвечает регистр RCC_APB2ENR (см. таблицу 5 статьи, либо стр. 91, 92 файла RM0041 Reference manual.pdf).

Таблица 5. Структура регистра RCC_APB2ENR
Структура регистра RCC_APB2ENR

Данный регистр является 32х битным, это значит, что он может содержать до 32х логических параметров. В нашем случае для порта С используется бит с номером 4, называющийся IOPCEN (расшифровывается как — Input/Output Port C clock ENabled). Для разрешения тактирования порта С, мы должны установить этот бит в логическую единицу (как производить такую установку на языке программирования, будет рассказано в следующих частях). После того как мы разрешили тактирование порта С, можно приступать к настройке самого порта.

Нам необходимо произвести настройку нашего порта на симметричный выход (в режиме полумоста (push-pull)). Рассмотрим, какие в микроконтроллере имеются регистры, относящиеся к настройке портов ввода/вывода, описание данных регистров начинается на стр. 111 (раздел 7.2 в файле RM0041 Reference manual.pdf).

GPIOx_CRL — Младший регистр конфигурации порта х;

GPIOx_CRH — Старший регистр конфигурации порта х;

GPIOx_IDR — Регистр данных входа, в этом регистре находятся значения входных логических уровней порта, данный регистр предназначен только для чтения физического состояния выводов порта x;

GPIOx_ODR – Выходной регистр осуществляет запись данных непосредственно в порт х;

GPIOx_BSRR – Регистр сброса/установки битов порта;

GPIOx_BRR – Регистр побитного сброса и установки состояния выходов порта;

GPIOx_LCKR – Регистр блокировки изменений настроек порта.

Рассмотрим подробнее назначение данных регистров.

Регистры конфигурации порта GPIOx_CRL и GPIOx_CRH

Таблица 6. Структура регистра GPIOx_CRL
Структура регистра GPIOx_CRL

Таблица 7. Структура регистра GPIOx_CRH
Структура регистра GPIOx_CRH

Настройка каждого вывода порта занимает четыре бита данных. Настройки младших 8 выводов порта расположены в регистре GPIOx_CRL, настройки старших 8 бит расположены в регистре GPIOx_CRH.

Группа битов MODEn определяет направление порта (на вход или выход) и максимальную частоту работы порта, если порт настроен на выход.

Таблица 8. Описание полей MODEn

MODEn[1]

MODEn[0]

Режим

0

0

Вход (режим по умолчанию)

0

1

Выход с максимальной частотой работы порта 10МГц

1

0

Выход с максимальной частотой работы порта 2МГц

1

1

Выход с максимальной частотой работы порта 50МГц

Группа битов CNFn определяет параметры порта, режим работы порта, который определяет данная группа битов, зависит от настройки направления порта.

Таблица 9. Описание полей CNFn

CNFn[1]

CNFn[0]

Порт настроен на вход

Порт настроен на выход

0

0

Аналоговый режим

Симметричный выход (push-pull)

0

1

Цифровой вход (режим по умолчанию)

Выход с открытым стоком

1

0

Цифровой вход с подтягивающими резисторами

Симметричный выход в режиме альтернативной функции

1

1

Зарезервирован

Выход в режиме альтернативной функции с открытым стоком

Поскольку нам требуется настроить выводы как симметричный выход, а большого быстродействия порта не требуется, то нам необходимо в регистр порта С GPIOC_CRH в бите вывода 8 MODE81 установить логическую единицу, а бит MODE80 сбросить в ноль (хотя он у нас является сброшенным по умолчанию), таким образом, мы настроим вывод как выход с максимальным быстродействием 2МГц. Для выбора работы порта с выходом в режиме push-pull необходимо в регистре GPIOС_CRH сбросить биты CNF81 и CNF80. Аналогично необходимо поступить и с выводом 9 порта С. В результате мы должны записать в регистр GPIOC_CRH число, представленное в двоичном виде — 0010 0010, это же число в шестнадцатеричном виде — 22. Содержимое данного регистра после этого будет соответствовать представленному в таблице 10.

Таблица 10. Содержимое регистра GPIOx_CRH после внесения изменений
Содержимое регистра GPIOx_CRH после внесения изменений

Установку и сброс состояния выводов можно произвести двумя способами, первый способ это непосредственная запись в выходной регистр порта GPIOx_ODR значения всех выводов порта.

Если нам необходимо изменить содержимое не всего порта, а только некоторых выводов, то можно пойти другим путем. Для этого достаточно в регистре GPIOx_BSRR указать маску, по которой будут установлены в единицу и/или сброшены в ноль соответствующие выводы. Структура этого регистра представлена в таблице 11.

Таблица 11. Структура регистра GPIOx_BSRR
Структура регистра GPIOx_BSRR

Данный регистр не может быть прочитан, он предназначен только для записи. Для установки нужных выводов в единицу, необходимо соответствующие выводам биты BS, регистра GPIOx_BSRR установить в единицу, выводы в которых биты BS небыли установлены, не будут изменены. Аналогично дело обстоит и со сбросом выводов в ноль, для этого в регистре GPIOx_BSRR имеются биты BR. Все выводы, для которых соответствующие биты BR были установлены, перейдут в нулевое логическое состояние. Использование данного регистра позволяет изменить состояние требуемых выводов порта, не изменяя состояния других выводов.

Так для того чтобы включить наши светодиоды, нам необходимо в регистре GPIOC_BSRR установить в единицу биты BS8 и BS9. Для этого достаточно в регистр GPIOC_BSRR записать число в двоичном виде 0000 0011 0000 0000, или это же число представленное в шестнадцатеричном виде 0х0000 0300. Для выключения только одного зеленого светодиода LD3 (он находится на выводе PC9) необходимо в регистре GPIOC_BSRR возвести бит BR9, т.е. число в этот регистр 0000 0001 0000 0000 (в двоичном виде) или оно же 0х0000 0100 (в шестнадцатеричном виде).

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

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

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

Подключение LCD дисплея к плате STM32VLDiscovery:

Демонстрация возможностей графической оболочки μU/GUI на плате STM32Mini+2.4″ LCD

Плеер с сенсорным графическим LCD дисплеем

Подключение камеры

Список использованных источников:
Серия STM32F100 (http://www.st.com/internet/mcu/product/216844.jsp)
Википедия (http://ru.wikipedia.org/wiki)
Ознакомительное руководство по ARM-микроконтроллерам Cortex-M3 (http://www.gaw.ru/html.cgi/txt/doc/micros/arm/cortex_arh/index.htm)

ARM – это просто (часть 2). Учимся говорить с электроникой на одном языке

Сторожев Денис (Дeн)

Теги:

Пару дней назад я опубликовал и потом внезапно убрал в черновики статью о плане написать про создание своей ОС для архитектуры ARM. Я сделал это, потому что получил много интересных отзывов как на Хабре, так и в G+.

Сегодня я попробую подойти к вопросу с другой стороны, я буду рассказывать о том, как программировать микроконтроллеры ARM на нарастающих по сложности примерах, пока мы не напишем свою ОС или пока мне не надоест. А может, мы перепрыгнем на ковыряние в Contiki, TinyOS, ChibiOS или FreeRTOS, кто знает, их там столько много разных и интересных (а у TinyOS еще и свой язык программирования!).

Итак, почему ARM? Возиться с 8-битными микроконтроллерами хотя и интересно, но скоро надоедает. Кроме того, средства разработки под ARM обкатаны долгим опытом и намного приятнее в работе. При этом, начать мигать светодиодами на каком-то «evaluation board» так же просто, как и на Arduino.

Небольшой экскурс в архитектуру

ARM продвигает замечательную архитектуру, которую успешно лицензирует, мне на самом деле сложно представить, в каком устройстве нет никакого присутствия продуктов этой компании. В вашем смартфоне гарантированно есть несколько ядер на базе архитектуры ARM. Еще парочка найдется в современном ноутбуке (и это даже не CPU, а так, сопутствующий контроллер какой-либо периферии), еще несколько – в автомобиле. Есть они и в других бытовых вещах: микроволновках и телевизорах.

Такая гибкость достигается тем, что в самом базовом варианте ядро ARM очень простое. Сейчас существуют три разновидности этой архитектуры. Application применяется в устройствах «общего назначения» – как основной процессор в смартфоне или нетбуке. Этот профиль самый навороченный функционально, тут есть и полноценный MMU (модуль управления памятью), возможность аппаратно выполнять инструкции Java bytecode и даже поддержка DRM-схем. Microcontroller – это полная противоположность профилю application, применяемая (внезапно!) для использования в микроконтроллерах. Тут актуально минимальное энергопотребление и детерминистическое поведение. И, наконец, real-time используется как эволюция профиля microcontroller для задач, где критично иметь гарантированное время отклика. Все эти профили получили реализацию в одном или нескольких ядрах Cortex, так, например, Cortex-A9 основан на профиле application и является частью процессора в iPhone 4S, а Cortex-M0 основан на профиле microcontroller.

Железки!


В качестве целевой платформы мы будем рассматривать работу с Cortex-M, так как она самая простая, соответственно, надо вникать в меньшее количество вопросов. В качестве тестовых устройств я предлагаю вам LPC1114 – MCU производства NXP, схему на котором можно собрать буквально на коленке (нет, правда, вам нужен только сам MCU, FTDI-кабель на 3,3 В, несколько светодиодов и резисторов). LPC1114 построен на базе Cortex-M0, так что это будет самый урезанный вариант платформы.


В качестве альтернативного варианта мы будем работать с платформой mbed, а конкретно, с моделью на базе LPC1768 (а значит, внутри там Cortex-M3, несколько более навороченный). Вариант уже не настолько бюджетный, но процесс заливки бинарников на чип и отладки упрощен максимально. Да и можно поиграться с самой платформой mbed (вкратце: это онлайн-IDE и библиотека, с помощью которой можно программить на уровне ардуины).

Приступим

Интересной особенностью современных ARM-ов является то, что их вполне реально программировать целиком на С, без применения ассемблерных вставок (хотя ассемблер не так уж и сложен, у Cortex-M0 всего 56 команд). Хотя некоторые команды в принципе не доступны из С, эту проблему решает CMSIS – Cortex Microcontroller Software Interface Standard. Это драйвер для процессора, который решает все основные задачи управления им.

Как же загружается процессор? Типична ситуация, когда он просто начинает выполнять команды с адреса 0x00000000. В нашем случае процессор несколько более умный, и рассчитывает на специально определенный формат данных в начале памяти, а именно – таблицу векторов прерываний:


Старт выполнения программы происходит следующим образом: процессор читает значение по адресу 0x00000000 и записывает его в SP (SP – регистр, который указывает на вершину стека), после чего читает значение по адресу 0x00000004 и записывает его в PC (PC – регистр, который указывает на текущую инструкцию + 4 байта). Таким образом начинает выполняться какой-то код пользователя, при этом у нас уже есть стек, указывающий куда-то в память (т.е., все условия для выполнения программы на С).

В качестве тестового упражнения мы будем мигать светодиодом. На mbed у нас их целых четыре, в схему с LPC1114 (далее — «доска») мы устанавливаем светодиод вручную.

Перед тем как непосредственно писать код, нам надо выяснить еще одну вещь, а именно – что где должно располагаться в памяти. Поскольку мы не работаем с какой-то «стандартной» ОС, то компилятор (вернее, компоновщик) не может узнать, где у него должен быть стек, где сам код, а где — куча. К счастью для нас, у семейства ядер Cortex стандартизированная карта памяти, что позволяет относительно просто портировать приложения между разными процессорами этой архитектуры. Работа с периферией, конечно, остается процессорозависимой.

Карта памяти для Cortex-M0 выглядит вот так:

(изображение из Cortex™-M0 Devices Generic User Guide)

У Cortex-M3 она, по сути, такая же, но несколько более детальна. Проблема тут в том, что у NXP есть свой, отдельный взгляд на этот вопрос, так что проверяем карту памяти в документации на процессор:

(изображение из LPC111x/LPC11Cxx User manual)

На самом деле, SRAM у нас начинается с 0x10000000! Вот так, одни стандарты, другие стандарты, а все равно надо тома документации листать.

Вооружившись этими знаниями, идем писать код. Для начала – таблица прерываний:

.cpu cortex-m0      /* ограничиваем ассемблер списком существующих инструкций */
.thumb

.word   _stack_base /* начало стека в самом конце памяти, стек растет вниз */
.word   main        /* Reset: с прерывания сразу прыгаем в код на С */
.word   hang        /* NMI и все остальные прерывания нас не сильно волнуют */
.word   hang        /* HardFault */
.word   hang        /* MemManage */
.word   hang        /* BusFault */
.word   hang        /* UsageFault */
.word   _boot_checksum /* Подпись загрузчика */
.word   hang        /* RESERVED */
.word   hang        /* RESERVED*/
.word   hang        /* RESERVED */
.word   hang        /* SVCall */
.word   hang        /* Debug Monitor */
.word   hang        /* RESERVED */
.word   hang        /* PendSV */
.word   hang        /* SysTick */
.word   hang        /* Внешнее прерывание 0 */
                    /* ... */

/* дальше идут остальные 32 прерывания у LPC1114 и 35 у LPC1768, но
   их нет смысла описывать, потому как мы их все равно не используем */

.thumb_func
hang:   b .         /* функция заглушка для прерываний: вечный цикл */

.global hang

Сохраним эту таблицу в boot.s. Тут, фактически, только одна ассемблерная вставка – функция hang, которая устраивает процессору бесконечный цикл. Все прерывания, кроме reset, указывают на нее, так что в случае непредвиденной ситуации процессор просто зависнет, а не пойдет выполнять непонятный участок кода.

Сама таблица должна бы быть длиннее, но на самом деле мы могли бы закончить ее еще после вектора Reset, остальные у нас не сработали бы в этом примере. Но, на всякий случай, мы заполнили таблицу почти целиком (кроме пользовательских прерываний).

Теперь напишем реализацию функции main:

#if defined(__ARM_ARCH_6M__)

/* Cortex-M0 это ARMv6-M, код для LPC1114 */

#define GPIO_DIR_REG  0x50018000  /* GPIO1DIR  задает направление для блока GPIO 1 */
#define GPIO_REG_VAL  0x50013FFC  /* GPIO1DATA задает значение для блока GPIO 1 */
#define GPIO_PIN_NO   (1<<8)      /* 8-й бит отвечает за 8-й пин */

#elif defined(__ARM_ARCH_7M__)

/* Иначе просто считаем что это LPC1768 */

#define GPIO_DIR_REG  0x2009C020  /* FIO1DIR задает направление для блока GPIO 1 */
#define GPIO_REG_VAL  0x2009C034  /* FIO1PIN задает значение для блока GPIO 1 */
#define GPIO_PIN_NO   (1<<18)     /* 18-й бит отвечает за 18-й пин */

#else

#error Unknown architecture

#endif

void wait()
{
  volatile int i=0x20000;
  while(i>0) {
    --i;
  }
}

void main()
{
  *((volatile unsigned int *)GPIO_DIR_REG) = GPIO_PIN_NO;

  while(1) {
    *((volatile unsigned int *)GPIO_REG_VAL) = GPIO_PIN_NO;
    wait();
    *((volatile unsigned int *)GPIO_REG_VAL) = 0;
    wait();
  }

  /* main() *никогда* не должен вернуться! */
}

У mbed первый светодиод подключен к порту GPIO 1.18, на доске мы подключили светодиод к GPIO 1.8. Одни и те же пины могут выполнять разные функции, эти по умолчанию работают именно как GPIO (General Purpose I/O – линии ввода/вывода общего назначения).

Код относительно прямолинеен, если держать под рукой LPC-шный User manual (один и второй). Для начала мы указываем режим работы GPIO через регистр GPIO_DIR_REG (у наших процессоров они в разных местах, да и вообще LPC1768 может работать с GPIO более эффективно), где 1 – вывод, 0 – ввод. Потом мы запускаем бесконечный цикл, в котором пишем в порт попеременно значения 0 и 1 (0 В и 3,3 В соответственно).

Функция для «паузы» у нас работает наугад, просто прокручивая относительно долгий цикл (volatile int не дает компилятору выоптимизировать этот цикл целиком).

Наконец, все это нужно правильно скомпоновать:

_stack_base = 0x10002000;
_boot_checksum = 0 - (_stack_base + main + 1 + (hang + 1) * 5);

MEMORY
{
   rom(RX)   : ORIGIN = 0x00000000, LENGTH = 0x8000
   ram(WAIL) : ORIGIN = 0x10000000, LENGTH = 0x2000
}

SECTIONS
{
   .text : { *(.text*) } > rom
   .bss  : { *(.bss*) } > ram
}

Сценарий компоновщика объясняет ему, где у нас флеш, где оперативная память, какие у них размеры (тут используются размеры для LPC1114, так как у LPC1768 всего больше, сдвиги, к счастью, идентичны). После определения карты памяти мы указываем, какие сегменты куда копировать, .text (код программы) попадает в флеш, .bss (статические переменные, которых у нас пока нет) – в память. Помимо этого мы задаем два символа, которые использовали в boot.s: _stack_base – указывает на вершину стека и _boot_checksum (спасибо Zuy за уточнение!) – записывает чексумму загрузчика. Чексумма рассчитывается по формуле: дополнительный код (2’s compliment) от суммы полей выше (т.е. адреса стека, и всех прерываний до непосредственно чексуммы). Хотя утилиты для прошивки (см. далее) сами исправили бы чексумму на правильную, если бы мы прошивали бы код из самого приложения, то загрузиться снова мы бы уже не смогли.

Теперь у нас есть три файла: boot.s, main.c, mem.ld, пора это все скомпилировать и, наконец, запустить. В качестве тулчейна мы будем использовать GCC, позже, возможно, я покажу как делать то же с LLVM. Пользователям OS X я советую взять тулчейн у Linaro – в самом конце списка: Bare-Metal GCC ARM Embedded. Пользователям других ОС я советую взять тулчейн там же :-) (разве что гентушникам будет проще сэмержить crossdev и скомпилить GCC).

arm-none-eabi-as boot.s -o boot.o
arm-none-eabi-gcc -O2 -nostdlib -nostartfiles -ffreestanding -Wall -mthumb -mcpu=cortex-m0 -c main.c -o main-c0.o
arm-none-eabi-gcc -O2 -nostdlib -nostartfiles -ffreestanding -Wall -mthumb -mcpu=cortex-m3 -c main.c -o main-c3.o
arm-none-eabi-ld -o blink-c0.elf -T mem.ld boot.o main-c0.o
arm-none-eabi-ld -o blink-c3.elf -T mem.ld boot.o main-c3.o
arm-none-eabi-objdump -D blink-c0.elf > blink-c0.lst
arm-none-eabi-objdump -D blink-c3.elf > blink-c3.lst
arm-none-eabi-objcopy blink-c0.elf blink-c0.bin -O binary
arm-none-eabi-objcopy blink-c3.elf blink-c3.bin -O binary

Интересный момент тут — это отключение использования всех стандартных библиотек у GCC. Действительно, весь код, который попадет в итоговый бинарник – это код, который написали мы сами.

Вопрос: как компоновщик знает, куда надо засунуть таблицу прерываний? А он и не знает, там не написано :-). Он просто линкует подряд, начиная с нулевого адреса, так что порядок файлов (boot.o, потом main-c0.o) очень важен! Попробуйте слинковать наоборот или слинковать boot.o два раза и сравните вывод в lst-файле.

Хорошая идея – посмотреть на итоговый листинг (файл lst) или закинуть бинарник в дизассемблер. Даже если вы не говорите на ARM UAL, то чисто визуально можно проверить, что хотя бы таблица прерываний находится на своем месте:


Еще можно обратить внимание на забавный момент – GCC при компиляции под Cortex-M3 генерирует функцию wait() больше, чем в варианте под Cortex-M0. Правда, если включить оптимизацию то она вправит ему мозги.

Мигаем!

Все что нам осталось – залить бинарники на наши тестовые платформы. С mbed тут все максимально просто, просто скопируйте blink-c3.bin на виртуальную флешку и нажмите reset (на mbed). С доской все немного сложнее. Во-первых, для того, чтобы попасть в загрузчик, нам нужен резистор между GND и GPIO 0.1. Во-вторых, необходима программа для непосредственно прошивки. Можно использовать Flash Magic (Win, OS X), можно использовать консольную утилиту – lpc21isp:

lpc21isp.out -verify -bin /path/to/blink-c0.bin /dev/ftdi/tty/device 115200 12000

Процесс прошивки следующий:

  • ставим резистор между j5 и j7 (10 кОм подойдет);
  • нажимаем reset;
  • запускаем lpc21isp;
  • снимаем резистор;
  • нажимаем reset еще раз – запускается приложение.

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

P.S. Отдельное спасибо хабраюзеру pfactum за то, что тратит время на исправление моих ошибок в тексте :-).

P.P.S. Просьба тем, у кого есть тестовая платформа на базе ARM – пишите в комментариях – какая. Я могу пересмотреть аппаратную базу для дальнейших статей.

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

Интересны ли реальные аппаратные демо?


34.96%
Прочитал, есть/куплю железо, буду запускать демки
438


18.44%
Прочитал, есть аналогичное железо (ARM-based evaluation board)
231


4.23%
Прочитал, демки не интересны
53


29.13%
Пролистал, если будет продолжение – тоже пролистаю
365


13.25%
Не читал, но голосовать люблю
166

Проголосовали 1253 пользователя.

Воздержались 238 пользователей.

Семейство ARM Cortex — новое поколение процессоров, которые выполнены по стандартной архитектуре и отвечают различным технологическим требованиям. В отличие от других ЦПУ ARM, семейство Cortex является завершенным процессорным ядром, которое объединяет стандартное ЦПУ и системную архитектуру. Семейство Cortex доступно в трех основных профилях: профиль A для 

высокопроизводительных применений, профиль R для реально-временных применений и профиль M для чувствительных к стоимости и микроконтроллерных применений. Микроконтроллеры STM32 выполнены на основе профиля Cortex-M3, которое специально разработано для применений, где необходимы развитые системные ресурсы и, при этом, малое энергопотребление. 

Читайте, знакомьтесь!

1. Артур Гриффитс «GCC. Настольная книга пользователей, программистов и системных администраторов»

Название: GCC. Настольная книга пользователей, программистов и системных администраторов

Автор: Артур Гриффитс

Издательство: DiaSoft Москва Санкт-Петербург Киев 2004г

Язык: Русский. Перевод с английского ООО «ТИД «ДС» 2004г

Формат: DjVu

Размер: 6Mb

Описание:

В книге описывается коллекция компиляторов GCC ( GNU Compilers Collection ). Очень доступное и подробное описание GCC и входящих в состав коллекции компиляторов. Особое внимание уделено компилятору языка С.

Эта книга будет также интересна программистам микроконтроллеров, использующих инструментарий GNU tool chain. Отдельная глава посвящена программированию встраиваемых систем. Также имеется описание опций для платформ ARM и AVR.

Описан синтаксис GNU Assembler. Есть информация по синтаксису скриптов компоновщика. Хотелось бы, конечно, более детального освещения этой темы.

В целом книга будет очень даже полезна как учебник и справочник по опциям GCC.

2. Джозеф Ию «Полное руководство по ARM Cortex-M3»

Название: The Definitive Guide to the ARM Cortex-M3

Автор: Joseph Yiu

Издательство : ELSEVIER 2007

Язык: English

Формат: pdf

Размер: 5,7 Мб

Описание:

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

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

В книге много таблиц и примеров исходного кода. Рассматривается программирование на языках С и Assembler. Программирование для Cortex -M3 описано буквально с нуля.

Есть информация по различным инструментальным средствам для программирования Cortex-M3, в том числе и GNU Tool chain.

Отдельная глава посвящена переносу на новую архитектуру приложений, написанных для процессоров ARM7.

Также книгу можно использовать как справочник по ассемблерным инструкциям процессорного ядра Cortex-M3.

3. Андрей Робачевский «Операционная система Unix»

Название: Операционная система Unix

Автор: Андрей Робачевский

Издательство: БХВ-Петербург 2002

Язык: Русский

Формат: pdf

Размер: 8,3 Мб

Описание:

Если есть непреодолимое желание разобраться в операционных систем семейства Unix( Linux, FreeBSD и т.д ), то эта книга будет просто незаменимой. В книге рассматривается архитектура ядра Unix, есть множество иллюстраций и примеров исходного кода на языке программирования С.

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

Книгу также можно использовать в качестве справочника. Эта книжка может по праву претендовать на звание одного из лучших технических руководств на русском языке по архитектуре ядра Unix.

4. Герберт Шилдт «Полный справочник по С»

Название: Полный справочник по С, четвертое издание

Автор: Герберт Шилдт

Издательство: Издательский дом «Вильямс » 2005

Язык: Русский, перевод с английского

Формат: html, упакован в архив 7-zip

Размер: 0,5 Мб

Описание:

«Полный справочник по С» будет полезен для любого программиста, пишущего на языке программирования С. В справочнике рассматриваются стандарты ANSI/ISO языка C89 и C99. Описаны основные функции из стандартной библиотеки функций языка С. Помимо справочной информации по синтаксису языка С, в книге описаны основные алгоритмы , в конце книги приведен исходный код командного интерпретатора языка Little C. Как справочник по стандартной библиотеке языка С книга будет более полезна программистам, работающим в операционных системах семейства Windows. В операционных системах класса Unix исчерпывающую информацию о функциях стандартной библиотеки С можно получить из встроенной справочной системы с помощью команды «man <название функции>».

5. К.Бойт «Цифровая электроника»

Название: Цифровая электроника

Автор: К.Бойт

Издательство: Техносфера Москва 2007

Язык: Русский, перевод с немецкого М.М.Ташлицкого

Формат: DjVu

Размер: 22,5 Мб

Описание:

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

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

6. В.Н.Баранов «Применение микроконтроллеров AVR: Схемы, алгоритмы, программы»

Название: Применение микроконтроллеров AVR : Схемы, алгоритмы, программы

Автор: В.Н.Баранов

Издательство: Издательский дом «Додэка XXI » Москва 2004г

Язык: Русский

Формат: DjVu

Размер: 3Мб

Описание:

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

7. А.В.Кравченко «10 практических устройств на AVR микроконтроллерах»

Название: 10 практических устройств на AVR микроконтроллерах

Автор: А.В.Кравченко

Издательство: Москва, издательский дом «Додэка XXI»

Киев , «МК — Пресс»

2008г

Формат: DjVu

Размер: 7,5Мб

Описание:

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

8. Ю.А.Шпак «Программирование на языке C для AVR и PIC микроконтроллеров»

Название: Программирование на языке С для AVR и PIC микроконтроллеров

Автор: Ю.А.Шпак

Издательство: «МК-Пресс» 2006г

Формат: DjVu

Размер: 9,5Мб

Описание:

Книга будет полезна разработчикам, программирующим микроконтроллеры на языке С.

Для программирования AVR в книге используется бесплатный инструментарий WinAVR. Программирование микроконтроллеров PIC описывается в книге с помощью компилятора CCS-PIC и среды разработки MPLAB от Microchip.

Книгу можно использовать как справочник по программированию микроконтроллеров AVR и PIC на языке C.

9. Тревор Мартин «Микроконтроллеры ARM7. Семейство LPC2000 компании Philips. Вводный курс»

Название: Микроконтроллеры ARM7. Семейство LPC2000 компании Philips. Вводный курс

Автор: Тревор Мартин

Издательство: «Додэка- XXI»

Москва 2006

Язык: русский, перевод с английского

Формат: DjVu

Размер : 12,5 Мб

Описание:

Книга Тревора Мартина «Микроконтроллеры ARM7. Семейство LPC2000 компании Philips. Вводный курс» для многих послужила путеводителем в мир программирования микроконтроллеров ARM. В книге доступно описывается архитектура ядра ARM7, система команд, периферия микроконтроллеров семейства LPC2000,инструментальные средства, есть много примеров кода, в общем самый настоящий «вводный курс » в микроконтроллеры ARM. Знания, приобретенные из книги, пригодятся не только для программирования устройств на основе ядра ARM7TDMI, но и при изучении других ARM-архитектур. Рекомендуется к прочтению специалистам , желающим перейти от 8-разрядных микроконтроллеров к 32-битным ARM.

10. «Ознакомительное руководство по ARM- микроконтроллерам Cortex-M3»

Название: The Insider’s Guide To The STM32 ARM Based Microcontroller

Автор: HITEX

Издательство: Распространяется в электронном виде

Язык: Русский. Перевод с английского языка на сайте www.gaw.ru

Формат: pdf

Размер: 2,3 Мб

Описание:

Краткое руководство по микроконтроллерам семейства STM32 от компании Hitex поможет быстро приступить к работе с семейством STM32 фирмы ST Microelectronics. Однако, как гласит название, руководство является ознакомительным и не заменит техническое описание архитектуры ядра ARM в целом и Cortex-M3 в частности.

Viewed 9971 times by 5600 viewers

Понравилась статья? Поделить с друзьями:
  • Руководство по программированию altivar 630
  • Whirlpool кондиционер инструкция на русском языке
  • Panasonic kx teb308 инструкция по программированию
  • Гпо белэнерго официальный сайт руководство
  • 191н инструкция по бюджетному учету с изменениями 2022 год