Удобная настройка GPIO STM32F030. Мой велосипед.

Долгое время я настраивал порты различных микроконтроллеров STM32 при помощи Standart Peripheral Library.

GPIO_InitTypeDef gpio_struct;
gpio_struct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8;
gpio_struct.GPIO_Mode = GPIO_Mode_Out_PP;
gpio_struct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOC , &gpio_struct);

Потом появилась необходимость использования мелких микроконтроллеров, типа STM32F030F4P6, поэтому решил от SPL отказаться. Настраивал через регистры.

GPIOA->MODER |= GPIO_MODER_MODER15_0; // LCD_RS PA15
GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR15;
GPIOB->MODER |= GPIO_MODER_MODER3_0; // LCD_CS PB3
GPIOB->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR3;
GPIOB->MODER |= GPIO_MODER_MODER4_0; // LCD_WR PB4
GPIOB->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR4;
GPIOB->MODER |= GPIO_MODER_MODER5_0; // LCD_RST PB5
GPIOB->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR5;

Но в один прекрасный момент мне надоели эти непонятные записи. Магические, ни о чём не говорящие числа… Код становится нечитаемым, а если надо изменить настройки одной ноги, то надо открывать даташит… Погуглил, наткнулся на тему, в которой описывалась моя проблема. Но предложенные там реализации кода мне не очень понравились.
Например, строчка которая ввела меня в ступор:

#define GPIO_MODE_INPUT_PULL_UP_DOWN

Или эти магические числа:

#define GPIO_MODE_OUTPUT2_ALT_OPEN_DRAIN
#define GPIO_MODE_OUTPUT10_OPEN_DRAIN
#define GPIO_MODE_OUTPUT50_PUSH_PULL

А уж не говоря про это, непонятно зачем вставленное

#define GPIO_MODE_RESERVED

Вобщем я перечитал тему со всеми комментариями, и решил изобрести свой велосипед, на основе предложенных там примеров. Так скажем, с каждого примера взял чуть по чуть. Может кому-то понравится мой вариант — буду допиливать. На данный момент можно настраивать только пины по отдельности, но могу допилить настройку пинов по маске.
Итак, мой велосипед:

// Режим работы
#define GPIO_MODE_INPUT 0UL
#define GPIO_MODE_OUTPUT 1UL
#define GPIO_MODE_ALTFUNC 2UL
#define GPIO_MODE_ANALOG 3UL

// Тип выхода
#define GPIO_OUTTYPE_NONE 0UL // заглушка
#define GPIO_OUTTYPE_PP 0UL
#define GPIO_OUTTYPE_OD 1UL

// Подтяжка
#define GPIO_PULL_NONE 0UL
#define GPIO_PULL_UP 1UL
#define GPIO_PULL_DOWN 2UL

// Скорость
#define GPIO_SPEED_LOW 0UL
#define GPIO_SPEED_MED 1UL
#define GPIO_SPEED_HI 3UL

// Альтернативные функции
#define GPIO_ALTFUNC_NONE 0UL // заглушка

// Макрос инициализации
#define GPIO_INIT(GPIO_PORT,GPIO_PIN,GPIO_MODE,GPIO_OUTTYPE,GPIO_PULL,GPIO_SPEED,GPIO_ALTFUNC)
{
GPIO_PORT->MODER = (GPIO_PORT->MODER & ~(3UL << (GPIO_PIN * 2UL)))
| (GPIO_MODE << (GPIO_PIN * 2UL));
GPIO_PORT->OTYPER = (GPIO_PORT->OTYPER & ~(1UL << (GPIO_PIN)))
| (GPIO_OUTTYPE << (GPIO_PIN));
GPIO_PORT->OSPEEDR = (GPIO_PORT->OSPEEDR & ~(3UL << (GPIO_PIN * 2UL)))
| (GPIO_SPEED << (GPIO_PIN * 2UL));
GPIO_PORT->PUPDR = (GPIO_PORT->PUPDR & ~(3UL << (GPIO_PIN * 2UL)))
| (GPIO_PULL << (GPIO_PIN * 2UL));
GPIO_PORT->AFR[GPIO_PIN / 8] = (GPIO_PORT->AFR[GPIO_PIN / 8] & ~(15UL << ((GPIO_PIN & 0x7) * 4)))
| ((GPIO_ALTFUNC) << (GPIO_PIN & 0x7) * 4);
}

// Макросы для работы с ножкой порта
#define GPIO_SET(GPIO_PORT,GPIO_PIN) (GPIO_PORT->BSRR = (1 << GPIO_PIN))
#define GPIO_RESET(GPIO_PORT,GPIO_PIN) (GPIO_PORT->BRR = (1 << GPIO_PIN))
#define GPIO_TOGGLE(GPIO_PORT,GPIO_PIN) (GPIO_PORT->BSRR = (1 << (GPIO_PIN+ ((GPIO_PORT->ODR & (1 << GPIO_PIN))?16:0)
#define GPIO_ISSET(GPIO_PORT,GPIO_PIN) (GPIO_PORT->IDR & (1 << GPIO_PIN))
#define GPIO_ISRESET(GPIO_PORT,GPIO_PIN) (!(GPIO_PORT->IDR & (1 << GPIO_PIN)))

// Макросы для работы с портом
#define GPIOS_SET(GPIO_PORT,GPIO_MASK) (GPIO_PORT->BSRR = GPIO_MASK)
#define GPIOS_RESET(GPIO_PORT,GPIO_MASK) (GPIO_PORT->BRR = GPIO_MASK)
#define GPIOS_TOGGLE(GPIO_PORT,GPIO_MASK) (GPIO_PORT->ODR ^= GPIO_MASK)

// Примеры инициализации
// GPIO_INIT(GPIOA, 0, GPIO_MODE_OUTPUT, GPIO_OUTTYPE_PP, GPIO_PULL_NONE, GPIO_SPEED_HI, GPIO_ALTFUNC_NONE);
// GPIO_INIT(GPIOA, 1, GPIO_MODE_INPUT, GPIO_OUTTYPE_NONE, GPIO_PULL_UP, GPIO_SPEED_HI, GPIO_ALTFUNC_NONE);

Делалось под STM32F030, для других МК возможно понадобятся исправления.
Замечания пишите в комментариях. Приветствуется любая адекватная критика.
Источник

Оставить комментарий

Вы можете использовать следующие теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>