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

Во втором уроке цикла, посвященного работе с микроконтроллерами STM32, речь пойдет о портах ввода/вывода.
Порты микроконтроллера позволяют взаимодействовать с внешними устройствами, начиная от светодиода и кнопки и заканчивая более сложными устройствами: дисплеями, GPS и GSM модемами и так далее. Также порты позволяют организовать связь с другими устройствами, например с компьютером.

General Purpose Input/Output (GPIO). GPIO основной и часто применяемый способ связи с внешней средой. Порты могут работать в 2-х режимах: вход (прием сигнала) и выход (передача сигнала). Работают они лишь с логическими уровнями 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.


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

Добавить комментарий

Ваш адрес email не будет опубликован.