STM32 с нуля. GPIO. Использование портов ввода-вывода.
image

В 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, которая содержит таблицу с описанием альтернативных функций для каждого вывода микроконтроллера. Ссылку на документацию можно добавить отдельным предложением. Документацию можно найти по этой ссылке: STM32F103CB datasheet. Вот, например, выводы PA9, PA10:

image

В столбце Default видим, какие функции будут выполнять эти пины при их настройке для работы в режиме Alternative function. То есть, настроив эти пины соответствующим образом они из просто PA9 и PA10 превратятся в Rx и Tx для USART1. А для чего же тогда столбец Remap? А это не что иное, как очень полезная функция ремаппинга портов. Благодаря ремапу, Tx USARTA ’а, например, может переместится с пина PA9 на PB6. Довольно часто эта функция оказывается невероятно полезной.

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

Раз уж только что обсудили в каких режимах могут существовать выводы STM32F10x, сразу же давайте разберемся, как же их можно собственно перевести в нужный режим. А для этого выделены два регистра – CRL и CRH. В первом конфигурируются выводы от 0 до 7, во втором, соответственно от 8 до 15. Регистры, как вы помните, 32-х разрядные. То есть на 8 выводов приходится 32 бита - получается 4 бита на одну ножку. Открываем даташит и видим:

image

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

image

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

  • Выходной регистр 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:

image

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

image

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

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

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

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

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

image

Функция GPIO_StructInit(&port) – принимает в качестве аргумента указатель на переменную port. Эта функция заполняет поля структуры, переданной ей в качестве аргумента значениями по умолчанию.

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

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

Автор: Aveal

Микроконтроллер STM32

Одна из линеек микроконтроллеров, которые производит компания STMicroelectronics.

Применяемость

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