STM32F091 — микроконтроллер начального уровня на базе ядра ARM Cortex-M0
ПодробностиКатегория: STM
STM32F091 — микроконтроллер начального уровня на базе ядра ARM Cortex-M0 с тактовой частотой 48 МГц, объёмом FLASH-памяти 256 кбайт, CAN интерфейсом и функцией управления пользовательскими устройствами (CEC).
Микроконтроллеры STM32F091xB/xC интегрируют высокопроизводительное 32-битное ядро ARM Cortex-M0 RISC-архитектуры с тактовой частотой 48 МГц.
В дополнение к перечисленному новые устройства содержат высокоскоростную встроенную память (до 256 КБ FLASH и 32 КБ SRAM) и расширенный набор периферийных устройств и линий ввода/вывода.
Микроконтроллеры оснащены стандартными коммуникационными интерфейсами (два I2C, два SPI/один I2S, один HDMI CEC, один CAN и до восьми USART), а также такими периферийными модулями, включая один 12-битный АЦП, один 12-битный ЦАП с двумя каналами, семь 16-битных таймеров общего назначения, 32-битный таймер и таймер ШИМ-модулятора с расширенными функциями управления.
Диапазон рабочих температур STM32F091xB/xC составляет от -40 °C до +85 °C и от -40 °C до +105 °C, а напряжение питания – от 2.0 В до 3.6 В. Различные режимы пониженного энергопотребления помогут разработчикам создавать на базе микроконтроллеров энергоэффективные решения.
STM32F091xB/xC поставляются в корпусах семи различных типов с количеством выводов от 48 до 100 и формой кристалла, которая может быть изготовлена по проекту заказчика. В зависимости от выбранной модели устройства пользователю доступен различный набор периферийных модулей.
Благодаря своим возможностям, STM32F091xB/xC отлично подходят для широкого круга применений, таких как: управление приложениями и пользовательские интерфейсы, портативное оборудование, A/V ресиверы и цифровые телевизоры, периферийные устройства ПК, игровые и навигационные платформы, промышленные приложения, программируемые логические контроллеры, инверторы, принтеры, сканеры, сигнализации, видеоконференции и системы климат-контроля.
Внутренняя архитектура микроконтроллеров STM32F091x
Периферия | STM32F091Cx | STM32F091Rx | STM32F091Vx | |||
FLASH (кбайт) | 128 | 256 | 128 | 256 | 128 | 256 |
SRAM (кбайт) | 32 | |||||
Таймеры | 8 (16-бит)1 (32-бит) | |||||
SPI [I2S] | 2 [2] | |||||
I2C | 2 | |||||
USART | 6 | 8 | ||||
CAN | 1 | |||||
CEC | 1 | |||||
12-бит АЦП (каналов) | 1 (10 внешних + 3 внутренних) | 1 (16 внешних + 3 внутренних) | ||||
12-бит ЦАП (каналов) | 1 (2) | |||||
Аналоговый компаратор | 2 | |||||
GPIO | 38 | 52 | 88 | |||
Емкостной сенсорный интерфейс (каналов) | 17 | 18 | 24 | |||
Частота ЦПУ | 48 МГц | |||||
Напряжение питания | 2.0…3.6 В | |||||
Диапазон рабочих температур | Окружающей среды: -40…+85°C / -40…+105°CПерехода: -40…+105°C / -40…+125°C | |||||
Корпуса | LQFP-48UFQFPN-48 | LQFP-64UFBGA-64WLCSP-64 | LQFP-100UFQFPN-100 |
Отличительные особенности:
- 32-битное ядро ARM® Cortex®-M0 с тактовой частотой до 48 МГц
- Внутренняя память:
- FLASH: от 128 кбайт до 256 кбайт
- SRAM: 32 кбайт с аппаратным блоком контроля по четности
- Блок вычисления кода коррекции ошибок (CRC)
- Система питания и схема сброса:
- Диапазон напряжения питания цифровой части и линий ввода/вывода: от 2.0 В до 3.6 В
- Диапазон напряжения питания аналоговой части: от 2.0 В до 3.6 В
- Схема сброса при включении и выключении питания (POR/PDR)
- Программируемый детектор напряжения (PVD)
- Режимы энергосбережения: спящий, останова и ждущий
- Схема питания от резервного источника (VBAT) для часов реального времени и регистров резервного хранения данных
- Система синхронизации и тактирования:
- Кварцевый генератор с тактовой частотой от 4 МГц до 32 МГц
- Отдельный генератор с тактовой частотой 32 кГц для часов реального времени с калибровкой
- Внутренний RC-генератор с тактовой частотой 8 МГц и шестью узлами фазовой автоподстройки частоты
- Внутренний RC-генератор с тактовой частотой 40 кГц
- Внутренний генератор с частотой 48 МГц с автоматической синхронизацией с внешним тактовым сигналом
- До 88 высокоскоростных линий ввода/вывода
- Карта векторов внешних прерываний
- До 69 линий ввода/вывода с напряжением питания 5 В и 19 линий с независимым источником питания VDDIO2
- 12-канальный контроллер прямого доступа к памяти (DMA)
- Один 12-битный АЦП с частотой дискретизации 1 MSPS (млн. выборок в сек.), до 16 каналов:
- Диапазон напряжения входного аналогового сигнала: от 0 В до 3.6 В
- Независимый источник питания: от 2.4 В до 3.6 В
- Один 2-канальный 12-битный ЦАП
- Два быстродействующих аналоговых компаратора с настраиваемыми входами и выходами
- До 24 каналов сенсорного емкостного интерфейса с функциями кнопок, клайдера и дискового элемента ввода
- Часы реального времени (RTC) с календарем, будильником и периодическим выходом из режима останова/ожидания
- 12 таймеров:
- Один 16-битный таймер с расширенными функциями управления для формирования 6 каналов ШИМ
- Один 32-битный и семь 16-битных таймеров с четырьмя каналами захвата/сравнения/OCN, необходимых для декодирования команд управления инфракрасного порта или управления ЦАП
- Независимый и системный сторожевой таймеры
- Системный таймер SysTick
- Коммуникационные интерфейсы:
- Два интерфейса I2C с поддержкой режима Fast Mode Plus (скорость передачи данных 1 Мбит/с) и током нагрузки 20 мА, один из которых поддерживает режим шины SMBus/PMBus и выход из режима сна по сигналу пробуждения
- До 8 портов USART с поддержкой синхронного режима ведущего SPI и управление модемом. Три из них поддерживают интерфейс ISO7816, LIN и IrDA с автоматическим определением скорости передачи данных и функцией выхода из режима сна по сигналу пробуждения
- Два интерфейса SPI со скоростью передачи данных 18 Мбит/с и программируемой длиной фрейма от 4 до 16 бит, а также мультиплексированный интерфейс I2S
- Интерфейс сети CAN
- Функция пробуждения при вставке разъёма в гнездо HDMI
- Последовательный проводной интерфейс отладки (SWD)
- Уникальный 96-битный идентификатор устройства
Область применения:
- Управление приложениями
- Пользовательские интерфейсы
- Портативное оборудование
- Аудиовидеоресиверы и цифровые телевизоры
- Периферийные компоненты ПК
- Игровые и навигационные платформы
- Промышленные приложения
- Программируемые логические контроллеры
- Инверторы
- Принтеры
- Сканеры
- Системы тревоги
- Видеоконференции
- Системы климат-контроля
Инструментальные средства:
NUCLEO-F091RC — отладочная плата STM32 Nucleo на базе микроконтроллера STM32F091RCT6 с поддержкой платформы Arduino.
- Плата STM32 Nucleo предлагает пользователю гибкий и доступный способ опробовать новые идеи и построить прототип на основе любого микроконтроллера серии STM32, производя выбор из различных комбинаций производительности, потребляемой мощности и набора периферии
- Поддержка плат расширения Arduino™ и ST Morpho позволяет расширить функциональные возможности открытой платформы разработки STM32 Nucleo благодаря широкому выбору специализированных модулей. Плата STM32 Nucleo не требует никаких дополнительных инструментальных средств, поскольку имеет в своем составе программатор/отладчик ST-LINK/V2-1
- Помимо этого, разработчикам доступна полнофункциональная библиотека (аппаратно абстрактного уровня) драйверов и примеров прикладного кода, а также доступ к онлайн среде проектирования embed
Источник: http://gamma.spb.ru/novosti-proizvoditelej/stm/190-stm32f091-mikrokontroller-nachalnogo-urovnya-na-baze-yadra-arm-cortex-m0
STM32 для начинающих. Урок 1. GPIO
GPIO (general-purpose input/output,Интерфейс ввода/ вывода общего назначения)— Интерфейс связывающий микроконтроллер с внешними устройствами (Кнопками, светодиодами, датчиками и так далее).
Как и любой другой микроконтроллер, микроконтроллер STM32, имеет в своем составе интерфейс ввода/вывода.
Данный интерфейс позволяет управлять внешними устройствами путем передачи сигналов низкого и высокого уровня через контакты GPIO, а так же принимать данные с них, путем приема сигналов низкого или высокого уровня.
Контакты GPIO, группируются в порты(GPIOA,GPIOB,GPIOC…). Каждый контакт может работать на прием или передачу данных.
Рассмотрим режимы работы контакта GPIO:
- Hi—Z вход — В таком состоянии сопротивление входа стремится к бесконечности, и он ведет себя как отключенный от схемы.
- Вход с подтяжкой к питанию — Контакт работает на прием данных. Когда данных нет, контакт подтягивается к логической “1” (напряжению питания). Это делается, что бы избежать помех и искажения данных.
- Вход с подтяжкой к земле — Контакт работает на прием данных. Когда данных нет, контакт подтягивается к логическому “0” (земле). Это делается, что бы избежать помех и искажения данных.
- Аналоговый вход — Контакт работает в аналоговом режиме, что позволяет выводить на него сигнал ЦАП или считывать сигнал для АЦП.
- Выход с открытым коллектором.
- Двухтактный выход — Контакт работает на передачу данных. Контакт может быть установлен в логическую “1” либо в логический “”, соответствующим регистром.
- Альтернативный режим с подтяжкой.
- Альтернативный режим с открытым коллектором.
Альтернативные режимы пока рассматривать не будем, равно как выход с открытым коллектором и аналоговый вход. Рассмотрим подробнее режимы работы “Вход с подтяжкой к питанию/земле” и “Двухтактный выход”.
Как и любую другую периферию, перед использованием GPIO необходимо настроить.
Так как периферия микроконтроллеров STM32 очень богата и разнообразна, разработчики потрудились облегчить жизнь пользователям и избавить их от ручной правки регистров, путем создания библиотек HALи SPL.
Разумеется, никто не запрещает вам вручную править регистры. Хоть ручная правка регистров и сложна, однако позволяет лучше понять работу микроконтроллера и оптимизировать прошивку.
Читайте также GPS маячок. STM32
Но мы не будет сильно углубляться в дебри даташитов и регистров. Возьмем библиотеку SPLи с её помощью инициализируем порты ввода/вывода нашей платы STM32 F3 DISCOVERY.
Работать будем в среде Keil uVision 5.
Как создать свой первый проект в данной среде смотрите здесь :
STM32 для начинающих. Урок 0. Создание проекта в Keil uVision.
Добавим следующий код:
#include “stm32f30x_gpio.h”#include “stm32f30x_rcc.h”RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE,ENABLE);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);GPIO_StructInit (&PORTE);PORTE.GPIO_Mode = GPIO_Mode_OUT;PORTE.GPIO_OType = GPIO_OType_PP;PORTE.GPIO_Pin = GPIO_Pin_10;PORTE.GPIO_PuPd = GPIO_PuPd_DOWN;PORTE.GPIO_Speed = GPIO_Speed_50MHz;GPIO_StructInit (&PORTA);PORTA.GPIO_Mode = GPIO_Mode_IN;PORTA.GPIO_Pin = GPIO_Pin_0;PORTA.GPIO_PuPd = GPIO_PuPd_DOWN;PORTA.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init (GPIOE,&PORTE);GPIO_Init (GPIOA,&PORTA);if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)GPIO_SetBits(GPIOE,GPIO_Pin_10);GPIO_ResetBits(GPIOE,GPIO_Pin_10); |
Итак, разберем подробнее, что же происходит в данном коде.
Точка входа — функция main, именно с неё начинается работа нашей прошивки. Сначала вызывается функция InitGPIO,в которой мы настраиваем работу наших портов. Остановимся на ней подобробнее.
Вначале создаются две структуры GPIO_InitTypeDef инициализации портов GPIOE,GPIOA, названные мною как PORTA,PORTE. Данные структуры являются частью библиотеки SPL, и содержат в себе параметры работы соответствующих портов.
Читайте также STM32.Bluetooth и Android.
Затем, происходит включение тактирование портов GPIOA,GPIOE командами RCC_AHBPeriphClockCmd. Следует помнить что, изначально тактирование периферии контроллера отключено, в целях снижения энергопотребления. Данной командой мы включаем или выключаем тактирование периферии шины AHB. Подробнее о тактировании поговорим в следующих уроках.
После этого мы заполняем поля структуры GPIO_InitTypeDef , для портов GPIOE,GPIOA. Предварительно структуру можно проинициализировать (записать в неё стандартные значения) командой GPIO_StructInit. Рассмотрим поля структуры GPIO_InitTypeDef:
- GPIO_Mode — Режим работы порта.
- GPIO_OType — При настройке порта на выход, данным полем задается его тип (С открытым стоком или двухтактный).
- GPIO_Pin — Данным полем мы выбираем, какие ножки порта настраивать.
- GPIO_PuPd — Выбираем режим подтяжки к напряжению питания или к земле.
- GPIO_Speed — Скорость работы порта.
Итак, поля заполнены, теперь инициализируем порты согласно тому, что прописано в соответствующей структуре командой GPIO_Init.
На этом функция InitGPIO заканчивается.
После вызова функции InitGPIO, наступает основной цикл программы while. В нем мы считываем входящее значение 0 ножки порта GPIOA(К которой подключена кнопка USER платы STM32 F3 DISCOVERY).
Делаем мы это командой GPIO_ReadInputDataBit, которая возвращает входное значение выбранной ножки порта. В соответствии с состоянием ножки 0 порта GPIOA, выставляем значение 10 ножки порта GPIOE командами GPIO_ResetBits и GPIO_SetBits.
Команда GPIO_ResetBits устанавливает логический ноль на выбранной ножке порта, а команда GPIO_SetBits устанавливает логическую единицу на выбранной нами ножке.
Когда вы загрузите данную программу в плату STM32 F3 DISCOVERY, не забудьте нажать кнопку RESET, которая сбросит микроконтроллер. После этого нажимайте кнопку USER и смотрите за результатом.
Спасибо за внимание!
Другие уроки цикла
Любое копирование, воспроизведение, цитирование материала, или его частей разрешено только с письменного согласия администрации MKPROG.RU. Незаконное копирование, цитирование, воспроизведение преследуется по закону!
Источник: http://mkprog.ru/mikrokontrollery-stm32/stm32-dlya-nachinayushhih-urok-1-gpio.html
Изучаем STM32. Урок 2. Изучаем порты ввода-вывода GPIO (ч1) — DRIVE2
Добрый день, итак, пока есть время между редактированиями кодов и пайками)) напишу ещё одну статейку. На этот раз мы будем знакомиться с нашими ножками (нет не теми что внизу), а теми которые находятся на микроконтроллере и за счёт чего он воспринимает сигналы из внешнего мира и соответственно передаёт сигналы в него.
Итак, давайте посмотрим на блок — схему порта ввода-вывода контроллера
Тут у нас справа расположены защитные диоды, дальше внизу расположен регистр вывода и на нём мы видим два полевичка один из которых N-канаьный, второй P-канальный. Именно они нам выдают либо лог. единицу, либо лог. ноль.Вверху нарисован регистр ввода, в котором мы видим триггер шмидта, перед ним мы видим резисторы подтяжки
Ну кому более интересно это, тот может найти feference manual и выучить всё от корки до корки, мы же в данной части урока просто разберёмся что значат разные режимы работы наших портов
Итак, помните в прошлом уроке мы настраивали чем у нас будет ножка контроллера — Входом, Выходом. Но это не все параметры. Ещё ножка может быть сконфигурирована как аналоговый входвыход для допустим работы с АЦП, или с ЦАП, у кого он есть на “борту”))
Давайте рассмотрим все режимы работы
1)Input floating — по простому это вход безо всяких подтяжек (Hi-Z состояние, плавающий). По простому вход у нас ни к чему не подключён (привет помехи))))
2)Input pull-up — режим входа, в котором он чрез подтягивающий резистор подключён к питанию (номинал резистора несколько десятков килоОм)
3)Input-pull-down — режим входа, в котором он чрез подтягивающий резистор подключён к земле (массе) (номинал резистора несколько десятков килоОм)
4)Analog — режим работы, который включаем если желаем работать с АЦП или ЦАП
5)Output open-drain with pull-up or pull-down capability — выход с “открытым коллектором”
6)Output push-pull with pull-up or pull-down capability — самый используемый режим, в котором наш пин может выдавать как лог. ноль так и лог. единицу (это будут работать те самые полевые тарнзисторы о которых писал выше)
7)Alternate function push-pull with pull-up or pull-down capability — альтернативная функция (двухтактный вывод)
8)Alternate function open-drain with pull-up or pull-down capability — альтернативная функция (открытый
коллектор)
Теперь опишу как работаем с этими параметрами в нашей среде программирования.
Вот смотрите, кусочек кода, который отвечает за настройку параметров выхода
GPIO_InitStruct.Pin = GPIO_PIN_0; — данная строчка кода указывает что конфигурировать мы будем ножку 0
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; — Данная строчка указывает что режим работы — ВходУ данной строчки могут быть вот такие параметрыGPIO_MODE_INPUTGPIO_MODE_OUTPUT_PPGPIO_MODE_OUTPUT_ODGPIO_MODE_AF_PP
GPIO_MODE_AF_OD
Следующая строчка GPIO_InitStruct.Pull = GPIO_PULLDOWN; — Указывает что у нас подтяжка к массе. У данной строчки ещё могут быть вот такие вариантыGPIO_NOPULLGPIO_PULLUP
GPIO_PULLDOWN
Ну и последняя строчка указывает нам с каким портом нашего контроллера мы вообще только что разговаривали) — HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Здесь мы рассмотрели настройку нашего пина к которому подключена кнопка. PA0.
А давайте теперь рассмотрим настройку нашего порта, куда подключены светодиоды/*Configure GPIO pins : PD12 PD13 */GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_LOW;HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13; — эта строчка указывает какие пины настраиваем
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; — эта строка указыввает нам режим работы — ВЫХОД двухтактный (push-pull) . Возможные варианты конфигурации описаны чуть выше.
GPIO_InitStruct.Pull = GPIO_PULLUP; — данная штука указывает что включена подтяжка к питаниюВозможные варианты конфигурации описаны чуть выше.
GPIO_InitStruct.Speed = GPIO_SPEED_LOW; — данная строчка настраивает скорость работы выхода
Возможны вот такие вариантыGPIO_SPEED_LOW — низкая скорость 2MHzGPIO_SPEED_MEDIUM — средняя скорость 25MHzGPIO_SPEED_FAST — повышеная скорость 50MHz
GPIO_SPEED_HIGH -высокая скорость до 100MHz
Также, чтобы работал наш порт, и мы что то могли с ним делать — нам нужно включить тактирование порта.
Так как мы создаём проект в CubeMX, то он за нас это всё делает, но на будущее, мало ли, может кто то захочет использовать старые библиотеки- не забывайте подавать тактирование на нужные вам порты.
В нашем случае тактирование наших портов включается вот таким образом/* GPIO Ports Clock Enable */__GPIOA_CLK_ENABLE();
__GPIOD_CLK_ENABLE();
Если поищем дальше, что обозначают эти строки то вот что найдём. Функция включения тактирования нашего порта A.#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \__IO uint32_t tmpreg; SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);/* Delay after an RCC peripheral clock enabling */ mpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);UNUSED(tmpreg);
} while(0)
Ну а теперь код, с помощью которого мы управляем нашими пинами. HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9,GPIO_PIN_RESET); — сбрасывает пин в НОЛЬHAL_GPIO_WritePin(GPIOC, GPIO_PIN_9,GPIO_PIN_SET); — устанавливает пин в ЕДИНИЦУ
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9); — изменяет состояние пина на противоположное. Если было 0, то станет единица, и наоборот.
Ну и добавлю сюда ещё одну функцию — функция задержки Delay. Мы её часто использовали в CAVR, и тут она тоже есть. Задаётся она в милисекундах и выглядит вот так — HAL_Delay(100);
Это означает задержка в 100 милисекунд.
Можете теперь поиграться светодиодами на плате, выставив задержку и используя HAL_GPIO_TogglePin. Ваши светодиоды будут по очереди перемигиваться.
Жмём палец вверх, и читаем, читаем, читаем мануалы, и уже в голове придумываем что мы сделаем на STM32! STM — мечты сбываются)))
Ну и не забываем про хорошую музычку, да погромче! Пока писал — наслаждался вот этим шедевральным концертом. С ним как то и светодиоды по другому перемигиваются))
Источник: https://www.drive2.ru/b/2212642/
STM32F407: быстрый старт
Источник: http://microsin.net/programming/ARM/stm32f407-quick-start.html
Микроконтроллеры Процессоры, проекты, программирование
Настройка порта GPIO в STM32 для цифрового ввода/вывода требует выполнения двух основных действий – подключения тактового сигнала и настройки режима работы. Также, при необходимости, выполняется блокировка настроечных параметров.
Пример 1. Вариант настройки, с использованием структур языка С
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // Подключение тактового сигнала
GPIOC->CRH |= GPIO_CRH_MODE8; // Настройка режима PORTC.
8 с частотой 50 МГц
GPIOC->CRH &=~GPIO_CRH_CNF8; // Установка простого режима цифрового выхода
В языке С очень популярно использование разнообразных структур данных и определений. Пример выше использует все эти элементы.
Первая строчка выполняет функцию подключения PORTC к шине APB2. Запись RCC->APB2ENR представляет собой обращение к регистру APB2ENR из группы регистров тактирования и контроля RCC. RCC_APB2ENR_IOPCEN есть определение значения управляющего бита PORTC в регистре APB2ENR.
В числовом виде данное значение выглядит как 0x00000010. Для установки используется оператор «ИЛИ», так как в данном регистре уже есть настроенные биты. Использовать чистое присваивание в данном случае нельзя.
Вторая строчка устанавливает режим работы выхода 8 в PORTC. Опять используется константа GPIO_CRH_MODE8 = 0x00000003, устанавливающая линию на выход с максимальной частотой.
Также можно использовать GPIO_CRH_MODE8_0 =0x00000001 или GPIO_CRH_MODE8_1=0x00000002, которые устанавливают порт на выход с частотой 10 и 20 МГЦ соответственно. Для других линий ввода/вывода используются точно такие же константы, имеющие номер соответствующей линии.
Следует учитывать, что настройка линий с 0 по 7 производится обращением к регистру GPIOC->CRL.
Третья строчка устанавливает тип ввода вывода. В данном случае используется простой цифровой вывод. Для этого в поле CNF8 необходимо записать значение 00.
Делается это использованием оператора «И» и инверсией константы GPIO_CRH_CNF8. Последняя, в ее прямом значении, устанавливает режим альтернативного вывода с открыты стоком, так как ее значение равно 11.
Доступны константы GPIO_CRH_CNF8_0 = 0x00000004 (режим 01) и GPIO_CRH_CNF8_1 = 0x00000008 (режим 10).
После выполнения всех этих действий, настройку порта можно считать законченной.
Пример 2. Настройка порта «классическим» способом
RCC->APB2ENR |= 0x00000010; // Подключение тактового сигнала GPIOC->CRH = 0x00000333; // Настройка режима PORTC.
8,9,10 с частотой 50 МГц
Данный код выполняет те же самые функции, что и приведенный выше. Единственное отличие – использование записи данных напрямую, без предопределенных констант.
Это несколько снижает объем исходного кода и больше напоминает программирование на ассемблере.
Первая строчка полностью аналогична первому примеру. Вторая выполняет настройку сразу трех линий ввода вывода. Каждый разряд используемого операнда отвечает за одну линию. В итоге одной строчкой можно настроить половину порта ввода/вывода.
Значение параметра соответствующей линии записывается в шестнадцатеричной форме, и устанавливает сразу оба поля CNF и MODE.
Так значение 3h соответствует 0011 или режиму простого вывода с максимальной скоростью, а значение Bh то же самое, что и 1011 или высокоскоростной выход, подключенный к альтернативному модулю.
Пример 3. Настройка порта на вывод
GPIOC->CRH = 0x00008333;
Данный пример осуществляет установку линий 8,9,10 как выходов, а линию 11 как цифровой вход. Для этого в поля CNF11и MODE11 заносится значение 8h или в двоичном виде 1000b.
Вывод информации
Запись данных в регистр производится самым обычным способом, с помощью операции равно.
GPIOA->ODR=0xABCD; GPIOA->ODR=0x0000;
При использовании регистра GPIOx_BSRR возможна как запись значений, так и предопределенных констант. Для установки высокого уровня сигнала применяются константы GPIO_BSRR_BSy, а для сброса GPIO_BSRR_BRy, где y – номер соответствующей линии.
Пример 4. Использование GPIOx_BSRR
GPIOC->BSRR=0x00010010; GPIOC->BSRR=0x00100001; GPIOC->BSRR=GPIO_BSRR_BS4|GPIO_BSRR_BR0; GPIOC->BSRR=GPIO_BSRR_BS0|GPIO_BSRR_BR4;
Первая и третья строчки устанавливают линию 4 и сбрасывают 0, вторая и четвертая производят обратную операцию.
Чтение состояния бита
if (GPIOC->IDR & GPIO_IDR_IDR11) GPIOC->BSRR = GPIO_BSRR_BS8;
Данная строчка выполняет опрос бита 11 регистра GPIOC->IDR и установку бита 8 в случае положительного результата. Также при программировании STM32 возможно простое присваивание значения регистра IDR какой-либо переменной.
Все, вышеуказанные примеры были опробованы на плате STM32 Discovery и показали свою работоспособность.
You have no rights to post comments
Источник: https://mcucpu.ru/index.php/stm32/83-stm32gpioprimers
GPIO: мигаем светодиодом
Наконец-таки мы приступим к оживлению устройства и научимся мигать светодиодом. Создайте проект lesson_01_led (или добавляйте функционал в файлы leds.h и leds.c).
Итак, порты ввода-вывода общего назначения уже упоминались ранее, и настало время воспользоваться полученными знаниями, дабы зажечь светодиод (любой из трех на плате). Сразу же возникает вопрос о том, как правильно подключить светодиод к МК, но об этом в самом конце курса.
Сейчас нас должно заботить только одно – как заставить его светиться. Абстрагируемся от физики и допустим, что если на ножку подать логическую «1» (т. е. напряжение 3,3 В), то светодиод загорится. Если же мы прдадим логический «0», соответственно, светодиод гореть не будет.
Как видите, один вывод (анод, он же «плюс») светодиода подключен к микроконтроллеру, а второй вывод (катод, он же «минус») подключен к земле. Вам должно быть известно, что ток побежит через светодиод в сторону земли.
Критически важно научиться работать с документацией, и начнем мы именно с этого. Для начала откройте принципиальную схему устройства из раздела «обзор конструктора» и найдите светодиод, который хотите зажечь (LED1, LED2 или LED3).
Здесь нам нужно выяснить, к какой ножке подключен светодиод. Допустим, мы хотим использовать LED1, который подключен к PB0. Что же это такое? Портов в микроконтроллере может быть несколько, и обозначаются они буквами A, B … F. В stm32 каждый порт может иметь 16 выводов.
Значит, LED1 подключен к порту B, ножке номер 0. По умолчанию все периферийные устройства, к которым относятся и порты ввода-вывода, отключены от системы тактирования.
И правильно – зачем питать те модули, которые не используются? В разделе «Что у микроконтроллера под капотом» была представлена диаграмма с внутренним устройством МК, на которой можно заметить, что порты подключены к шине APB2.
Также, когда мы говорили о системе тактирования, был упомянут модуль, ответственный за это – RCC. Теперь, когда мы сопоставили все эти факты, нам предстоит:
- включить тактирование порта B;
- настроить 2-ю ножку порта B на выход;
- управлять этой ножкой.
Но перед тем, как мы включим тактирование и настроим ножку, давайте создадим специальную функцию, которая будет отвечать за логику настройки ножки.
// leds.h
…
void init_leds(void);
…
// leds.c
void init_leds() { // Код по настройке ножки
}
Добавьте функцию инициализации светодиодов в оговоренную в прошлом разделе функцию init_mcu(), в которой будут вызываться все инициализирующие функции нашей программы.
// main.c
int main() { init_mcu(); while(1) { // Включаем и выключаем светодиод }
}
Пожалуй, наиболее важным документом, с которым нам придется работать, является Reference Manual.
В нём содержится описание всего адресного пространства и всех регистров микроконтроллера, а также того, за что они отвечают. Как нам известно – регистр не что иное, как ячейка памяти.
Следовательно для того что бы включить тактирование порта B нам необходимо записать единицу по определённому адресу.
Давайте откроем данный документ и найдем в оглавлении пункт, «2.2 Memory organization». Интересующей нас пункт «Reset and clock control RCC» (модуль системы тактирования), имеет адрес 0x40021000.
Сам модуль имеет много разных регистров, нам очевидно необходим тот, что отвечает за порты ввода-вывода. Обратимся снова к оглавлению и в «6 Reset and clock control (RCC)» перейдём к пункту «6.3.7 APB2 peripheral clock enable register (RCC_APB2ENR)».
Как видим, здесь указан не абсолютный адрес, а смещение относительно 0x40021000 – 0x18. Следовательно необходимый нам адрес – 0x40021018. Получается, что для включения тактирования необходимо просто в регистр APB2ENR записать на место четвёртого бита единицу. Как это сделать? Очень просто!
*((u32 *)0x40021018) = 0x00000008;
Но, конечно же, никто так код не пишет (21 век, как-никак). Для каждой периферии заведена структура, в которой хранятся переменные, связанные с соответствующими регистрами. В нашем случае это структура RCC. Так выглядит запись «1» на место третьего бита:
RCC->APB2ENR |= 1 APB2ENR |= RCC_APB2ENR_IOPBEN;
Так намного лучше. Согласно намеченному нами плану, необходимо настроить порт на выход.
Перейдем к разделу General-purpose I/Os (GPIO), подразделу GPIO registers. Первые два регистра, которые мы встречаем, называются GPIOx_CRL (L, нижний) и GPIOx_CRH (H, высокий). (Названия регистров могут отличаться от микроконтроллера к микроконтроллеру.
Так, например, в stm32f103 регистры MODE и CNF разделены на большее число (функционал логически обособлен) регистров.) Так как ножек на одном порте может быть 16, а под настройку режима и скорости каждого нужно по 4 (22) бита, то в общей сложности их требуется 64.
Поскольку мы хотим настроить нулевую ножку, нам необходимо произвести запись в MODE0 и CNF0 соответственно.
Настроим MODE0.
Ножка должна работать в режиме выхода. Раз скорость для нас не важна, то пусть это будет 2 МГц. Другими словами, в нижний регистр нужно записать «0», а в верхний – «1».
GPIOB->CRL &= ~GPIO_CRL_MODE0_0;
GPIOB->CRL |= GPIO_CRL_MODE0_1;
Теперь нужно настроить сам режим работы – двухтактный выход.
GPIOB->CRL &= ~GPIO_CRL_CNF0;
На этом настройка завершена. Теперь, если мы запишем в выходной регистр «1», то на выходе появится напряжение 3,3 В, и соответственно, если запишем «0», на выходе будет 0 В.
while(1) { GPIOB->ODR |= GPIO_ODR_ODR0; for (uint32_t i = 0; i ODR &= ~GPIO_ODR_ODR0; for (uint32_t i = 0; i
Так как мы еще не умеем делать правильные задержки, просто заполним процессорное время обработкой цикла на 1 миллион операций. Для выполнения такта процессора используется ассемблерная инструкция NOP (сокращение от английского: «No OPeration»), которая говорит процессору пропустить один такт работы (ничего не делать в течение него).
Подумайте, при помощи какой логической операции можно сократить код переключения состояния на две строчки.
Ответ:
GPIOB->ODR ^= GPIO_ODR_ODR0;
for (u32 i = 0; i
Осталось лишь запустить программу!
В дальнейшем мы научимся работать со стандартной библиотекой периферии, которая позволит абстрагироваться от регистров и делать всё на уровне структур. Но об этом чуть позже.
Код урока можно найти на github.
Источник: http://stm32.chrns.com/post/149088613644/gpio
STM32: Урок 4 – GPIO
GPIO (General Purpose Input-Output) — это выводы общего назначения, ноги микроконтроллера, доступные для прямого управления.
Это обычно довольно дефицитный ресурс во многих популярных МК, но с STM32 эта проблема теряет актуальность: в самом мелком корпусе (LQFP48) доступно 37 GPIO, а в самом большом (LQFP176) — 140 GPIO.
И всё это богатство ещё и настраивается вдоль и поперёк. Но, обо всём по порядку.
Для начала откроем и взглянем на схему вывода порта:
Сами МК питаются 3.3 В, но до сих пор ещё активно используются 5-вольтовые микросхемы и логика, а их нужно как-то подключать. Поэтому в STM32 большинство выводов «толерантны» к 5 В — уж не знаю, как ещё перевести термин «5 V tolerant».
То есть, они могут принимать на вход 5 В без какой-либо угрозы их здоровью. Толерантный пин отличается от обычного только тем, что у него верхний защитный диод подключён к Vdd_ft вместо Vdd.
Из этой схемы становится понятно, что хоть выводы и толерантны к 5 В на вход, но вот выдавать 5 В на выход не могут — тут уже нужен транзистор. Если нужно получить логическую единичку, то это не проблема — 3.
3 В вполне распознаются 5-вольтовой логикой как 1, но если нужно именно 5 В, то есть решение — режим Open-drain у GPIO. Всего у STM32F10x режимов GPIO имеется 8.
Выход общего назначения:
- Push-pull, стандартный выход: выставляешь 0 в выходном регистре — получаешь низкий уровень на выходе, выставляешь 1 — получаешь высокий.
- Open-drain (открытый сток, аналог открытого коллектора): вывод подключен к стоку N-MOS полевика в то время, как P-MOS полевик заперт, что позволяет управлять нагрузкой с большим напряжением, чем Vdd (3.3 В). Кому там нужно 5 В на выход? Ниже я расскажу, как их получить.
Выход с альтернативной функцией (для периферии типа SPI, UART):Вход:
- Analog, аналоговый высокоимпендансный: подтягивающие резисторы и триггер Шмитта отключены. Используется при работе с АЦП.
- Floating, обычный высокоимпендансный: подтягивающие резисторы отключены, триггер Шмитта включен.
- Pull-up, вход с подтяжкой к питанию.
- Pull-down, вход с прижатием у к «земле».
Как водится, линии GPIO объединены в порты, в STM32 — по 16 линий, поэтому нумеруются они с 0 по 15: PA0, PA1… PA15 — это линии порта A, например. Линии порта управляются программно с помощью нескольких регистров.
GPIOx_CRL и GPIOx_CRH — регистры конфигурации, содержат настройки режима (вход/выход) и частоты GPIO. Доступны на чтение и запись.
GPIOx_IDR и GPIOx_ODR — входной и выходной регистры: в первом хранится считанное со входов порта значение, во второй записывается новое состояние выводов. GPIOx_IDR доступен только на чтение, а GPIOx_ODR — на чтение и запись.
GPIOx_BSRR и GPIOx_BRR — регистры атомарного изменения битов в GPIOx_ODR.
Обычно, если нужно установить бит в регистре периферии, то его сначала нужно прочитать, потом применить побитовое 'ИЛИ' к считанному значению и битовой маске, после чего записать новое значение назад в регистр. То же и со сбросом битов, только маску нужно инвертировать и применить побитовое 'И'. А вот запись значений в GPIOx_BSRR и GPIOx_BRR изменяет только те биты выходного регистра, которые были установлены в единицу, притом происходит это за 1 такт, так что прерывание не сможет ворваться и всё испортить. Проиллюстрирую кодом:const uint32_t mask = 1 PB6, RX -> PB7 */ GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);Если вы два часа разводили двустороннюю плату, а потом обнаружили, что не можете развести какую-то сторону без огромной тучи переходов и перемычек, возможно, что функция переназначения выводов спасёт вашу клавиатуру от нелепой смерти под кулаком. Есть у GPIO и довольно диковинная функция — блокирование выводов. Я так и не понял, зачем она может понадобится, но суть такова: можно заблокировать изменение состояния любого GPIO до следующей перезагрузки МК. Активируется тоже несложно:/* Фиксируем состояния выводов PA6 и PA13 */ GPIO_PinLockConfig(GPIOA, GPIO_Pin_6 | GPIO_Pin_13);
Несколько слов об электрических характеристиках
В встречаются рекомендации подключать не более 20 выводов с отдачей 8 мА через каждый или не более 8 выводов с 20 мА, но практически нереально найти информацию по максимальному току на вывод. Но есть таблица, где приведена максимальная рассеиваемая мощность для МК целиком, причём для разных корпусов эта мощность разная. Например, для LQFP64, в котором идёт STM32F100RBT6B на STM32VLDiscovery, эта мощность равна 444 мВт, что при напряжении питания 3.3 В даёт силу тока ~134 мА. В другой таблице указано, что максимальный ток, потребляемый МК в режиме выполнения кода со всей включенной периферией при 100℃, составляет 15.7 мА. Итого имеем 134 — 15.7 = 118.3 мА на все выходы. Это максимальный ток, который может пропустить через себя МК, что немного расходится с рекомендациями. Впрочем, питать что-либо кроме светодиодов от MК в любом случае — плохая идея, а 118.3 мА хватит на пару-тройку десятков обычных светодиодов, которые при номинальном токе в 20 мА выжигают глаза, а при 1 мА вполне годятся в индикаторы.
Источник: http://robocraft.ru/blog/ARM/687.html
Adblockdetector