Программирование ARM Программное управление ножками STM32 Thu, November 21 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


Программное управление ножками 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 использоваться будет очень редко.

STM32F407-LQFP144-GPIO-pinout

Любая ножка порта GPIO может быть настроена в одной из четырех возможных конфигураций:

• Input (вход): Floating (плавающий вход с высоким входным сопротивлением, ничем не нагруженный), Pull-up (с верхним нагрузочным резистором), Pull-down (с нижним нагрузочным резистором).
• Output (выход): Push-Pull двухтактный ключ (Pull-up с верхней нагрузкой, Pull-down с нижней нагрузкой или no Pull просто двухтактный выход), Open Drain открытый сток (Pull-up, Pull-down или no Pull). В режиме выхода может быть запрограммирована скорость работы порта: 2 МГц, 25 МГц, 50 МГц или 100 МГц.
• Alternate Function (альтернативная функция): Push-Pull (Pull-up, Pull-down или no Pull), Open Drain (Pull-up, Pull-down или no Pull).
• Analog (аналоговая линия): этот режим необходим, когда вывод используется как канал ADC (АЦП) или выход DAC (ЦАП).

Во время активного сигнала сброса и сразу после его окончания все альтернативные функции на выводах портов не активны (за исключением выводов, задействованных под JTAG), и все порты оказываются сконфигурированными как плавающие входы с высоким сопротивлением.

Выводы генератора LSE (OSC32_IN и OSC32_OUT) могут использоваться как GPIO (PC14 и PC15 соответственно), если генератор LSE выключен. LSE имеет приоритет перед функцией GPIO.

Выводы генератора HSE (OSC_IN и OSC_OUT) могут использоваться как GPIO (PH0 и PH1), когда генератор HSE выключен (основной кварцевый генератор не используется, что бывает очень редко). HSE имеет приоритет над функцией GPIO.

Чтобы порт начал работать в режиме программного ввода/вывода, нужно 2 вещи: разрешить его тактирование, и настроить параметры порта.

[Настройка тактирования порта]

Чтобы порт GPIOx начал работать, и можно было программно управлять состоянием его ножек, нужно включить тактирование порта. Каждый из портов GPIOx подключен к ядру микроконтроллера через шину AHB1, и для управления включения тактирования в нормальном режиме работы служит регистр RCC_AHB1ENR (описание его бит см. [1]). 

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
Res. OTG
HSULPI
EN
OTG
HS
EN
ETH
MACPTP
EN
ETH
MACRX
EN
ETH
MACTX
EN
ETH
MAC
EN
Res. DMA2
EN
DMA1
EN
CCM
DATARAM
EN
Res. BKP
SRAM
EN
Res.
rw rw rw rw rw rw rw rw rw rw
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Reserved CRCEN Reserved GPIOI
EN
GPIOH
EN
GPIOG
EN
GPIOF
EN
GPIOE
EN
GPIOD
EN
GPIOC
EN
GPIOB
EN
GPIOA
EN
rw rw rw rw rw rw rw rw rw rw

Например, чтобы пользоваться ножкой 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, разрешение тактирования периферийных устройств.
2. Olimex STM32-P407.
3STM32: аббревиатуры и термины.

 

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


Защитный код
Обновить

Top of Page