Stm32. порты ввода/вывода

Микроконтроллеры Процессоры, проекты, программирование

Порты ввода/вывода GPIO в STM32 имеют по 16 линий, каждая из которых может быть настроена необходимым образом.

Поддерживаются функции цифрового ввода, цифрового вывода, входа внешнего прерывания, а также функции ввода/вывода других модулей микроконтроллера.

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

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

Port configuration register low (GPIOx_CRL) (x=A..G)

Port configuration register high (GPIOx_CRH) (x=A..G)

Для программирования режимов работы портов ввода/вывода STM32, используются два 32 разрядных регистра для каждого GPIO. Они позволяют произвольно настроить режим работы любой отдельной линии.

Регистр GPIOx_CRL отвечает за линии с номерами от 0 до 7, GPIOx_CRH – за линии 8-15. Для каждой из них в регистре имеется два двухразрядных поля CNFy[1:0] и MODEy[1:0].

Первое определяет тип работы линии, второе – направление обмена по линии. все биты доступны для чтения/записи.

Регистр GPIOx_CRL

Бит регистра 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Поле CNF7[1:0] MODE7[1:0] CNF6[1:0] MODE6[1:0] CNF5[1:0] MODE5[1:0] CNF4[1:0] MODE4[1:0]
Линия ввода/вывода 7 6 5 4
Бит регистра 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Поле CNF3[1:0] MODE3[1:0] CNF2[1:0] MODE2[1:0] CNF1[1:0] MODE1[1:0] CNF0[1:0] MODE0[1:0]
Линия ввода/вывода 3 2 1

Регистр GPIOX_CRH

Бит регистра 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Поле CNF15[1:0] MODE15[1:0] CNF14[1:0] MODE14[1:0] CNF13[1:0] MODE12[1:0] CNF12[1:0] MODE12[1:0]
Линия ввода/вывода 15 14 13 12
Бит регистра 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Поле CNF11[1:0] MODE11[1:0] CNF10[1:0] MODE10[1:0] CNF9[1:0] MODE9[1:0] CNF8[1:0] MODE8[1:0]
Линия ввода/вывода 11 10 9 8

Поле MODEy[1:0] может принимать следующие значения:

  • 00 – линия работает на ввод. Данное состояние устанавливается после сброса.
  • 01 – линия работает на выход, с максимальной частотой переключения 10 МГц
  • 10 – линия работает на выход, с максимальной частотой переключения 20 МГц
  • 11 – линия работает на выход, с максимальной частотой переключения 50 МГц

Поле CNFy[1:0] зависит от направления передачи. При работе на вход (MODEy[1:0]=0) доступны следующие состояния:

  • 00 – аналоговый вход.
  • 01 – вход в третьем состоянии. (Устанавливается после сброса).
  • 10 – вход с подтягивающим резистором
  • 11 – зарезервировано для будущих применений.

При работе на выход (MODEy[1:0]>0) поле CNFy[1:0] может иметь следующие состояния:

  • 00 – цифровой выход
  • 01 – цифровой выход с открытым стоком
  • 10 – цифровой выход, подключенный специализированным блокам
  • 11 – цифровой выход, подключенный специализированным блокам с открытым стоком 

Регистр защиты от изменения настроек

Port configuration lock register (GPIOx_LCKR) (x=A..G)

Бит 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Поле Резерв LCKK
Бит 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Поле LCK15 LCK14 LCK13 LCK12 LCK11 LCK10 LCK9 LCK8 LCK7 LCK6 LCK5 LCK4 LCK3 LCK2 LCK1 LCK1

Установить блокируемый бит  в GPIOx_LCKRДля невозможности изменения настроек порта в микроконтроллерах STM32 используется регистр GPIOx_LCKR. Его младщие 15 бит отвечают за соответсвующие линии порта ввода/вывода. Бит 16, установленный в 1, разрешает блокировку изменения настроек.

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

 Алгоритм установки защиты выглядит следующим образом:

  1. Установить бит 16 GPIOx_LCKR.
  2. Сбросить бит 16 GPIOx_LCKR.
  3. Установить бит 16 GPIOx_LCKR.
  4. Прочитать GPIOx_LCKR
  5. Повторно прочитать GPIOx_LCKR 

Регистры установки состояния линий

В отличие от привычных 8-ми битных моделей, в STM32 имеется несколько регистров, отвечающих за состояние линий порта ввода вывода. Условно они разделены на две группы – регистры порта и регистры установки отдельных битов.

Выходной регистр порта ввода/вывода

Port output data register (GPIOx_ODR) (x=A..G) 

Бит 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Поле Резерв
Бит 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Поле ODR15 ODR14 ODR13 ODR12 ODR11 ODR10 ODR9 ODR8 ODR7 ODR6 ODR5 ODR4 ODR3 ODR2 ODR1 ODR0

Данный регистр имеет разрядность 32, но используются только младшие 16 бит. Биты с 16 по 31 не используются. При записи в GPIOx_ODR какого-либо значения, это значение устанавливается на выходных линиях соответствующего порта. Биты регистра доступны только для чтения/записи. 

Входной регистр

Port input data register (GPIOx_IDR) (x=A..G)

Бит31302928272625242322212019181716Бит1514131211109876543211
Поле Резерв
Поле IDR15 IDR14 IDR13 IDR12 IDR11 IDR10 IDR9 IDR8 IDR7 IDR6 IDR5 IDR4 IDR3 IDR2 IDR1 IDR0

 Аналогично регистру выхода, регистр входа имеет толь 16 младших действующих бит из 32. Чтение GPIOx_IDR возвращает значение состояния всех линий порта. Биты регистра доступны только для чтения. 

Регистр битовых операций

Port bit set/reset register (GPIOx_BSRR) (x=A..G)

Бит31302928272625242322212019181716Бит1514131211109876543211
Поле BR15 BR14 BR13 BR12 BR11 BR10 BR9 BR8 BR7 BR6 BR5 BR4 BR3 BR2 BR1 BR0
Поле BS15 BS14 BS13 BS12 BS11 BS10 BS9 BS8 BS7 BS6 BS5 BS4 BS3 BS2 BS1 BS0

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

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

Запись в регистр производится в формате слова, при этом нулевые биты никакого действия не оказывают. Биты регистра доступны только для записи.

Регистр сброса

Port bit reset register (GPIOx_BRR) (x=A..G)

Бит31302928272625242322212019181716Бит1514131211109876543211
Поле Резерв
Поле BR15 BR14 BR13 BR12 BR11 BR10 BR9 BR8 BR7 BR6 BR5 BR4 BR3 BR2 BR1 BR0

Данный регистр производит сброс высокого уровня линии, установленной в регистре GPIOx_ODR. Задействованы только младшие 16 бит, доступных только для записи.

Еще по теме:

STM32. Работа с базовыми портами ввода/вывода. Примеры.
Первый проект на STM32 Discovery.

You have no rights to post comments

Источник: https://mcucpu.ru/index.php/stm32/82-stm32gpio

Изучаем 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);<\p>

} 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/

Программирование STM32. Часть 1. GPIO, порты ввода-вывода STM32

Недавно коллега меня подсадил на идею создания умного дома, я даже успел заказать себе десятки разных датчиков. Встал вопрос о выборе Микроконтроллера (далее МК) или платы. После некоторых поисков нашёл несколько вариантов.

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

В итоге выбирал между Atmel ATtiny (2313), Atmel ATmega (решил отказаться т.к. не смог найти за адекватные деньги), STM32 (Cortex на ядре ARM). С тинькой я уже успел побаловаться, так что взял себе STM32VL-Discovery. Это можно назвать вступлением к циклу статей по STM32.

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

Общие сведения

Микроконтроллеры семейства STM32 содержат в своём составе до семи 16-разрядных портов ввода-вывода c именами от PORTA до PORTG. В конкретной модели микроконтроллера без исключений доступны все выводы портов, общее количество которых зависит от типа корпуса и оговорено в DataSheet на соответствующее подсемейство.

Для включения в работу порта x необходимо предварительно подключить его к шине APB2 установкой соответствующего бита IOPxEN в регистре разрешения тактирования периферийных блоков RCC_APB2ENR:

RCC->APB2ENR |= RCC_APB2ENR_IOPxEN; // Разрешить тактирование PORTx.

Управление портами STM32 осуществляется при помощи наборов из семи 32-разрядных регистров:

  • GPIOx_CRL, GPIOx_CRH – задают режимы работы каждого из битов порта в качестве входа или выхода, определяют конфигурацию входных и выходных каскадов.
  • GPIOx_IDR – входной регистр данных для чтения физического состояния выводов порта x.
  • GPIOx_ODR– выходной регистр осуществляет запись данных непосредственно в порт.
  • GPIOx_BSRR – регистр атомарного сброса и установки битов порта.
  • GPIOx_BSR – регистр сброса битов порта.
  • GPIOx_LCKR – регистр блокировки конфигурации выводов.

Режимы работы выводов GPIO

Режимы работы отдельных выводов определяются комбинацией битов MODEy[1:0] и CNFy[1:0] регистров GPIOx_CRL и GPIOx_CRH (здесь и далее: x-имя порта, y- номер бита порта).

GPIOx_CRL — регистр конфигурации выводов 0…7 порта x:

Структура регистра GPIOx_CRH аналогична структуре GPIOx_CRL и предназначена для управления режимами работы старших выводов порта (биты 8…15).

Биты MODEy указанных регистров определяют направление вывода и ограничение скорости переключения в режиме выхода:

  • MODEy[1:0] = 00: Режим входа (состояние после сброса);
  • MODEy[1:0] = 01: Режим выхода, максимальная скорость – 10МГц;
  • MODEy[1:0] = 10: Режим выхода, максимальная скорость – 2МГц;
  • MODEy[1:0] = 11: Режим выхода, максимальная скорость – 50МГц.

Биты CNF задают конфигурацию выходных каскадов соответствующих выводов:

в режиме входа:

  • CNFy[1:0] = 00: Аналоговый вход;
  • CNFy[1:0] = 01: Вход в третьем состоянии (состояние после сброса);
  • CNFy[1:0] = 10: Вход с притягивающим резистором pull-up (если PxODR=1) или pull-down (если PxODR=0);
  • CNFy[1:0] = 11: Зарезервировано.

в режиме выхода:

  • CNFy[1:0] = 00: Двухтактный выход общего назначения;
  • CNFy[1:0] = 01: Выход с открытым стоком общего назначения;
  • CNFy[1:0] = 10: Двухтактный выход с альтернативной функцией;
  • CNFy[1:0] = 11: Выход с открытым стоком с альтернативной функцией.

С целью повышения помехоустойчивости все входные буферы содержат в своём составе триггеры Шмидта. Часть выводов STM32, снабженных защитными диодами, соединёнными с общей шиной и шиной питания, помечены в datasheet как FT (5V tolerant) — совместимые с напряжением 5 вольт.

Защита битов конфигурации GPIO

Для защиты битов в регистрах конфигурации от несанкционированной записи в STM32 предусмотрен регистр блокировки настроек GPIOx_LCKR
GPIOx_LCKR — регистр блокировки настроек вывода порта:

Для защиты настроек отдельного вывода порта необходимо установить соответствующий бит LCKy. После чего осуществить последовательную запись в разряд LCKK значений “1” — “0” — “1” и две операции чтения регистра LCKR, которые в случае успешной блокировки дадут для бита LCKK значения “0” и “1” . Защита настроечных битов сохранит своё действие до очередной перезагрузки микроконтроллера.

Файл определений для периферии микроконтроллеров STM32 stm32f10x.h определяет отдельные группы регистров, объединённые общим функциональным назначением (в том числе и GPIO), как структуры языка Си, а сами регистры как элементы данной структуры. Например:

GPIOC->BSRR – регистр BSRR установки/сброса порта GPIOC.
Воспользуемся определениями из файла stm32f10x.h для иллюстрации работы с регистрами ввода-вывода микроконтроллера STM32F100RB установленного в стартовом наборе STM32VLDISCOVERY:

#include “stm32F10x.h” u32 tmp; int main (void) { RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // Разрешить тактирование PORTC. GPIOC->CRH |= GPIO_CRH_MODE8; // Вывод светодиода LED4 PC8 на выход. GPIOC->CRH &=~GPIO_CRH_CNF8; // Двухтактный выход на PC8. GPIOC->CRH |= GPIO_CRH_MODE9; // Вывод светодиода LED3 PC9 на выход. GPIOC->CRH &=~GPIO_CRH_CNF9; // Двухтактный выход на PC9. GPIOA->CRL&=~GPIO_CRL_MODE0; // Кнопка “USER” PA0 – на вход. // Заблокировать настройки выводов PC8, PC9. GPIOC->LCKR = GPIO_LCKR_LCK8|GPIO_LCKR_LCK9| GPIO_LCKR_LCKK; GPIOC->LCKR = GPIO_LCKR_LCK8|GPIO_LCKR_LCK9; GPIOC->LCKR = GPIO_LCKR_LCK8|GPIO_LCKR_LCK9| GPIO_LCKR_LCKK; tmp=GPIOC->LCKR; tmp=GPIOC->LCKR; }

Запись и чтение GPIO

Для записи и чтения портов предназначены входной GPIOx_IDR и выходной GPIOx_ODR регистры данных.

Запись в выходной регистр ODR порта настроенного на вывод осуществляет установку выходных уровней всех разрядов порта в соответствии с записываемым значением. Если вывод настроен как вход с подтягивающими резисторами, состояние соответствующего бита регистра ODR активирует подтяжку вывода к шине питания (pull-up, ODR=1) или общей шине микроконтроллера (pull-down, ODR=0).

Чтение регистра IDR возвращает значение состояния выводов микроконтроллера настроенных как входы:

// Если кнопка нажата (PA0=1), установить биты порта C, иначе сбросить. if (GPIOA->IDR & GPIO_IDR_IDR0) GPIOC->ODR=0xFFFF; else GPIOC->ODR=0x0000;

Сброс и установка битов порта

Для атомарного сброса и установки битов GPIO в микроконтроллерах STM32 предназначен регистр GPIOx_BSRR.

Традиционный для архитектуры ARM способ управления битами регистров не требующий применения операции типа “чтение-модификация-запись” позволяет устанавливать и сбрасывать биты порта простой записью единицы в биты установки BS (BitSet) и сброса BR (BitReset) регистра BSRR. При этом запись в регистр нулевых битов не оказывает влияния на состояние соответствующих выводов.

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

GPIOC->BSRR=GPIO_BSRR_BS8|GPIO_BSRR_BR9; // Зажечь LED4 (PC8), погасить LED3.
GPIOC->BSRR=GPIO_BSRR_BS9|GPIO_BSRR_BR8; // Зажечь LED3 (PC9), погасить LED4.

Альтернативные функции GPIO и их переназначение (remapping)
Практически все внешние цепи специального назначения STM32 (включая выводы для подключения кварцевых резонаторов, JTAG/SWD и так далее) могут быть разрешены на соответствующих выводах микроконтроллера, либо отключены от них для возможности их использования в качестве выводов общего назначения. Выбор альтернативной функции вывода осуществляется при помощи регистров с префиксом “AFIO”_.
Помимо этого регистры AFIO_ позволяют выбирать несколько вариантов расположения специальных функций на выводах микроконтроллера. Это в частности относится к выводам коммуникационных интерфейсов, таймеров (регистры AFIO_MAPR), выводам внешних прерываний (регистры AFIO_EXTICR) и т. д.

Подробнее смотрите документы “Reference manual” на соответствующую подгруппу микроконтроллеров.

Проекты к статье:

Для управления GPIO STM32 Вы можете применить макросы написанные как альтернативу далеко не оптимальным по мнению многих библиотекам от ST: gpio_emcu.h

Дополнительный материал:

Другие части

Источник: https://ergoz.ru/programmirovanie-stm32-chast-1-gpio-portyi-vvoda-vyivoda-stm32/

STM32. Урок 2. Порты ввода/вывода

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

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

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

General Purpose Input/Output (GPIO). GPIO основной и часто применяемый способ связи с внешней средой. Порты могут работать в двух режимах: вход (прием сигнала) и выход (передача сигнала). Работают они только с логическими уровнями 0 (низкий уровень) или 1 (высокий уровень).

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

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

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

Решим первую практическую задачу: управление светодиодами и считывание состояние кнопки.
Следует отметить очень важный момент – порты микроконтроллера могут выдать ток не более 20 мА. Хотя выдать он их может, но один раз и ненадолго, до хлопка и сизого дыма;). Для подключения более мощных нагрузок следует использовать силовые ключи.

Итак, начнем. Для работы возьмем плату STM32F4 Discovery. На ней изначально установлена пользовательская кнопка, подключенная к порту PA0 и 4 светодиода, подключенные к портам PD12-PD15.

Схема подключение кнопки и светодиодов показаны на рисунке.

Резистор R1 номиналом 10кОм – «подтяжка к земле», позволяет избежать ситуации, когда порт не подключен ни к «0», ни к «1» – этого необходимо избегать, а резистор решает эту проблему. Такую подтяжку можно включить и программно, но лучше обезопасить себя так.

Резисторы R2-R5 330Ом ограничивают ток, протекающий через светодиоды. Их можно выбрать в диапазоне от 200Ом до 1кОм, все зависит от необходимой яркости.

Теперь перейдем к написанию программы. В качестве среды разработки я использую CooCox. Среда бесплатная и, на мой взгляд, удобная. Как начинать в ней работать рассказывать не буду – в интернете по ней достаточно информации, для прошивки использую STM32 ST-LINK Utility.
Для начала включаем тактирование порта A, к которому подключена кнопка:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

Теперь нужно правильно сконфигурировать порт:

//Структура содержащая настройки порта
GPIO_InitTypeDef GPIO_InitStructure;
//задаем номер вывода, если кнопка подключена, например к 6 порту, то пишем GPIO_Pin_6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
//порт будет работать как цифровой вход
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

Существует несколько вариантов режима работы порта: GPIO_Mode_IN – цифровой вход; GPIO_Mode_OUT – цифровой выход; GPIO_Mode_AF – альтернативная функция (UART и т.д.);

GPIO_Mode_AN – аналоговый режим.

//включаем подтяжку к «земле»
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;

Возможны следующие режимы «подтяжки»: GPIO_PuPd_NOPULL – без подтяжки, вывод «болтается в воздухе» GPIO_PuPd_UP – подтяжка к 3,3В

GPIO_PuPd_DOWN – подтяжка к «земле»

//вызов функции инициализации
GPIO_Init(GPIOA, &GPIO_InitStructure);

Теперь сконфигурируем выводы, к которым подключены светодиоды:

//Включаем тактирование порта D
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
//Выбираем нужные выводы
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
//Включаем режим выхода
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
//вызов функции инициализации
GPIO_Init(GPIOD, &GPIO_InitStructure);

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

while(1) { //Если кнопка нажата, то… if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1) { GPIO_SetBits(GPIOD, GPIO_Pin_12); //Подаем «1» на PD12 delay(); //Функция задержки GPIO_SetBits(GPIOD, GPIO_Pin_13); //Подаем «1» на PD13 delay(); GPIO_SetBits(GPIOD, GPIO_Pin_14); //Подаем «1» на PD14 delay(); GPIO_SetBits(GPIOD, GPIO_Pin_15); //Подаем «1» на PD15 delay(); GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //Сбрасываем все пины в «0» delay(); } }

Вот и все, программа готова. Полная версия в архиве с проектом. Работа платы показана на видео.

Теперь подробнее об использованных функциях: GPIO_ReadInputDataBit – чтение состояния выбранного порта.

Синтаксис:

GPIO_ReadInputDataBit(GPIO_TypeDef GPIOx, uint16_t GPIO_Pin);

Где GPIOx – выбранный порт, GPIO_Pin – выбранный пин. Возвращает 0 или 1.

GPIO_SetBits и GPIO_ResetBits устанавливают или сбрасывают бит выбранного порта. Синтаксис:

GPIO_SetBits(GPIO_TypeDef GPIOx, uint16_t GPIO_Pin);
GPIO_ResetBits(GPIO_TypeDef GPIOx, uint16_t GPIO_Pin);

Где GPIOx – выбранный порт, GPIO_Pin – выбранный пин.

Вот собственно и все, что нужно знать для работы с цифровыми портами. Следующая статья будет посвящена работе с UART.

Прикрепленные файлы:

Источник: http://cxem.net/mc/mc196.php

STM32 с нуля. GPIO. Порты ввода-вывода

Доброго времени суток! Сегодня мы займемся изучением GPIO! И, в первую очередь, давайте посмотрим в каких режимах могут работать порты ввода-вывода в STM32F10x. А режимов этих существует море, а именно:

  • Input floating
  • Input pull-up
  • Input-pull-down
  • Analog
  • Output open-drain
  • Output push-pull
  • Alternate function push-pull
  • Alternate function open-drain

А если по-нашему, то при работе на вход:

  • Вход – Hi-Z
  • Вход – подтяжка вверх
  • Вход – подтяжка вниз
  • Вход – аналоговый

При работе порта на выход имеем следующие варианты:

  • Выход – с открытым коллектором
  • Выход – двухтактный
  • Альтернативные функции – выход типа «с открытым коллектором»
  • Альтернативные функции – двухтактный выход

Вот кстати документация на STM32F103CB –

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

Вот, например, выводы PA9, PA10: <\p>

В столбце Default видим, какие функции будут выполнять эти пины при их настройке для работы в режиме Alternative function.

То есть, настроив эти пины соответствующим образом они из просто PA9 и PA10 превратятся в Rx и Tx для USART1. А для чего же тогда столбец Remap? А это не что иное, как очень полезная функция ремаппинга портов.

Благодаря ремапу, Tx USARTA ’а, например, может переместится с пина PA9 на PB6. Довольно часто эта  функция оказывается чертовски полезной.

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

Раз уж только что обсудили в каких режимах могут существовать выводы STM32F10x, сразу же давайте прошарим как же их можно собственно перевести в нужный режим. А для этого выделены аж два регистра – CRL и CRH.

В первом конфигурируются выводы от 0 до 7, во втором, соответственно от 8 до 15. Регистры, как вы помните, 32-разрядные. То есть на 8 выводов приходтся 32 бита – получается 4 бита на одну ножку.

Открываем даташит и видим:

Например, надо нам настроить ножку PB5. Идем в регистр GPIOB->CRL и выставляем сответствующие биты так как нам требуется (на картинке 32-х битный регистр CRL). Для PB5 это биты:

После восьмибиток может показаться все достаточно сложным и каким то корявым, но на самом деле реализовано все довольно изящно =). Посмотрим, что тут есть еще.

Выходной регистр GPIOx_ODR – напоминает регистр PORTx в AVR. Все что попадает в этот регистр сразу же попадает во внешний мир. Регистр 32-разрядный, а ножек всего 16. Как думаете, для чего используются оставшиеся 16? Все очень просто, биты регистра с 15 по 31 не используются вовсе )

Входной регистр GPIOx_IDR – аналог PINx в AVR. Структура его похожа на упомянутую структуру ODR. Все, что появляется на входе микроконтроллера, сразу же оказывается во входном регистре IDR.

Еще два полезных регистра GPIOx_BSSR и GPIOx_BRR. Они позволяют менять значения битов в регистре ODR напрямую, без использования привычных бит-масок. То есть, хочу я, например, выставить в единицу пятый бит ODR. Записываю единичку в пятый бит GPIOx_BSSR, и все, цель достигнута. Вдруг захотелось сбросить пятый бит ODR – единицу в 5 бит GPIOx_BRR и готово.

Итак, основные регистры рассмотрели, но, на самом-то деле, мы в наших примерах будем делать все иначе, используя Standard Peripheral Library. Так что лезем ковырять библиотеку. За GPIO в SPL отвечают файлы stm32f10x_gpio.h и stm32f10x_gpio.c. Открываем их оба и видим очень много непонятных цифр-букв-значков итд.

На самом деле, все очень просто и понятно. За конфигурацию портов отвечает структура GPIO_InitTypeDef.

typedef struct
{ uint16_t GPIO_Pin;             // Specifies the GPIO pins to be configured. This parameter can be any value of @ref GPIO_pins_define */
  GPIOSpeed_TypeDef GPIO_Speed;  // Specifies the speed for the selected pins. This parameter can be a value of @ref GPIOSpeed_TypeDef */
  GPIOMode_TypeDef GPIO_Mode;    // Specifies the operating mode for the selected pins. This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;

Видим, что структура имеет три поля: GPIO_PIN, GPIO_Speed и GPIO_Mode.

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

Таким образом, для настройки вывода нам всего лишь нужно объявить переменную типа структуры и заполнить ее поля нужными значениями. Все возможные значения полей тут же – в stm32f10x_gpio.h. Например,

typedef enum
{ GPIO_Mode_AIN = 0x0, GPIO_Mode_IN_FLOATING = 0x04, GPIO_Mode_IPD = 0x28, GPIO_Mode_IPU = 0x48, GPIO_Mode_Out_OD = 0x14, GPIO_Mode_Out_PP = 0x10, GPIO_Mode_AF_OD = 0x1C, GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;

Все значения уже рассчитаны создателями SPL, так что для настройки какого-нибудь вывода для работы в режиме Output push-pull надо всего лишь в соответствующей структуре задать поле: GPIO_Mode =  GPIO_Mode_Out_PP.

Ну вот, структура объявлена, поля заполнены как надо, что же дальше? Ведь мы всего лишь создали переменную. Причем тут регистры, микроконтроллеры и вообще электроника? Лезем в файл stm32f10x_gpio.c и находим там тучу различных функций для работы с STM32 GPIO.

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

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

Так что, разобраться несложно, но надо немного дружить с английским. Хотя без этого никуда;)

Отвлечемся ненадолго от портов ввода-вывода и обсудим один довольно тонкий момент. Чтобы использовать порты, либо любую другую периферию, ОБЯЗАТЕЛЬНО надо включить тактирование.

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

c и stm32f10x_rcc.h. Не забывайте добавлять их в проект.

Давайте уже перейдем к программированию. Как это принято, заставим диодик помигать ) Чтобы получше разобраться с Standard Peripheral Library немножко усложним обычное мигание диодом – будем опрашивать кнопку, и если она нажата – диод загорается, иначе – гаснет.

Запускаем Keil, создаем проект, добавляем все нужные файлы, не забываем про CMSIS. Из SPL для этого проекта нам понадобятся 4 файла, уже упомянутые выше. Создание нового проекта описано в предыдущей статье учебного курса.

Также там можно найти ссылки на библиотеки )

Итак, код:

/****************************gpio.c*********************************/
//Подключаем все нужные файлы
#include “stm32f10x.h”
#include “stm32f10x_rcc.h”
#include “stm32f10x_gpio.h”
/*******************************************************************/
//Тут будет вся инициализация всей использующейся периферии
void initAll()
{ //Объявляем переменную port типа GPIO_InitTypeDef GPIO_InitTypeDef port; //Это функция из файла stm32f10x_rcc.c, включает тактирование на GPIOA //GPIOA сидит на шине APB2
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //Про эту функцию напишу чуть ниже
    GPIO_StructInit(&port);    //Заполняем поля структуры нужными значениями    //Первый вывод – вход для обработки нажатия кнопки – PA1
    port.GPIO_Mode = GPIO_Mode_IPD;
    port.GPIO_Pin = GPIO_Pin_1; port.GPIO_Speed = GPIO_Speed_2MHz;      //А про эту функцию мы уже говорили      //Отметим только что один из параметров – указатель(!) на     //нашу структуру GPIO_Init(GPIOA, &port);     //Настраиваем вывод, на котором будет висеть диодик – PA0
    port.GPIO_Mode = GPIO_Mode_Out_PP;      port.GPIO_Pin = GPIO_Pin_0;     port.GPIO_Speed = GPIO_Speed_2MHz;      GPIO_Init(GPIOA, &port);
}
/*******************************************************************/
int main() { //Объявляем переменную для хранения состояния кнопки      uint8_t buttonState = 0;     initAll();      while(1)      {      //С помощью функции из SPL считываем из внешнего мира          //состояние кнопки          buttonState = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1);          if (buttonState == 1)         {          GPIO_SetBits(GPIOA, GPIO_Pin_0); }          else         {         GPIO_ResetBits(GPIOA, GPIO_Pin_0); } } } /****************************End of file****************************/

Кстати, возможно кто-то обратит внимание на наличие скобок {  }, несмотря на всего лишь одну инструкцию  в теле if и else. А это уже привычка) Очень рекомендуется так писать, особенно при разработке крупных проектов.

При дописывании/исправлении программы невнимательный программист может не обратить внимания на отсутствие скобок и дописать вторую инструкцию, которая, как вы понимаете, уже окажется все блока if или else. Та же тема с циклами.

Когда над проектом работает много народу, нет никаких гарантий, что кто-нибудь не окажется невнимательным, так что, чтобы не тратить минуты/часы на последующие поиски косяка, рекомендую ставить эти скобки всегда ) Хотя может, кто-то и не согласится с такой логикой.

Нажимаем F7, компилируем, и вот наша первая программа для STM готова. Вроде бы код довольно подробно откомментирован, так что поясню только пару моментов.

Функция GPIO_StructInit(&port) – принимает в качестве аргумента адрес переменной port.

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

Еще две функции, которые мы использовали:

  • GPIO_SetBits(GPIOA, GPIO_Pin_0);
  • GPIO_ResetBits(GPIOA, GPIO_Pin_0);

Ну вы и так догадались для чего они

Источник: https://microtechnics.ru/stm32-uchebnyj-kurs-gpio-porty-vvoda-vyvoda/

STM32F1. Часть 1. GPIO, порты ввода-вывода STM32

ПодробностиКатегория: STM32F1 Cortex M3Опубликовано 09.12.2010 22:00Микроконтроллеры семейства STM32 содержат в своём составе до семи 16-разрядных портов ввода-вывода c именами от PORTA до PORTG.

В конкретной модели микроконтроллера без исключений доступны все выводы портов, общее количество которых зависит от типа корпуса и оговорено в DataSheet на соответствующее подсемейство.

Для включения в работу порта x необходимо предварительно подключить его к шине APB2 установкой соответствующего бита IOPxEN в регистре разрешения тактирования периферийных блоков RCC_APB2ENR:

RCC->APB2ENR |= RCC_APB2ENR_IOPxEN; // Разрешить тактирование PORTx.

Управление портами STM32 осуществляется при помощи наборов из семи 32-разрядных регистров:

GPIOx_CRL, GPIOx_CRH – задают режимы работы каждого из битов порта в качестве входа или выхода, определяют конфигурацию входных и выходных каскадов.

GPIOx_IDR – входной регистр данных для чтения физического состояния выводов порта x.
GPIOx_ODR – выходной регистр осуществляет запись данных непосредственно в порт.
GPIOx_BSRR – регистр атомарного сброса и установки битов порта.
GPIOx_BSR – регистр сброса настроек битов порта.
GPIOx_LCKR – регистр блокировки конфигурации выводов.

§ Режимы работы выводов GPIO

Режимы работы отдельных выводов определяются комбинацией битов MODEy[1:0] и CNFy [1:0] регистров GPIOx_CRL и GPIOx_CRH (здесь и далее: x-имя порта, y- номер бита порта). GPIOx_CRL – регистр конфигурации выводов 0…7 порта x:
Структура регистра GPIOx_CRH аналогична структуре GPIOx_CRL и предназначена для управления режимами работы старших выводов порта (биты 8…15). Биты MODEy указанных регистров определяют направление вывода и ограничение скорости переключения в режиме выхода:MODEy[1:0] = 00 – Режим входа (состояние после сброса); MODEy[1:0] = 01 – Режим выхода, максимальная скорость – 10МГц; MODEy[1:0] = 10 – Режим выхода, максимальная скорость – 2МГц;

MODEy[1:0] = 11 – Режим выхода, максимальная скорость – 50МГц.

Биты CNF задают конфигурацию выходных каскадов соответствующих выводов: в режиме входа:CNFy[1:0] = 00: Аналоговый вход; CNFy[1:0] = 01: Вход в третьем состоянии (состояние после сброса); CNFy[1:0] = 10: Вход с притягивающим резистором pull-up (если PxODR=1) или pull-down (если PxODR=0);

CNFy[1:0] = 11: Зарезервировано.

в режиме выхода:CNFy[1:0] = 00: Двухтактный выход общего назначения; CNFy[1:0] = 01: Выход с открытым стоком общего назначения; CNFy[1:0] = 10: Двухтактный выход с альтернативной функцией;

CNFy[1:0] = 11: Выход с открытым стоком с альтернативной функцией.

С целью повышения помехоустойчивости все входные буферы содержат в своём составе триггеры Шмидта. Часть выводов STM32, снабженных защитными диодами, соединёнными с общей шиной и шиной питания, помечены в datasheet как FT (5V tolerant) – совместимые с напряжением 5 вольт.

§ Защита битов конфигурации GPIO

Для защиты битов в регистрах конфигурации от несанкционированной записи в STM32 предусмотрен регистр блокировки настроек GPIOx_LCKR: GPIOx_LCKR – регистр блокировки настроек вывода порта x:Для защиты настроек отдельного вывода порта необходимо установить соответствующий бит LCKy. После чего осуществить последовательную запись в разряд LCKK значений “1” – “0” – “1” и две операции чтения регистра LCKR, которые в случае успешной блокировки дадут для бита LCKK значения “0” и “1” . Защита настроечных битов сохранит своё действие до очередной перезагрузки микроконтроллера. Файл определений для периферии микроконтроллеров STM32 stm32f10x.h определяет отдельные группы регистров, объединённые общим функциональным назначением (в том числе и GPIO), как структуры языка Си, а сами регистры как элементы данной структуры. Например: GPIOC->BSRR – регистр BSRR установки/сброса порта GPIOC. Воспользуемся определениями из файла stm32f10x.h для иллюстрации работы с регистрами ввода-вывода микроконтроллера STM32F100RB установленного в стартовом наборе STM32DISCOVERY:#include “stm32F10x.h” u32 tmp; int main (void) { RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // Разрешить тактирование PORTC. GPIOC->CRH |= GPIO_CRH_MODE8; // Вывод светодиода LED4 PC8 на выход. GPIOC->CRH &=~GPIO_CRH_CNF8; // Двухтактный выход на PC8. GPIOC->CRH |= GPIO_CRH_MODE9; // Вывод светодиода LED3 PC9 на выход. GPIOC->CRH &=~GPIO_CRH_CNF9; // Двухтактный выход на PC9. GPIOA->CRL&=~GPIO_CRL_MODE0; // Кнопка “USER” PA0 – на вход. // Заблокировать настройки выводов PC8, PC9. GPIOC->LCKR = GPIO_LCKR_LCK8|GPIO_LCKR_LCK9|GPIO_LCKR_LCKK; GPIOC->LCKR = GPIO_LCKR_LCK8|GPIO_LCKR_LCK9; GPIOC->LCKR = GPIO_LCKR_LCK8|GPIO_LCKR_LCK9|GPIO_LCKR_LCKK; tmp=GPIOC->LCKR; tmp=GPIOC->LCKR;

}

Для записи и чтения портов предназначены входной GPIOx_IDR и выходной GPIOx_ODR регистры данных. Запись в выходной регистр ODR порта настроенного на вывод осуществляет установку выходных уровней всех разрядов порта в соответствии с записываемым значением.

Если вывод настроен как вход с подтягивающими резисторами, состояние соответствующего бита регистра ODR активирует подтяжку вывода к шине питания (pull-up, ODR=1) или общей шине микроконтроллера (pull-down, ODR=0).

Чтение регистра IDR возвращает значение состояния выводов микроконтроллера настроенных как входы:

// Если кнопка нажата (PA0=1), установить биты порта C, иначе сбросить.
if (GPIOA->IDR & GPIO_IDR_IDR0) GPIOC->ODR=0xFFFF; else GPIOC->ODR=0x0000;

§ Сброс и установка битов порта

Для атомарного сброса и установки битов GPIO в микроконтроллерах STM32 предназначен регистр GPIOx_BSRR. Традиционный для архитектуры ARM способ управления битами регистров не требующий применения операции типа “чтение-модификация-запись” позволяет устанавливать и сбрасывать биты порта простой записью единицы в биты установки BS (BitSet) и сброса BR (BitReset) регистра BSRR. При этом запись в регистр нулевых битов не оказывает влияния на состояние соответствующих выводов. GPIOx_BSRR – регистр сброса и установки битов порта:

GPIOC->BSRR=GPIO_BSRR_BS8|GPIO_BSRR_BR9; // Зажечь LED4 (PC8), погасить LED3.
GPIOC->BSRR=GPIO_BSRR_BS9|GPIO_BSRR_BR8; // Зажечь LED3 (PC9), погасить LED4.

§ Альтернативные функции GPIO и их переназначение (remapping)

Практически все внешние цепи специального назначения STM32 (включая выводы для подключения кварцевых резонаторов, JTAG/SWD и так далее) могут быть разрешены на соответствующих выводах микроконтроллера, либо отключены от них для возможности их использования в качестве выводов общего назначения. Выбор альтернативной функции вывода осуществляется при помощи регистров с префиксом “AFIO_”. Помимо этого регистры AFIO_ позволяют выбирать несколько вариантов расположения специальных функций на выводах микроконтроллера. Это в частности относится к выводам коммуникационных интерфейсов, таймеров (регистры AFIO_MAPR), выводам внешних прерываний (регистры AFIO_EXTICR) и т. д. Подробнее смотрите документы “Reference manual” на соответствующую подгруппу микроконтроллеров.

§ Макросы управления портами, проекты к статье

Не хочется критиковать стандартную библиотеку «STM32F10x Standard Peripherals Library» от STM, ведь то, что она есть – уже хорошо. Но некоторые операции с использованием её функций кажутся слишком громоздкими.

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

Проекты к статье:

µVision 4.13a ⇒ STM32GPIO_emcu_uV.rar

IAR ARM 6.0 ⇒ STM32GPIO_emcu_iar.rar
IAR ARM 6.21 ⇒ STM32GPIO_emcu_iar_V6.21.rar

Далее ⇒ Часть 2. Система тактирования STM32.

Источник: http://eugenemcu.nichost.ru/articles/stm32f1/126-stm32-gpio

Ссылка на основную публикацию
Adblock
detector
",css:{backgroundColor:"#000",opacity:.6}},container:{block:void 0,tpl:"
"},wrap:void 0,body:void 0,errors:{tpl:"
",autoclose_delay:2e3,ajax_unsuccessful_load:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},beforeOpen:n.noop,afterOpen:n.noop,beforeClose:n.noop,afterClose:n.noop,afterLoading:n.noop,afterLoadingOnShow:n.noop,errorLoading:n.noop},o=0,p=n([]),h={isEventOut:function(a,b){var c=!0;return n(a).each(function(){n(b.target).get(0)==n(this).get(0)&&(c=!1),0==n(b.target).closest("HTML",n(this).get(0)).length&&(c=!1)}),c}},q={getParentEl:function(a){var b=n(a);return b.data("arcticmodal")?b:(b=n(a).closest(".arcticmodal-container").data("arcticmodalParentEl"),!!b&&b)},transition:function(a,b,c,d){switch(d=null==d?n.noop:d,c.type){case"fade":"show"==b?a.fadeIn(c.speed,d):a.fadeOut(c.speed,d);break;case"none":"show"==b?a.show():a.hide(),d();}},prepare_body:function(a,b){n(".arcticmodal-close",a.body).unbind("click.arcticmodal").bind("click.arcticmodal",function(){return b.arcticmodal("close"),!1})},init_el:function(d,a){var b=d.data("arcticmodal");if(!b){if(b=a,o++,b.modalID=o,b.overlay.block=n(b.overlay.tpl),b.overlay.block.css(b.overlay.css),b.container.block=n(b.container.tpl),b.body=n(".arcticmodal-container_i2",b.container.block),a.clone?b.body.html(d.clone(!0)):(d.before("
"),b.body.html(d)),q.prepare_body(b,d),b.closeOnOverlayClick&&b.overlay.block.add(b.container.block).click(function(a){h.isEventOut(n(">*",b.body),a)&&d.arcticmodal("close")}),b.container.block.data("arcticmodalParentEl",d),d.data("arcticmodal",b),p=n.merge(p,d),n.proxy(e.show,d)(),"html"==b.type)return d;if(null!=b.ajax.beforeSend){var c=b.ajax.beforeSend;delete b.ajax.beforeSend}if(null!=b.ajax.success){var f=b.ajax.success;delete b.ajax.success}if(null!=b.ajax.error){var g=b.ajax.error;delete b.ajax.error}var j=n.extend(!0,{url:b.url,beforeSend:function(){null==c?b.body.html("
"):c(b,d)},success:function(c){d.trigger("afterLoading"),b.afterLoading(b,d,c),null==f?b.body.html(c):f(b,d,c),q.prepare_body(b,d),d.trigger("afterLoadingOnShow"),b.afterLoadingOnShow(b,d,c)},error:function(){d.trigger("errorLoading"),b.errorLoading(b,d),null==g?(b.body.html(b.errors.tpl),n(".arcticmodal-error",b.body).html(b.errors.ajax_unsuccessful_load),n(".arcticmodal-close",b.body).click(function(){return d.arcticmodal("close"),!1}),b.errors.autoclose_delay&&setTimeout(function(){d.arcticmodal("close")},b.errors.autoclose_delay)):g(b,d)}},b.ajax);b.ajax_request=n.ajax(j),d.data("arcticmodal",b)}},init:function(b){if(b=n.extend(!0,{},a,b),!n.isFunction(this))return this.each(function(){q.init_el(n(this),n.extend(!0,{},b))});if(null==b)return void n.error("jquery.arcticmodal: Uncorrect parameters");if(""==b.type)return void n.error("jquery.arcticmodal: Don't set parameter \"type\"");switch(b.type){case"html":if(""==b.content)return void n.error("jquery.arcticmodal: Don't set parameter \"content\"");var e=b.content;return b.content="",q.init_el(n(e),b);case"ajax":return""==b.url?void n.error("jquery.arcticmodal: Don't set parameter \"url\""):q.init_el(n("
"),b);}}},e={show:function(){var a=q.getParentEl(this);if(!1===a)return void n.error("jquery.arcticmodal: Uncorrect call");var b=a.data("arcticmodal");if(b.overlay.block.hide(),b.container.block.hide(),n("BODY").append(b.overlay.block),n("BODY").append(b.container.block),b.beforeOpen(b,a),a.trigger("beforeOpen"),"hidden"!=b.wrap.css("overflow")){b.wrap.data("arcticmodalOverflow",b.wrap.css("overflow"));var c=b.wrap.outerWidth(!0);b.wrap.css("overflow","hidden");var d=b.wrap.outerWidth(!0);d!=c&&b.wrap.css("marginRight",d-c+"px")}return p.not(a).each(function(){var a=n(this).data("arcticmodal");a.overlay.block.hide()}),q.transition(b.overlay.block,"show",1*")),b.overlay.block.remove(),b.container.block.remove(),a.data("arcticmodal",null),n(".arcticmodal-container").length||(b.wrap.data("arcticmodalOverflow")&&b.wrap.css("overflow",b.wrap.data("arcticmodalOverflow")),b.wrap.css("marginRight",0))}),"ajax"==b.type&&b.ajax_request.abort(),p=p.not(a))})},setDefault:function(b){n.extend(!0,a,b)}};n(function(){a.wrap=n(document.all&&!document.querySelector?"html":"body")}),n(document).bind("keyup.arcticmodal",function(d){var a=p.last();if(a.length){var b=a.data("arcticmodal");b.closeOnEsc&&27===d.keyCode&&a.arcticmodal("close")}}),n.arcticmodal=n.fn.arcticmodal=function(a){return e[a]?e[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?void n.error("jquery.arcticmodal: Method "+a+" does not exist"):q.init.apply(this,arguments)}}(jQuery)}var debugMode="undefined"!=typeof debugFlatPM&&debugFlatPM,duplicateMode="undefined"!=typeof duplicateFlatPM&&duplicateFlatPM,countMode="undefined"!=typeof countFlatPM&&countFlatPM;document["wri"+"te"]=function(a){let b=document.createElement("div");jQuery(document.currentScript).after(b),flatPM_setHTML(b,a),jQuery(b).contents().unwrap()};function flatPM_sticky(c,d,e=0){function f(){if(null==a){let b=getComputedStyle(g,""),c="";for(let a=0;a=b.top-h?b.top-h{const d=c.split("=");return d[0]===a?decodeURIComponent(d[1]):b},""),c=""==b?void 0:b;return c}function flatPM_testCookie(){let a="test_56445";try{return localStorage.setItem(a,a),localStorage.removeItem(a),!0}catch(a){return!1}}function flatPM_grep(a,b,c){return jQuery.grep(a,(a,d)=>c?d==b:0==(d+1)%b)}function flatPM_random(a,b){return Math.floor(Math.random()*(b-a+1))+a}