STM32F3 и STM32F4 GPIO.
Ранее на сайте уже была опубликована статья о том как конфигурировать выводы STM32, она посвящалась микроконтроллерам 100 серии, хотя явно об этом в статье не говорилось.
В этой статье речь пойдёт о микроконтроллерах 300 и 400 серии.
Структурная схема вывода выглядит следующим образом.
Каждый вывод МК может быть сконфигурирован в одно из состояний.
На всякий случай поясню какое битовое поле за, что отвечает.
MODER определяет режим работы вывода
00: режим входа(после сброса)
01: режим выхода
10: режим альтернативных функций
11: аналоговый режим
OTYPER определяет тип выхода
0: двухтактный выход или push-pull сокращено PP(после сброса)
1: открытый сток или open-drain сокращено OD
OSPEEDR определяет частоту переключения выхода
x0: 2 MHz
01: 10 MHz
11: 50 MHz
PUPDR определяет подтяжку вывода
00: без подтяжки
01: подтяжка к плюсу питания или pull-up сокращено PU
10: подтяжка к земле или pull-down сокращено PD
11: зарезервирован
Надо отметить, что большинство выводов после сброса настроены как плавающий вход
(input floating), кроме выводов, отвечающих за отладку, они настроены как вход с подтяжкой.
PA15: JTDI in pull-up
PA14: JTCK/SWCLK in pull-down
PA13: JTMS/SWDIO in pull-up
PB4: NJTRST in pull-up
PB3: JTDO/TRACESWO
Регистры ODR, BRR и IDR работают также как и в сотой серии, а регистр BSRR, он 32-битный, разделен на две части, младшая служит для установки битов — BSRRL, старшая для сброса — BSRRH.
Осталось самое интересное, разобраться как настроить вывод, чтобы он выполнял альтернативные функции.
У микроконтроллеров этих серий надо конкретно указывать какая альтернативная функция будет соответствовать данному выводу. Настраиваются альтернативные функции с помощью двух регистров AFRL и AFRH. AFRL отвечает за настройку 8 младших выводов порта, AFRH за настройку 8 старших выводов порта, то есть с 8 по 15. Альтернативные функции вывода можно найти в даташите на МК.
Например, мы хотим выводу PD12 назначить функцию первого канала четвёртого таймера (TIM4_CH1). Для этого мы должны записать номер альтернативной функции в AFRH5.( так как выводы с 0 по 7 настраиваются в AFRL, то за настройку 12 вывода отвечает AFRH(12 - 7 = 5).
Номер альтернативной функции соответствует номеру столбца, в данном случае AF2, значит в AFRH5 надо записать двойку.
Перед тем как переходить к реализации надо отметить, что под настройку каждого вывода в регистрах AFR выделено 4 бита.
С настройкой выводов разобрались, теперь немного дополнительной информации. Если генератор HSE и LSE выключены, выводы к которым подключаются резонаторы могут использоваться как обычные выводы. Если же МК тактируется от внешнего источника(для этого нужен только один вывод), свободный вывод можно использовать для своих целей. Также надо отметить, что любой вывод может быть настроен на внешнее прерывание.
В общем, ничего сложно, а в следующей статье опишу как можно использовать режим open-drain и почему его не может заменить push-pull.
В этой статье речь пойдёт о микроконтроллерах 300 и 400 серии.
Структурная схема вывода выглядит следующим образом.
Каждый вывод МК может быть сконфигурирован в одно из состояний.
На всякий случай поясню какое битовое поле за, что отвечает.
MODER определяет режим работы вывода
00: режим входа(после сброса)
01: режим выхода
10: режим альтернативных функций
11: аналоговый режим
OTYPER определяет тип выхода
0: двухтактный выход или push-pull сокращено PP(после сброса)
1: открытый сток или open-drain сокращено OD
OSPEEDR определяет частоту переключения выхода
x0: 2 MHz
01: 10 MHz
11: 50 MHz
PUPDR определяет подтяжку вывода
00: без подтяжки
01: подтяжка к плюсу питания или pull-up сокращено PU
10: подтяжка к земле или pull-down сокращено PD
11: зарезервирован
//Полагаем что выводы после сброса в режиме плавающего входа
//разрешаем тактирование порта A
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
//двухтактный выход 10MHz
GPIOA->MODER |= GPIO_MODER_MODER0_0;
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_0;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0_0;
//выход с открытым стоком 2MHz с подтяжкой к питанию
GPIOA->MODER |= GPIO_MODER_MODER0_0;
GPIOA->OTYPER |= GPIO_OTYPER_OT_0;
GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR0;
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR0_0;
//альтернативная ф-ция, двухтактный выход без подтяжки, 50 MHz
GPIOA->MODER |= GPIO_MODER_MODER0_1;
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_0;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR0;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0;
//альтернативная ф-ция, выход с открытым стоком с подтяжкой к питанию, 50 MHz
GPIOA->MODER |= GPIO_MODER_MODER0_1;
GPIOA->OTYPER |= GPIO_OTYPER_OT_0;
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR0_0;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0;
//вход с подтяжкой к +
GPIOA->MODER &= ~ GPIO_MODER_MODER0;
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR0_0;
//вход с подтяжкой к -
GPIOA->MODER &= ~ GPIO_MODER_MODER0;
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR0_1;
//аналоговый режим
GPIOA->MODER |= GPIO_MODER_MODER0;
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR0;
Надо отметить, что большинство выводов после сброса настроены как плавающий вход
(input floating), кроме выводов, отвечающих за отладку, они настроены как вход с подтяжкой.
PA15: JTDI in pull-up
PA14: JTCK/SWCLK in pull-down
PA13: JTMS/SWDIO in pull-up
PB4: NJTRST in pull-up
PB3: JTDO/TRACESWO
Регистры ODR, BRR и IDR работают также как и в сотой серии, а регистр BSRR, он 32-битный, разделен на две части, младшая служит для установки битов — BSRRL, старшая для сброса — BSRRH.
//установить все выходы порта в 1
GPIOA->ODR = 0xFFFF;
//сбросить нулевой бит порта А
GPIOA->BRR = GPIO_BRR_BR_0;
//установить нулевой бит
GPIOA->BSRRL = GPIO_BSRR_BS_0;
//сбросить нулевой бит
GPIOA->BSRRH = GPIO_BSRR_BS_0;//скорее всего заработало именно так потому,
//что регистр разделен на две части, думал что заработает так
//GPIOA->BSRRH = GPIO_BSRR_BR_0;
//проверить значение нулевого вывода порта А
if(GPIOA->IDR & GPIO_IDR_0)
Осталось самое интересное, разобраться как настроить вывод, чтобы он выполнял альтернативные функции.
У микроконтроллеров этих серий надо конкретно указывать какая альтернативная функция будет соответствовать данному выводу. Настраиваются альтернативные функции с помощью двух регистров AFRL и AFRH. AFRL отвечает за настройку 8 младших выводов порта, AFRH за настройку 8 старших выводов порта, то есть с 8 по 15. Альтернативные функции вывода можно найти в даташите на МК.
Например, мы хотим выводу PD12 назначить функцию первого канала четвёртого таймера (TIM4_CH1). Для этого мы должны записать номер альтернативной функции в AFRH5.( так как выводы с 0 по 7 настраиваются в AFRL, то за настройку 12 вывода отвечает AFRH(12 - 7 = 5).
Номер альтернативной функции соответствует номеру столбца, в данном случае AF2, значит в AFRH5 надо записать двойку.
Перед тем как переходить к реализации надо отметить, что под настройку каждого вывода в регистрах AFR выделено 4 бита.
//включаем тактирование порта и таймера
RCC->AHBENR |= RCC_AHBENR_GPIODEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
//альтернативная ф-ция push-pull без подтяжки, 50МНz
GPIOD->MODER |= GPIO_MODER_MODER12_1;//
GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR12;
GPIOD->PUPDR &= ~GPIO_PUPDR_PUPDR12;
//назначаем 12 выводу альтернативную функцию
GPIOD->AFR[1] |= (0x02<<4*4);
С настройкой выводов разобрались, теперь немного дополнительной информации. Если генератор HSE и LSE выключены, выводы к которым подключаются резонаторы могут использоваться как обычные выводы. Если же МК тактируется от внешнего источника(для этого нужен только один вывод), свободный вывод можно использовать для своих целей. Также надо отметить, что любой вывод может быть настроен на внешнее прерывание.
В общем, ничего сложно, а в следующей статье опишу как можно использовать режим open-drain и почему его не может заменить push-pull.
Похожие статьи