Программное управление ножками STM32 |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
В этой статье будет рассмотрено программное управление выводами портов STM32 на примере микроконтроллера STM32F407 в корпусе LQFP144 (такой микроконтроллер установлен на платах Olimex STM32-E407 и STM32-P407 [2]). Непонятные термины и сокращения см. в словарике [3]. [Обзор выводов GPIO] У микроконтроллера STM32F407 всего имеется семь 16-выводных портов: GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG (под GPIOx подразумеваются все эти порты). Они распределены по корпусу кристалла, как показано на рисунке. Также есть еще и порт GPIOH, но у него в корпусе LQFP144 представлены только 2 ножки, и те задействованы под кварцевый резонатор, так что скорее GPIOH использоваться будет очень редко. Любая ножка порта GPIO может быть настроена в одной из четырех возможных конфигураций: • Input (вход): Floating (плавающий вход с высоким входным сопротивлением, ничем не нагруженный), Pull-up (с верхним нагрузочным резистором), Pull-down (с нижним нагрузочным резистором). Во время активного сигнала сброса и сразу после его окончания все альтернативные функции на выводах портов не активны (за исключением выводов, задействованных под JTAG), и все порты оказываются сконфигурированными как плавающие входы с высоким сопротивлением. Выводы генератора LSE (OSC32_IN и OSC32_OUT) могут использоваться как GPIO (PC14 и PC15 соответственно), если генератор LSE выключен. LSE имеет приоритет перед функцией GPIO. Чтобы порт начал работать в режиме программного ввода/вывода, нужно 2 вещи: разрешить его тактирование, и настроить параметры порта. [Настройка тактирования порта] Чтобы порт GPIOx начал работать, и можно было программно управлять состоянием его ножек, нужно включить тактирование порта. Каждый из портов GPIOx подключен к ядру микроконтроллера через шину AHB1, и для управления включения тактирования в нормальном режиме работы служит регистр RCC_AHB1ENR (описание его бит см. [1]).
Например, чтобы пользоваться ножкой PA3 как портом ввода/вывода, нужно разрешить тактирование GPIOA, для чего в разряд GPIOAEN надо записать единицу. Для этой цели служат удобные библиотечные функции (в этом примере разрешено тактирование порта GPIOA): RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); [Управление портом как выходом] Для того, чтобы можно было начать управлять выводом, переводя его в состояние лог. 0 или лог. 1, порт надо настроить. Пример настройки порта PF6 как выхода: /* Разрешить тактирование GPIOF */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); /* Конфигурирование ножки PF6, туда подключен светодиод STAT1 платы разработчика Olimex STM32-P407 */ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOF, &GPIO_InitStructure); После того, как порт настроен, можно его программно переключать в любое нужное состояние. Для переключения порта служат регистры BSRRL и BSRRH, пример: /* Бесконечный цикл мигания светодиодом STAT1 */ while(1) { GPIOF->BSRRL = GPIO_Pin_6; //STAT==1, светодиод горит Delay(3000000L); GPIOF->BSRRH = GPIO_Pin_6; //STAT==0, светодиод погас Delay(3000000L); } Для управления ножками можно также применять удобные функции GPIO_SetBits и GPIO_ResetBits. [Чтение состояния порта как входа] Получить текущее состояние ножки порта, работающей в режиме входа, можно с помощью функции GPIO_ReadInputDataBit(). Но для начала нужно соответствующие ножки настроить как входы, и разрешить тактирование порта. Вот пример настройки портов для чтения джойстика платы Olimex STM32-P407 [2]: /* Разрешить тактирование GPIOG, туда подключены контакты джойстика. */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); /* Конфигурирование ножек джойстика платы разработчика Olimex STM32-P407. * PG6 RIGHT * PG7 UP * PG8 DOWN * PG11 LEFT * PG15 CENT */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_Init(GPIOG, &GPIO_InitStructure); Как опрашивать состояние порта: if(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_15)) { //сюда попадаем, если с входа прочитана лог. 1. ... } [Ссылки] 1. STM32F407, разрешение тактирования периферийных устройств. |