Цитата(Reflector @ Apr 18 2017, 16:47)

Для примера, у меня вот такая инициализация портов для FSMC:
Код
GpioD<0xC8B3>(PinMode::AF_PushPull_VeryHighSpeed, 12);
GpioE<0x0780>(PinMode::AF_PushPull_VeryHighSpeed, 12);
Т.к. пины там жестко привязаны, то меня такая форма записи абсолютно не напрягает, но при желании можно маску пинов перевести в бинарный вид:
Код
GpioD<0b1100'1000'1011'0011>(PinMode::AF_PushPull_VeryHighSpeed, 12);
Хрен редьки не слаще - как было нифига не понятно, что значат эти магические числа, так оно и осталось.

Битовые литералы тут как собаке - пятая нога )))
Цитата
Или расписать более подробно, как обычно и делают:
Код
const uint32_t FSMC_PD = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_11 | GPIO_Pin_14 | GPIO_Pin_15;
GpioD<FSMC_PD>(PinMode::AF_PushPull_VeryHighSpeed, 12);
Мне такой вариант вообще не по душе, поэтому накидал свой класс Pin.hpp (для каждого семейства процов он разный):
CODE
.............
typedef enum
{
PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15,
PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15,
PC0, PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10, PC11, PC12, PC13, PC14, PC15,
PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15,
PE0, PE1, PE2, PE3, PE4, PE5, PE6, PE7, PE8, PE9, PE10, PE11, PE12, PE13, PE14, PE15,
PF0, PF1, PF2, PF3, PF4, PF5, PF6, PF7, PF8, PF9, PF10, PF11, PF12, PF13, PF14, PF15,
PH0, PH1, PH2, PH3, PH4, PH5, PH6, PH7, PH8, PH9, PH10, PH11, PH12, PH13, PH14, PH15,
} PIN;
.................
class PinBase
{
public:
PinBase(PIN pin)
{
portIndex = pin / 16;
pinIndex = pin % 16;
pinMask = (((UNSIGNED32)1) << pinIndex);
.....
}
.....
inline void setToHigh(void) { port->BSRRL = pinMask; }
inline void setToLow(void) { port->BSRRH = pinMask; }
inline bool isHigh(void) { return (((port->IDR) & pinMask) != 0); }
inline bool isLow(void) { return (((port->IDR) & pinMask) == 0); }
inline void toggle(void) { port->ODR ^= pinMask; }
protected:
volatile GPIO_TypeDef * port;
volatile UNSIGNED8 portIndex;
volatile UNSIGNED8 pinIndex;
volatile UNSIGNED32 pinMask;
};
...............
template <PIN pin>
class Pin : public PinBase
{
public:
Pin(void) : PinBase(pin) { }
};
..........
template <PIN pin>
class DigitalOutputPin : public PinBase
{
public:
DigitalOutputPin(void) : PinBase(pin)
{
setAsDigitalOutput();
setAsPushPull();
setOutputSpeed40MHz();
}
};
.......................
template <PIN pin>
class LedOpenDrain : public PinBase
{
public:
LedOpenDrain(void) : PinBase(pin)
{
setAsDigitalOutput();
setAsOpenDrain();
setOutputSpeed10MHz();
off();
}
void on(void) { setToLow(); }
void off(void) { setToHigh(); }
};
........
Все привязки пинов описаны в одном файле, так удобнее изменять привязку портов при смене камня и просто при переносе кусков кода из проекта в проект:
CODE
......
// EXTERNAL ADC
#define PIN_ADC_CONVST (PB14)
#define PIN_ADC_SCLK (PB13)
#define PIN_ADC_DATA (PC6)
// LEDS
#define PIN_LED_GREEN (PB6)
#define PIN_LED_RED (PB5)
......
Вот так применяю:
*.hpp:
Код
class ExternalDAC
{
public:
void initialize(void);
void setVoltage(FLOAT32 voltage);
FLOAT32 getVoltage(void) const { return (voltage); }
private:
DigitalOutputPin<PIN_DAC_CS> pinCS;
DigitalOutputPin<PIN_DAC_SCK> pinSCK;
DigitalOutputPin<PIN_DAC_MOSI> pinMOSI;
FLOAT32 voltage;
};
*.cpp
Код
void ExternalDAC::initialize(void)
{
pinCS.setToHigh();
pinSCK.setToHigh();
pinMOSI.setToLow();
}