Top.Mail.Ru

STM32 и GPIO. Настройка портов ввода-вывода в STM32CubeMx.

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

Не пропустите первую статью по STM32CubeMx - ссылка.

Я буду использовать отладочную плату STM32F4Discovery, ну и, соответственно, проект будет под STM32F4. В качестве среды разработки - IAR. Но на самом деле существенной разницы в использовании CubeMx при работе с STM32F4 или, например, STM32F1 нет.

Итак, сегодня у нас цель запустить GPIO при помощи кода, сгенерированного STM32CubeMx, поэтому поставим себе какую-нибудь простенькую задачу. На STM32F4Discovery у нас в наличии одна пользовательская кнопка и четыре светодиода. Давайте при нажатой кнопке будем зажигать зеленый и синий диоды, а при не нажатой - красный и оранжевый. К выводам микроконтроллера подключено все следующим образом:

Светодиоды на плате STM32F4Discovery.

Исходя из данной информации нам необходимо настроить выводы PD12, PD13, PD14 и PD15 на работу в режиме выхода, а PA0 надо настроить в качестве входа. Режим работы портов можно задавать банальнейшим образом кликая на них и выбирая необходимый пункт меню:

Настройка GPIO в STM32CubeMx

Пока ничего сложного. Обратите внимание, что у меня активны еще и выводы PA13 и PA14, которые используются для программатора ST-Link. Его также надо обязательно активировать в случае необходимости в соответствующем пункте:

SWD

Далее идем на вкладку "Project Manager" и там сохраняем базовые настройки проекта, а именно его имя, путь для сохранения сгенерированных файлов, а также выбираем IDE, для которой необходимо создать файлы проекта. В моем случае это IAR (EWARM):

Настройки проекта в STM32CubeMx

На этом подготовительный этап заканчивается, и мы можем переходить к генерации кода. И этап этот также очень прост - нажимаем на соответствующую кнопку "Generate Code" в правом верхнем углу программы. В папке, которую мы указали в настройках проекта, теперь появились файлы с исходным кодом, а также файлы проекта. Собственно, теперь мы можем открыть и собрать сгенерированный проект в выбранной IDE.

Таким образом, CubeMx не просто сгенерировал код, также был создан проект, в котором уже прописаны все пути ко всем нужным файлам, а также выбранный способ отладки (ST-Link) и остальные сопутствующие настройки. Единственное, что в данном случае не может сделать STM32CubeMx - это за нас решить задачу с мигающими диодами. Так что сейчас мы добавим пару строк кода в файл main.c и проверим наш проект на практике.

Как вы помните, CubeMx не использует SPL, ее место заняла библиотека HAL, поэтому функции будут отличаться от тех, которые мы привыкли использовать в проектах с SPL:

int main(void)
{
	/* USER CODE BEGIN 1 */

	/* USER CODE END 1 */

	/* MCU Configuration----------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();

	/* Configure the system clock */
	SystemClock_Config();

	/* Initialize all configured peripherals */
	MX_GPIO_Init();

	/* USER CODE BEGIN 2 */

	/* USER CODE END 2 */

	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1)
	{
		/* USER CODE END WHILE */
		
		/* USER CODE BEGIN 3 */
		GPIO_PinState currentButtonState = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

		if (currentButtonState == GPIO_PIN_RESET)
		{
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
		}
		else
		{
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET);
			HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
		}
	}
	/* USER CODE END 3 */
}

По итогу все оказывается несложно, первым делом в цикле while(1) анализируем состояние кнопки:

GPIO_PinState currentButtonState = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

Если кнопка нажата (currentButtonState == 0, поскольку кнопка замыкает на землю), то гасим красный и оранжевый (PD13, PD14) и зажигаем зеленый и синий светодиоды (PD12, PD15):

if (currentButtonState == GPIO_PIN_RESET)
{
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
}	

В случае ненажатой кнопки все наоборот. Прошиваем программу в микроконтроллер и видим, что все работает именно так как и должно. В принципе, в такой простой задаче не особо видны преимущества использования такого мощного инструмента как STM32CubeMx, но нашей целью было, в первую очередь, сделать пример для работы с GPIO, и с этой задачей мы справились на все 100 процентов. Так что на сегодня на этом все, скоро продолжим 🤝

Подписаться
Уведомить о
guest

42 комментариев
Старые
Новые
Межтекстовые Отзывы
Посмотреть все комментарии
Арчил
Арчил
8 лет назад

Добрый день, спасибо за уроки! Раньше Вы использовали Кеил, сейчас ИАР. С чем это связанно? Возможно Вы считаете, надо уметь работать во всех средах?

Арчил
Арчил
8 лет назад

Понятно, мне тоже думается, что среда не самое главное. Есть ли у Вас опыт подключения stm32 к андроид устройству, типа io ? Странно то, что как бы эта тема мало кому интересна, практически нет информации.

Арчил
Арчил
8 лет назад

То что нужно. Вообще очень интересны вопросы коммуникации discoveryf4 с внешним миром (тот же Bluetooth, wifi, usb-android и т.д.). Тот же андроид, в принципе не так и сложно сделать программу там, а вот управлять stm-мом из нее - было бы круто. Так что - ждем.

lex
lex
8 лет назад

Добрый день. Что может быть, сгенерированый cubeMX проект(keil 5) шьется в чип, а дальше чип виснет(st-link не видит его ). Пробывал на f100 VL discovery и 103с8. Код на основе SPL работает нормально.

Marat Galimov
Marat Galimov
Ответ на комментарий  lex
7 лет назад

У STM32CubeMX есть прикол при создании проекта для серии STM32F1 - от отрубает по умолчанию интерфейсы отладки JTAG и SWD. В итоге, генерируешь проект, шьешь из под Keil uVision 5, первый раз прошиваешь, а дальше не шьется.

==== Избежание проблемы ====

Чтобы избежать этой проблемы, при создании проекта в STM32CubeMX нужно сделать следующее: Вкладка Pinout ⇒ Configuration ⇒ Peripherals ⇒ SYS ⇒ Debug ⇒ Из выпадающего списка выбрать подходящее значение (все кроме No Debug)

==== Ликвидация последствий ====

Необходимо сделать очистку чипа (Erase Chip) через режим (Mode) Connect Under Reset (подключение при сбросе / соединение из-под ресета). Этот режим позволяет подключиться к микроконтроллеру до начала выполнения программы. Чтобы прошить микроконтроллер в данном режиме, нужно на вывод сброса микроконтроллера (NRST) подать низкий уровень (или соединить вывод с землей), запустить прошивку и сразу убрать низкий уровень с NRST.

Это делается через любую внешнюю программу для прошивки программатором ST-LINK, например:
1) STM32 ST-LINK utility (http://www.st.com/en/embedded-software/stsw-link004.html);
2) ST Visual Programmer STM32 (http://www.st.com/en/development-tools/stvp-stm32.html);

PS. Стандартные грабли, на которые все наступают, кто решает начать работать с STM32CubeMX.

lex
lex
8 лет назад

странно !?? После включения-выключения отладки во вкладке SYS все заработало нормально.

AuguR
AuguR
8 лет назад

А в какой вкладке SYS? Просто у меня тоже самое.

Master
Master
8 лет назад

Супер!!! на Кейл мю4 всё завелось с пол-оборота, года два-три назад всё было намного сложнее. Надеюсь будет много статей конкретно по Кубу - Дискавери4... спасибо за статью.

LEV
LEV
7 лет назад

Здравствуйте. Спасибо за Ваши статьи, очень интересно и познавательно. По использованию Cube возник вопрос. Пытаюсь задействовать freeRTOS сгенерированную с помощью Cube, при попытке создать задачу и запустить шедулер ничего не выходит, никаких действий задача не выполняет (зажечь светодиод в моем случае). Подскажите в чем может быть причина? Я так догадываюсь, что не туда в функции main вставляю код создания задачи и запуска шедулера и возможно саму задачу (функцию). Но без использования Cube таких проблем никогда невозникало.

Андрей
Андрей
7 лет назад

Добрый день. Спасибо за ваши уроки.
С кнопкой у меня все работает. Теперь стоит задача организовать параллельную передачу данных (8 бит) с мелкосхемы АЦП на PORTB STM32. В HALе есть только прием с одного пина (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);), а как сделать чтение всего порта или половины порта. Подскажите пожалуйста, а то я уже запутался.

Андрей
Андрей
Ответ на комментарий  Aveal
7 лет назад

Спасибо большое. С регистром все работает. А побитно слишком муторно все биты паковать в байт. Придется регистром пользоваться, хотя хотелось бы функцией пользоваться, которой почему-то в HALе нет.

Андрей
Андрей
Ответ на комментарий  Aveal
7 лет назад

Засранцы они))

Vladimir
Vladimir
Ответ на комментарий  Андрей
5 лет назад

"они" может и "засранцы", но вам-то написать свою функцию в, которой прочитать регистр IDR порта GPIOA
"облом"?

максим
максим
6 лет назад

Почему вы использовали переменную для состояния кнопки uint8_t?
Есть что;то типа boolean? Извините, я к stm сейчас только активно приглядываюсь)))

максим
максим
Ответ на комментарий  Aveal
6 лет назад

А boolean в stm используется?

Так мало информации для русскоязных пользователей(((

Благодаря только таким статьям как ваша и собираем по крупице!
Спасибо за труды!

Andriy
Andriy
5 лет назад

Доброго дня! Спасибо за урок, очень полезно для начинающего. Прошу пояснить одну неясную вещь. Я научился проверять состояние входа. Но, если этого требует логика программы, можно ли проверять состояние выхода? Допустим, мне нужно установить выход в 1, нужно ли проверять, не был ли он уже установлен в 1 ранее, и как это сделать средствами HAL?
Заранее спасиобо )))

Andriy
Andriy
Ответ на комментарий  Aveal
5 лет назад

Простите, прошу таки пояснить - иногда в главном цикле идет проверка условия, и, при его выполнении, установка вывода в нужное состояние. Бывает, что вывод уже в нужном состоянии. Я полагал, что есть смысл проверить это, и не задавать его еще раз (

Andriy
Andriy
Ответ на комментарий  Aveal
4 лет назад

Прошло немало времени. Вот, появилась такая необходимость на практике. В процессе работы, при открытии соленоида, должен начать работать счетчик наработки. Есть решение - присвоение какого-то значения глобальной переменной в процессе подачи сигнала на выход МК, для открытия соленоида, а затем, из прерывания таймера - отслеживать значение этой глобальной переменной. Но вариант проверки состояния выхода кажется более предпочтительным

Vladimir
Vladimir
5 лет назад

Большое спасибо за полезные уроки и главное очень грамотно подобранные и "не перегруженные" лишним примеры.
К GubeMx специально не приближался пока не поработал с CMSIS. Теперь ваши уроки, как говорят, "зашли".
Правда, как мне показалось, они датированы не позже 2015 (хотя, возможно, я еще не все "посетил").
Вы их продолжаете?
В любом случае благодарю и буду рекомендовать другим.

sWin
sWin
5 лет назад

У меня некорректно работает
Нажатие то срабатывает то нет.
Дребезг идет
Камень STM32F030R8, мама XNUCLEO R8
У Вас, наверно, кнопки на маме хорошие, с аппаратным антидребезгом?
Мне пришлось извратиться, отслеживать в цикле состояние кнопки, пока она "не успокоится"...

Алексей
Алексей
1 год назад

Это урок, или я не туда попал!
всё понятно сказано, и в конце крэш.
// - прошиваем программу в микроконтроллер и видим...........
вот человек в первый раз установил пакет CUBE в котором есть отдельная софтина -programmer, В статье не сказано, чем шить и как, программатором или идешкой.
пошёл дальше искать на просторах сети ибо хрен знает почему, но у меня компеляция проходит, ST-link обновить могу, а вот прошить не выходит, ошибка отсутствия каког то файла.

Алексей
Алексей
1 год назад

О, не ожидал,что так быстро ответите. Может тогда подскажите, в какую сторону копать.
выдаёт при попытке прошить это-

Could not determine GDB version using command: arm-none-eabi-gdb --version
arm-none-eabi-gdb: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory
Спасибо.

Алексей
Алексей
Ответ на комментарий  Aveal
1 год назад

Linux

Алексей
Алексей
Ответ на комментарий  Aveal
1 год назад

Спасибо, думаю разберусь.
Да, забыл, благодарю за статьи, многое встало на свё место в голове моей!!

Алексей
Алексей
Ответ на комментарий  Aveal
1 год назад

Дааааа, простая установка файла помогла!!!
Теперь я вашь читатель постоянный!!!

42
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x