STM32F3 и STM32F4 GPIO.

STM32F3 и STM32F4 GPIO.

Ранее на сайте уже была опубликована статья о том как конфигурировать выводы STM32, она посвящалась микроконтроллерам 100 серии, хотя явно об этом в статье не говорилось.
В этой статье речь пойдёт о микроконтроллерах 300 и 400 серии.
Каждый вывод МК может быть сконфигурирован в одно из состояний.
STM32F3 и STM32F4 GPIO.

На всякий случай поясню какое битовое поле за, что отвечает.

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;	
		GPIOA->PUPDR |= GPIO_PUPDR_PUPDR0_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. Альтернативные функции вывода можно найти в даташите на МК.
STM32F3 и STM32F4 GPIO.

Например, мы хотим выводу PD12 назначить функцию первого канала четвёртого таймера (TIM4_CH1). Для этого мы должны записать номер альтернативной функции в AFRH5.( так как выводы с 0 по 7 настраиваются в AFRL, то за настройку 12 вывода отвечает AFRH(12 - 7 = 5).
Номер альтернативной функции соответствует номеру столбца, в данном случае AF2, значит в AFRH5 надо записать двойку.

Перед тем как переходить к реализации надо отметить, что под настройку каждого вывода в регистрах AFR выделено 4 бита.
STM32F3 и STM32F4 GPIO.


       //включаем тактирование порта и таймера
	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.
Похожие статьи
комментарии
0