[uquote="Reflector",url="/forum/viewtopic.php?p=3562874#p3562874"][uquote="Satarych",url="/forum/viewtopic.php?p=3562812#p3562812"]Тестируемый проект для Keil'а прилагаю. IDE-Version: µVision V5.25.2.0, C Compiler: ArmClang.exe V6.9[/uquote]
Понятно, компилятор таки новый, просто я как-то компилировал такую конструкцию с передачей GPIO_TypeDef* в шаблон под clang и выдавало ошибку, а сейчас проверил и ошибка действительно есть, но только в режиме С++17, а gcc выдает ошибку в любом случае. Похоже это баг clanga, по правилам можно передавать целочисленные константы или указатели/ссылки на объекты или функции, собственно gcc и пишет, что не может взять адрес... Если бы компилировалось и работало, то можно было поспорить, а так

[/uquote]В файле CMSIS stm32f10x.h объявлен следующий тип данных
Код: Выделить всё
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
Соответственно GPIO_TypeDef - тип, GPIO_TypeDef* - тип "указатель на объекты этого типа", а GPIOA, GPIOB и пр. - непосредственно указатели на объекты этого типа. Однако, учитывая тот факт, что GCC компилятор не принимает GPIOx в качестве параметра моего шаблона, очевидно, что я что-то путаю. Поправьте где именно я не прав.
Эксперимента ради:
Код: Выделить всё
Stm32Gpio <GPIOA, 1<<8> led0; // ошибка
Stm32Gpio <(GPIO_TypeDef *)0x40010800, 1<<8> led1; // таже самая ошибка
GPIO_TypeDef GPIO_1;
Stm32Gpio <&GPIO_1, 1<<8> led2; // а вот это, хоть и бессмысленно, но компилируется
Не могу понять, чем "&GPIO_1" отличается от "(GPIO_TypeDef *)0x40010800" с точки зрения типа данных?
PS Ваш вариант использовать GPIOx_BASE мне не очень нравится потому что обязывает заранее создать шаблоны для всех GPIO, что по сути дублирует CMSIS. В противном случае ничто не защитит от написания бессмыслицы типа
Код: Выделить всё
template<uint32_t pin, uint32_t af = 0>
using PinX = PinT<I2C1_BASE, pin, af>;