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.

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

  • Урок_2.rar (135 Кб)

Теги: