Научная статья на тему 'ПРОГРАММИРОВАНИЯ МИКРОКОНТРОЛЛЕРОВ'

ПРОГРАММИРОВАНИЯ МИКРОКОНТРОЛЛЕРОВ Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
100
18
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
ПРОЦЕССОР / ПРОГРАММИРОВАНИЕ / МИКРОКОНТРОЛЛЕР / АРХИТЕКТУРА / ИНФОРМАЦИОННЫЕ СИСТЕМЫ / PROCESSOR / PROGRAMMING / MICROCONTROLLER / ARCHITECTURE / INFORMATION SYSTEMS

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Арапёнков Д.В., Литвиненко В.А.

В данной статье мы познакомимся с ключевым компонентом, для большого количества успешных 32-битных встраиваемых систем, а именно процессоры ARM и в частности рассмотрим процессоры Cortex. Также в статье рассмотрены и проанализированы возможности 32-разрядных микроконтроллеров и их использований в построении информационных систем, при работе с отладочной платой STM32.

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

PROGRAMMING OF MICROCONTROLLERS

In this article we will get acquainted with the key component for a large number of successful 32-bit embedded systems, namely arm processors and in particular consider cortex processors. The article also discusses and analyzes the possibilities of 32-bit microcontrollers and their use in the construction of information systems, when working with the stm32 debug Board.

Текст научной работы на тему «ПРОГРАММИРОВАНИЯ МИКРОКОНТРОЛЛЕРОВ»

МАТЕМАТИКА, ИНФОРМАТИКА И ИНЖЕНЕРИЯ

УДК 004

Арапёнков Д.В. студент 3 курса Литвиненко В.А студент 3 курса

факультет «Информационных систем и технологий» Поволжский Государственный Университет Телекоммуникаций и Информатики

Россия, г. Самара

ФГБОУ ВО «Поволжский государственный университет

телекоммуникаций и информатики»

Россия, г. Самара ПРОГРАММИРОВАНИЯ МИКРОКОНТРОЛЛЕРОВ

Аннотация. В данной статье мы познакомимся с ключевым компонентом, для большого количества успешных 32-битных встраиваемых систем, а именно процессоры ARM и в частности рассмотрим процессоры Cortex. Также в статье рассмотрены и проанализированы возможности 32-разрядных микроконтроллеров и их использований в построении информационных систем, при работе с отладочной платой STM32.

Ключевые слова: процессор, программирование, микроконтроллер, архитектура, информационные системы.

Arapenkov D. V.

Litvinenko V.A. the students

3-nd year, Faculty of Information Systems and Technologies

Volga State University Telecommunications and Informatics Information systems and technologies

Federal State-Funded Educational Russia, Samara «Povolzhsky State University of Telecommunications and

Informatics», Russia, Samara PROGRAMMING OF MICROCONTROLLERS

Keywords: processor, programming, microcontroller, architecture, information systems.

Annotation. In this article we will get acquainted with the key component for a large number of successful 32-bit embedded systems, namely arm processors and in particular consider cortex processors. The article also discusses and analyzes the possibilities of 32-bit microcontrollers and their use in the construction of information systems, when working with the stm32 debug Board.

Keywords: processor, programming, microcontroller, architecture, information systems.

Введение

Это миниатюрные компьютеры, все составляющие которых (процессор, ОЗУ, ПЗУ) располагаются на одном кристалле. От микропроцессоров их отличает наличие таймеров, контроллеров, компараторов и других периферийных устройств. В настоящее время микроконтроллеры используются при производстве:

• датчиков для автомобилей;

• игрушек;

• индикаторов напряжения, зарядных устройств;

• пультов управления;

• миниатюрных электронных приборов.

Управление осуществляется при помощи специальных программ.

Выбор микроконтроллера

Многие могут сказать, что начинать изучение микроконтроллеров лучше с AVR, PIC, 8051 или чего-то еще. Вопрос многогранный и спорный. Я знаю достаточно примеров, когда люди изучив Cortex-M, программировали AVR, ARM7 и т.д. Сам же я начинал с Cortex-M3. Если перед вами стоит определенная задача, в интернете достаточно много информации со сравнением различных типов микроконтроллеров и решаемых с их помощью задач.

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

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

Что необходимо для изучения?

К сожалению, для начала программирования МК не достаточно одного лишь ПК. Придется где-то раздобыть демонстрационную плату и программатор. Сам я использую демонстрационную плату STM3220G-EVAL и программатор J-Link PRO. Но для начала, будет вполне достаточно

STM32F4DISCOVERY, которую можно купить без особых проблем за небольшую сумму.

Все примеры будут именно для отладочной платы STM32F4DISCOVERY. На данном этапе нам будет совершенно не важно, что этой плате стоит МК на базе ядра Cortex-M4. В ближайшее время мы не будем использовать его особенности и преимущества над Cortex-M3. А как там будет дальше — посмотрим.

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

Среда разработки

Как уже неоднократно упоминалось, для ARM микроконтроллеров существует достаточное количество сред разработки, как платных так и не очень. И снова хочется опустить полемику по этому поводу. Я использую IAR Embedded Workbench for ARM 6.60. Все примеры будут именно в этой среде. Если вам по душе (или в вашей организации используется) что -то другое (Keil, Eclipse, CCS, CooCoc и т.д.) то это вам тоже не очень помешает. На особенности, связанные именно со средой разработки, я буду обращать отдельное внимание.

Создание проекта

Для начала создадим пустой проект. IAR позволяет создать проекты на ASM, C и C++. Мы будем использовать чистый C. Перед нами появится пустой проект с main файлом.

Workspace - IAR Embedded Workbench IDE

Fríe Edit View Project Simulator Tools Window Help

i

Workspace х IAR Information Center for ARM main

Debug * E int main() { return G;

Files Щ

В Q) Lessonl - ... 1—Ш [?] main.с Чэ □ Output

Рис. 1. Создание пустого проекта в 1ЛЯ Теперь необходимо настроить проект для начала работы с «нашим» МК и отладчиком. На плате STM32F4DISCOVERY установлен MK

STM32F407VG . Его необходимо выбрать в свойствах проекта (General Options->Target->Device):

Рис. 2. Выбор настроек проекта.

При выборе целевого программируемого процессора происходит загрузка его описания, что дает широкие возможности для отладки (об этом будет идти речь ниже). Кроме того, автоматически присоединяется конфигурационный файл с описанием доступного адресного пространства для линкера. После этого необходимо настроить отладчик. Отладка программы происходит непосредственно «в железе». Производится это с помощью JTAG отладчика. На плату STM32F4DISCOVERY интегрирован отладчик ST-LINK/V2. Для работы с отладчиком необходимо выбрать его драйвер в меню Debugger->Setup->Driver. Так же необходимо указать, что отладка должна производиться непосредственно в железе. Для этого необходимо поставить флаг Debugger->Download->Use flash loader(s)

Теперь проект готов для работы (программирования, заливки и отладки).

«ТЗ» для первого проекта

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

Не будем отходить от классики. Первым проектом будет мигающий светодиод. Благо на плате их предостаточно. Что же это означает с точки зрения программирования? Первым делом необходимо изучить принципиальную схему демонстрационной платы и понять как «заводится» светодиод.

User manual доступен на сайте производителя. В данном описании даже есть отдельный раздел про светодиоды на плате -4.4 LEDs. Для

примера, будем использовать User LD3. Найдем его на схеме:

Рис. 3. Схема модулей микроконтроллера

Простейший анализ схемы говорит о том, что для того, что бы «зажечь» светодиод необходимо на пин МК подать «1» (которая для данного МК соответствует 3.3В). Выключение производится подачей на этот пин «0». На схеме этот пин обозначается PD13 (это, наверное, самая важная информация из этого документа).

Прежде чем приступить к реализации нашего ТЗ, необходимо понять как производится управление МК.

Начнем с того, что любой МК включает ядро, память и периферийные блоки. Думаю, что с памятью пока все понятно. Упомяну лишь, в STM32 есть флеш-память в которой хранится программа МК (в общем случае это не верное утверждение, программа может храниться во внешней энергонезависимой памяти, но пока это опустим) и другие данные, в том числе и пользовательские. Так же есть SRAM — оперативная память.

Ядро — часть микроконтроллера, осуществляющая выполнение одного потока команд. В нашем МК тип ядра — Cortex-M4. Ядро МК можно сравнить с процессором в ПК. Оно умеет только выполнять команды и передавать данные другим блокам (в этом сравнении не учитываются процессоры с интегрированными графическими ускорителями).

При этом производитель МК не разрабатывает ядро. Ядро покупается у компании ARM Limited. Главное отличие между различными МК — в периферии.

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

В отличии от ядра МК периферийные блоки не выполняют инструкции. Они лишь выполняют команды ядра. При этом участие ядра при выполнении команды не требуется.

Запись данных по адресу в памяти

Предположим, что читая описание периферийного блока, мы поняли, что для его корректной работы необходимо записать в него число 0x3B. Адрес спец регистра 0x60004012. Регистр 32-битный.

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

Значение 0x60004012 есть не что иное, как значение указателя на ячейку памяти. Нужно именно это и указать в нашей программе, то есть сделать преобразование типов согласно синтаксису языка C: (unsigned long*)(0x60004012)

Таким образом, у нас есть указатель на элемент. Теперь нужно в этот элемент записать необходимое значение. Делается это разыменовыванием указателя. Таким образом получаем правильную команду: *(unsigned long*)(0x60004012) = 0x3B; Установка произвольных бит в 1

Предположим, что необходимо установить «1» в 7 и 1 биты по адресу 0x60004012, при этом не изменив значение всех остальных бит в регистре. Для этого необходимо использовать бинарную операцию |. Сразу приведу правильный ответ:

*(unsigned long*)(0x60004012) |= 0x82;

Обратите внимание на 2 факта. Биты считаются с нулевого, а не с первого. Данная операция на самом деле занимает не менее 3 тактов — считывание значения, модификация, запись. Иногда это не допустимо, поскольку между считыванием и записью значение одного из бит, которые нам запрещено изменять, могло быть изменено периферийным блоком. Не забывайте про эту особенность, иначе могут полезть баги, которые крайне сложно отловить.

Установка произвольных бит в 0

Предположим, что необходимо установить «0» в 7 и 1 биты по адресу 0x60004012, при этом не изменив значение всех остальных бит в регистре. Для этого необходимо использовать бинарную операцию &. Сразу приведу правильный ответ:

*(unsigned long*)(0x60004012) &= 0xFFFFFF7D;

Или его более простою запись (не переживайте за лишнюю операцию, компилятор все заранее посчитает даже при минимальной оптимизации): *(unsigned long*)(0x60004012) &= (~0x82); Приступаем к работе

Работа над программой для МК всегда начинается с чтения документации. Для нашего МК Reference manual доступен на сайте производителя. Страниц много, но все читать пока не нужно. В первую очередь необходимо определиться с какими блоками предстоит работать. Для это достаточно изучить разделы Introduction и Main features.

Непосредственное управление состоянием пинов МК осуществляется с помощью блока GPIO. Как указано в документации в МК STM32 может

быть до 11 независимых блоков GPIO. Различные периферийные блоки GPIO принято называть портами. Порты обозначаются буквам от A до K. Каждый порт может содержать до 16 пинов. Как мы отметили ранее, светодиод подключается к пину PD13. Это означает, что управление этим пином осуществляется периферийным блоком GPIO порт D. Номер пина 13. Управление тактированием периферийных блоков Для снижения электропотребления МК практически все периферийные блоки после включения МК отключены. Включение/выключение блока производится подачей/прекращением подачи тактового сигнала на его вход. Для корректной работы, необходимо сконфигурировать контроллер тактового сигнала МК, чтобы необходимому периферийному блоку поступал тактовый сигнал.

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

За включение тактирования периферийных блоков отвечают регистры RCC XXX peripheral clock enable register .На месте XXX могут стоять шины AHB1, AHB2, AHB3, APB1 и APB2. После внимательного изучения описания соответствующих регистров, можно сделать вывод о том, тактирование периферийного блока GPIOD включается установкой «1» в третий бит регистра RCC AHB1 peripheral clock enable register (RCCAHB1ENR):

Зажигаем светодиод

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

void main() {

//Enable port D clocking *(unsigned long*)(0x40023830) |= 0x8; //little delay for GPIOD get ready volatile unsigned long i=0;

i++; i++; i++; i=0;

//Set PD13 as General purpose output

*(unsigned long*)(0x40020C00) = (*(unsigned long*)(0x40020C00)& (~0x0C000000)) | (0x04000000); //Turn LED ON!

*(unsigned long*)(0x40020C14) |= 0x2000;

while(1); }

Можно компилировать (Project->Compile) и заливать (Project->Download->Download active application). Или запустить отладку (Project-

>Dpwnload and Debug) и начать выполнение (F5). Светодиод загорелся! Мигаем светодиодом

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

void main() {

//Enable port D clocking *(unsigned long*)(0x40023830) |= 0x8; //little delay for GPIOD get ready volatile unsigned long i=0;

i++; i++; i++; i=0;

//Set PD13 as General purpose output

*(unsigned long*)(0x40020C00) = (*(unsigned long*)(0x40020C00)& (~0x0C000000)) | (0x04000000);

while(1) {

//Turn LED ON

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

*(unsigned long*)(0x40020C14) |= 0x2000; //Delay

for( i=0; i<1000000 ;++i ); //Turn LED OFF

*(unsigned long*)(0x40020C14) &= ~0x2000; //Delay

for( i=0; i<1000000 ;++i ); }

}

Значение 1000000 в задержке подобрано экспериментально так, чтобы период мигания светодиода был различим глазом, но и не был слишком велик.

Немного об отладке

IAR позволяет осуществлять отладку приложения непосредственно в железе. Все выглядит практически так же, как и отладка приложения для ПК. Есть режим пошагового выполнения, входа в функцию, просмотр значения переменных (В режиме отладки View->Watch->Watch1/4).

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

Я настоятельно рекомендую ознакомиться с возможностями дебаггера во время изучения программирования МК. Несколько слов в заключение

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

Использованные источники:

1. Джозеф Ю.; Ядро CORTEX-M3 компании ARM; Полное руководство; Додэка-XXI; 2012 г. 553 с.

2. Редькин П.П.; 32-битные микроконтроллеры NXP с ядром CORTEX-M3 семейства LPC17XX; Полное руководство; ДМК Пресс; 2015 г. 766 с.

3. НаЬг(Хабр) [Электронный ресурс] - Электронные данные. - Режим доступа http:https://habr.com

4. Информационный портал. [Электронный ресурс] - Электронные данные. - Режим доступа: http://www.chipnews.ru

i Надоели баннеры? Вы всегда можете отключить рекламу.