Пример из текущего проекта
/* void pincfg_alternate(GPIO_TypeDef* gpio, PIN pin, AF af, OTYPE otype, OSPEED ospeed, PULL pull)
* Описание: Настройка пина на альтернативную функцию.
* Параметры: gpio - порт,
* pin - номер ножки,
* af - альтернативная функция
* otype - тип выхода,
* ospeed - скорость пина,
* pull - тип подтяжки.
* Note: По-умолчанию пин настроен на цифровой вход.
*/
void GPIO::pincfg_alternate(GPIO_TypeDef* gpio, PIN pin, AF af, OTYPE otype, OSPEED ospeed, PULL pull)
{
uint8_t p = static_cast<uint8_t>(pin);
// 1 - Настройка режима работы
// 1.1 - Очистка битов
gpio->MODER &= ~(0b11 << (p << 1));
// 1.2 - Установка режима "AF"
gpio->MODER |= 0b10<<(p << 1);
// 2 - Настройка типа выхода
// 2.1 - Очистка битов
gpio->OTYPER &= ~(0b01 << p);
// 2.2 - Установка типа
gpio->OTYPER |= static_cast<uint32_t>(otype) << p;
// 3 - Настройка скорости пина
// 3.1 - Очистка битов
gpio->OSPEEDR &= ~(0b11 << (p << 1));
// 3.2 - Установка типа
gpio->OSPEEDR |= static_cast<uint32_t>(ospeed) << (p << 1);
// 4 - Выбираем подтяжку
// 4.1 - Очистка битов
gpio->PUPDR &= ~(0b11 << (p << 1));
// 4.2 - Установка типа
gpio->PUPDR |= static_cast<uint32_t>(pull) << (p << 1);
// 5 - Выбор альтернативной функции
if (p < 8)
{
gpio->AFR[0] &= ~(0b1111 << (p << 2));
gpio->AFR[0] |= static_cast<uint32_t>(af) << (p << 2);
}
else
{
gpio->AFR[1] &= ~(0b1111 << ((p - 8) << 2));
gpio->AFR[1] |= static_cast<uint32_t>(af) << ((p - 8) << 2);
}
return;
};
А потом где-нибудь в коде
GPIO::pincfg_alternate(GPIOG, GPIO::PIN::PIN_9, GPIO::AF::USART_6, GPIO::OTYPE::PP, GPIO::OSPEED::HIGH, GPIO::PULL::FLOATING);
Гораздо удобнее, чем каждый раз пихать в регистры битмаски типа GPIOG->MODER = GPIO_MODER_MODE9_0;