Введение в STM 32 F1

Микроконтроллеры STM32 F1 xx основаны на ядре ARM Cortex-M3. Cortex-M3 также является основой для микроконтроллеров ряда других производителей, включая TI, NXP, Toshiba и Atmel. Совместное использование общего ядра означает, что инструменты разработки программного обеспечения, включая компилятор и отладчик, являются общими для широкого спектра микроконтроллеров. Cortex-M3 отличается от процессоров ARM предыдущих поколений тем, что определяет ряд ключевых периферийных устройств как часть базовой архитектуры, включая контроллер прерываний, системный таймер и оборудование для отладки и трассировки (включая внешние интерфейсы). Этот дополнительный уровень интеграции означает, что системное программное обеспечение, такое как операционные системы реального времени, и инструменты разработки оборудования, такие как интерфейсы отладчика, могут быть общими для всего семейства процессоров. Различные семейства микроконтроллеров на базе Cortex-M3 значительно различаются по аппаратным периферийным устройствам и памяти — периферийные устройства семейства STM32 полностью отличаются по архитектуре от периферийных устройств семейства NXP, даже если они имеют схожую функциональность. В этой главе мы познакомим вас с ключевыми аспектами ядра Cortex-M3 и микроконтроллеров STM32 F1xx. Блок-схема процессора STM32F100, используемого на плате обнаружения линий ценности, показана на рис. 2.1. Процессор Cortex-M3 показан в верхнем левом углу. Компоненты линейки значений имеют максимальную частоту 24 МГц — другие процессоры STM32 могут поддерживать тактовую частоту 72 МГц. Основная часть рисунка иллюстрирует периферийные устройства и их взаимосвязь. Процессор обнаружения имеет 8 КБ SRAM и 128 КБ флэш-памяти. Существует две периферийные коммуникационные шины — APB2 и APB1, поддерживающие широкий спектр периферийных устройств.

 

Архитектура stm32 f100 ре

Архитектура ядра Cortex-M3 cсостоит из 3 с небольшим набором ключевых периферийных устройств. Интерфейс между Cortex- конкретное оборудование проходит через три шины памяти — ICode, DCode и System. – которые определены для доступа к различным областям памяти.

 

Упрощенная архитектура ядра Cortex-M3

 

 

STM32, показанный на рис. 2.3, соединяет три шины, определенные Cortex-M3,

через матрицу шин на уровне микроконтроллера. В STM32 шина ICode соединяет

интерфейс инструкций CM3 с флэш-памятью, шина DCode подключается к флэш-

памяти для выборки данных, а системная шина обеспечивает доступ для чтения/

записи к SRAM и периферийным устройствам STM32. Периферийная подсистема

поддерживается шиной AHB, которая далее делится на две области подшины AHB1 и

AHB2. STM32 предоставляет сложный контроллер прямого доступа к памяти (DMA),

который поддерживает прямую передачу данных между периферийными

устройствами и памятью.

Архитектура шины средней плотности value line stm32

2.1 Кортекс-М3

Процессор CM3 реализует набор инструкций Thumb-2, который предоставляет

большой набор 16-битных инструкций, позволяющих выполнять 2 инструкции на выборку

из памяти, а также небольшой набор 32-битных инструкций для поддержки более сложных

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

отношения к этой книге, так как мы будем выполнять все наши программы на C. Однако

есть несколько ключевых идей, которые мы обсудим ниже.

Как и все процессоры RISC, Cortex-M3 представляет собой архитектуру загрузки/сохранения с

тремя основными типами.

2.1. КОРТЭКС-М3

внутренний счетчик;

int counterInc (пусто) {

вернуть счетчик++;

}

Результирующий (аннотированный) язык ассемблера с соответствующим машинным кодом выглядит

следующим образом:

Две 32-битные инструкции (movw, movt) используются для загрузки нижней/верхней половин адреса прилавок (известны во время компоновки и, следовательно, 0 в листинге кода). Затем три 16-битных инструкции загружают (ldr) значение счетчика, увеличивают (добавляют) значение и записывают обратно (str) обновленное значение. Наконец, процедура возвращает исходный счетчик. Не ожидается, что читатель этой книги поймет набор инструкций Cortex-M3 или даже этот пример в мельчайших деталях. Ключевым моментом является то, что Cortex-M3 использует смесь 32-битных и 16-битных инструкций (в основном последние) и что ядро взаимодействует с памятью исключительно посредством инструкций загрузки и сохранения. Хотя существуют инструкции, которые загружают/сохраняют группы регистров (в нескольких циклах), нет инструкций, которые непосредственно работают с ячейками памяти. Ядро Cortex-M3 имеет 16 видимых пользователю регистров (показаны на рис. 2.4) — вся обработка происходит в этих регистрах. Три из этих регистров имеют специальные функции, включая программный счетчик (PC), который содержит адрес следующей инструкции для выполнения, регистр связи (LR), который содержит адрес, с которого была вызвана текущая процедура, и  стек . указатель (SP), который содержит адрес текущей вершины стека (как мы обсудим в главе 11, CM3 поддерживает несколько режимов выполнения, каждый из которых имеет собственный частный указатель стека). Отдельно проиллюстрирован регистр состояния процессора (PSR), к которому неявно обращаются многие инструкции. Cortex-M3, как и другие процессоры ARM, был разработан для программирования (почти) полностью на языке более высокого уровня, таком как C. Одним из следствий этого является хорошо разработанный  стандарт вызова процедур  (часто называемый ABI или ABI).

Набор регистров процессора

 

двоичный интерфейс приложения), который определяет, как используются регистры. [2] В этой модели явным образом предполагается, что оперативная память исполняемой программы разделена на три области, как показано на рис. 2.5. Данные в ОЗУ выделяются в процессе связывания и инициализируются кодом запуска при сбросе (см. главу 3). (Необязательная) куча управляется во время выполнения библиотечным кодом, реализующим такие функции, как маллок и бесплатно которые являются частью стандартной библиотеки C. Стек управляется во время выполнения сгенерированным компилятором кодом, который генерирует кадры стека для каждого вызова процедуры, содержащие локальные переменные и сохраненные регистры. Cortex-M3 имеет  физическое  адресное пространство 232 байт. Техническое справочное руководство ARM Cortex-M3 определяет, как должно использоваться это адресное пространство. [1] Это (частично) показано на рис. 2.6. Как уже упоминалось, доступ к области  Код  осуществляется через шины ICode (инструкции) и DCode (постоянные данные). Доступ к SRAM и периферийным областям осуществляется через системную шину. Физическое население этих регионов зависит от реализации. Например, процессоры STM32 имеют флэш-память объемом 8–1 МБ по адресу (0x08000000).1 Процессор STM32F100 на плате Discovery имеет 8 КБ SRAM по адресу 0x20000000. На этой карте адресов не показаны внутренние периферийные устройства Cortex-M3, такие как NVIC, расположенные начиная с

 

 

Модель памяти программы

 

адрес 0xE000E000; они определены в справочном руководстве Cortex-M3.

[1] Мы обсудим NVIC далее

Адресное пространство памяти Cortex-M3

 

Как уже упоминалось, ядро Cortex-M3 включает векторный контроллер прерываний (NVIC) (подробнее см. в главе 11). NVIC — это программируемое устройство, которое находится между ядром CM3 и микроконтроллером. Cortex-M3 использует модель векторных прерываний с приоритетом — таблица векторов определена для размещения, начиная с ячейки памяти 0. Первые 16 записей в этой таблице определены для всех реализаций Cortex-M3, а остальные, до 240, зависят от реализации. ; например, устройства STM32F100 определяют 60 дополнительных векторов. NVIC поддерживает динамическое переопределение приоритетов до 256 уровней приоритета — STM32 поддерживает только 16 уровней приоритета. Две записи в векторной таблице особенно важны: NVIC также предоставляет ключевые регистры управления системой, включая системный таймер (SysTick), который обеспечивает регулярное прерывание таймера. Предоставление встроенного таймера в семействе Cortex-M3 имеет значительное преимущество, поскольку делает код операционной системы легко переносимым — всем операционным системам требуется как минимум один основной таймер для разделения времени. Регистры, используемые для управления NVIC, определены как находящиеся по адресу0xE000E000 и определяются спецификацией Cortex-M3. Доступ к этим регистрам осуществляется через системную шину.

2.2 СТМ32 Ф1

STM32 — семейство микроконтроллеров. Микроконтроллеры STM32 F1xx

основаны на Cortex-M3 и включают в себя микроконтроллер STM32F100 valueline,

используемый на плате обнаружения, рассматриваемой в этой книге. Серия STM32 L1

является производной от серии STM32 F1, но с пониженным энергопотреблением.

Серия STM32 F2 также основана на Cortex-M3, но имеет расширенный набор

периферийных устройств и более быстрое процессорное ядро. Многие периферийные

устройства серии STM32 F1 совместимы с предыдущими версиями, но не все. В

процессорах серии STM32 F4 используется ядро Cortex-M4, которое является

значительным усовершенствованием Cortex-M3. Наконец, появилось новое семейство

STM32 — STM32 F0 на базе Cortex-M0. Каждое из этих семейств — STM32F0, STM32 F1,

STM32 L1. STM32 F2 и STM32 F4 поддерживаются разными библиотеками

микропрограмм. Несмотря на значительное совпадение между семьями и их

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

STM32 F1.

Как показано на рис. 2.3, микроконтроллеры STM32 F1 основаны на ядре

Cortex-M3 с набором периферийных устройств, распределенных по трем шинам

— AHB и двум ее подшинам APB1 и APB2. Эти периферийные устройства

 

СТМ32 Ф1

 

управляется ядром с помощью инструкций загрузки и сохранения, которые обращаются к регистрам, отображаемым в памяти. Периферийные устройства могут  прерывать  ядро, чтобы привлечь внимание через запросы на прерывание, специфичные для периферийных устройств, маршрутизируемые через NVIC. Наконец, передача данных между периферийными устройствами и памятью может быть автоматизирована с помощью прямого доступа к памяти. В главе 4 мы обсуждаем базовую конфигурацию периферийных устройств, в главе 11 мы показываем, как можно использовать прерывания для создания эффективного программного обеспечения, а в главе 12 мы показываем, как использовать DMA для повышения производительности и обеспечения возможности выполнения обработки параллельно с передачей данных. В этой книге мы используем стандартную периферийную библиотеку ST для процессоров STM32 F10xx. Полезно понять структуру этой программной библиотеки. На рис. 2.7 представлен упрощенный вид структуры каталогов. Библиотека состоит из двух основных подкаталогов — STM32F10x_StdPeriph_Driver и CMSIS. CMSIS означает  Стандарт интерфейса программного обеспечения микроконтроллера Cortex  и предоставляет общее низкоуровневое программное обеспечение, необходимое для всех частей ARM Cortex. Например, файлы core_cm3.* обеспечивают доступ к контроллеру прерываний, системному таймеру и модулям отладки и трассировки. Каталог STM32F10x_StdPeriph_Driver содержит примерно один модуль (всего 23) для каждого из периферийных устройств, доступных в семействе STM32 F10x. На рисунке я включил модули для ввода-вывода общего назначения (GPIO), I2C, SPI и последовательного ввода-вывода (USART).

 

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

STM32 F1 имеет сложную систему синхронизации. Есть два основных внешнихисточника хронометража — HSE и LSE. Сигнал HSE выводится из кварцевого резонатора 8МГц или другого резонатора, а сигнал LSE выводится из кварца 32,768 кГц. Внутри HSE

умножается по частоте за счет использования PLL; выход этого SYSCLK используется для получения (путем деления) различных встроенных источников времени, включая часы для периферийных устройств ABP1 и APB2, а также для различных программируемых таймеров.

LSE используется для управления маломощными часами реального времени. Микроконтроллеры STM32F100 могут поддерживать максимальную частоту SYSCLK 24 МГц, в то время как другие микроконтроллеры STM32 F1xx поддерживают частоту SYSCLK 72 МГц. К счастью, большая часть кода, необходимого для управления этими часами, содержится в модуле стандартной периферийной библиотеки (system_stm32f10x.[ch]) который обеспечивает функцию инициализации

Системная инициализация (пусто) вызываться при запуске. Этот модуль также

Стандартная периферийная библиотека ST

экспортирует переменнуюSystenCoreClock который содержит частоту SYSCLK; это упрощает

Задача разработки кода, переносимого на семейство STM32F1.

 

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

 

2.2. СТМ32 Ф1

 

АЦП Аналого-цифровой преобразователь – Глава 14.

ЦАП Цифро-аналоговый преобразователь – Глава 13.

GPIO Ввод-вывод общего назначения — глава 4.

I2C Шина I2C — Глава 9.

СПИ Шина SPI — Глава 6.

ТИМ Таймеры (разные) — Глава 10.

USART Универсальный синхронный асинхронный приемник-передатчик – Гл.

тер 5.

В этой книге не рассматриваются следующие периферийные устройства.

МОЖЕТ Локальная сеть контроллера. Не поддерживается STM32F100

ЦИК Контроль бытовой электроники.

CRC Блок расчета циклического контроля избыточности.

Эфириум Ethernet-интерфейс. Не поддерживается STM32F100

ФКЦБ Гибкий контроллер статической памяти. Не поддерживается средней плотностью

СТМФ100.

мощность Управление питанием (спящий режим и режим пониженного энергопотребления).

РТК Часы реального времени.

ИВДГ Независимый сторожевой пес.

USB Универсальная последовательная шина. Не поддерживается STM32F100

ВВДГ Оконный сторожевой таймер

Как упоминалось ранее, все периферийные устройства  сопоставляются с памятью ,

что означает, что ядро взаимодействует с периферийным оборудованием, читая и

записывая периферийные  регистры  с помощью инструкций загрузки и сохранения. 2 Все

2. Терминология может сбивать с толку — с точки зрения ядра CM3 периферийные регистры —

это просто выделенные ячейки памяти.

различные периферийные регистры описаны в различных справочных руководствах по STM32 ([20, 21]). Документация включает определения различных регистров на уровне битов и текст, помогающий интерпретировать эти биты. Фактические физические адреса также можно найти в справочных руководствах. В следующей таблице приведены адреса подмножества периферийных устройств, которые мы рассматриваем в этой книге. Обратите внимание, что все они попадают в область адресного пространства Cortex-M3, определенного для периферийных устройств. 0x40013800 – 0x40013BFF 0x40013000 – 0x400133FF 0x40012C00 – 0x40012FFF 0x40012400 – 0x400127FF . . . USART1 SPI1 Таймер TIM1 АЦП1 . . . К счастью, программисту не нужно искать все эти значения, поскольку они определены в файле библиотеки. stm32f10x.h в виде USART1_BASE, SPI1_BASE, TIM1_BASE ADC1_BASE, и Т. Д. Как правило, каждое периферийное устройство имеет управляющие регистры для настройки периферийного устройства, регистры состояния для определения текущего состояния периферийного устройства и регистры данных для чтения данных и записи данных в периферийное устройство. Каждый порт GPIO (GPIOA, GPIOB и т. д.) имеет семь регистров. Два используются для индивидуальной настройки шестнадцати битов порта, два используются для параллельного чтения/записи шестнадцати битов порта, два используются для установки/сброса шестнадцати битов порта по отдельности, а один используется для реализации  последовательности блокировки , которая предназначен для предотвращения случайного изменения конфигурации порта мошенническим кодом. Эта последняя функция может помочь свести к минимуму вероятность того, что программные ошибки приведут к аппаратным сбоям; например, случайное короткое замыкание.

В дополнение к предоставлению адресов периферийных устройств, stm32f10x.h также

предоставляет структуры уровня языка C, которые можно использовать для доступа к каждому

периферийному устройству. Например, порты GPIO определяются следующей структурой регистров.

структура typedef

Адреса регистров различных портов определены в библиотеке как(следующие определения взяты изstm32f10x.h)

# определять PERIPH_BASE.    ((uint32_t)0x40000000)

# определять.  APB2PERIPH_BASE. (PERIPH_BASE + 0x10000)

# определять. GPIOA_BASE. (APB2PERIPH_BASE + 0x0800)

# определять. GPIOA. ((GPIO_TypeDef *) GPIOA_BASE)

Чтобы прочитать 16 бит GPIOA параллельно, мы можем использовать следующее  код:

uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) {

вернуть ((uint16_t)GPIOx->IDR);

}

Предыдущий пример несколько вводит в заблуждение своей простотой.

Учтите, что для настройки контакта GPIO требуется запись двух 2-битных полей в

правильном месте в правильном регистре конфигурации. В общем, требуемые детали

могут быть мучительными.

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

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

представлено подмножество процедур, доступных для управления портами GPIO:

Функция инициализации (GPIO_инит) предоставляет интерфейс для

настройки отдельных битов порта. Остальные функции предоставляют

интерфейсы для чтения и записи (а также установки и сброса) как отдельных

битов, так и 16 бит порта параллельно.

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

У этой библиотеки есть существенный недостаток — модули огромны. Модуль GPIO

stm32f10x_gpio.o при компиляции с проверкой параметров составляет 4 КБ, тогда как

простое приложение может использовать несколько 100 байт пользовательского

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

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

предлагает гораздо более быстрый способ исправить код прототипа. Для работы с прототипом,

вероятно, лучше использовать дополнительное оборудование (память, тактовую частоту) для

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

целесообразно усовершенствовать дизайн, чтобы уменьшить зависимость от этих библиотек.

Чтобы получить представление о стоимости использования библиотеки, рассмотрим код на рис. 2.1, в котором PC8 и PC9 настраиваются как выходы (для управления светодиодами), а PA0 — как входы (для считывания с кнопки). 3. Подобный код на основе библиотеки представлен в качестве упражнения в главе 4. В таблице 2.1 я сравниваю требования к пространству для двух версий этой программы с использованием стандартной периферийной библиотеки и без нее. Первый столбец (текст) обеспечивает размер  текстового сегмента  (инициализаторы кода и данных), данные, выделяемые в оперативной памяти при запуске, представляют собой сумму данных (инициализированные данные) и bss (обнуленные данные). Общие требования к памяти указаны в тексте столбца. Файлы .elf представляют собой полные двоичные файлы. Исключая 256 байт предварительно выделенного стека времени выполнения (bss), версия библиотеки почти в 3 раза больше. В отличие от оригинала, который выполнял минимальную инициализацию системы, я включил два общих файла запуска для обеих версий. Кроме того, стандартная библиотека периферийных устройств имеет расширенную проверку параметров, которую я отключил для этого сравнения.

Размер кода со стандартными библиотеками и без них

 

Программирование без стандартной периферийной библиотеки

 

 

47ост/11/03

Оставьте комментарий

Ваш адрес email не будет опубликован.

Exit mobile version