
从GITLAB上看到一个PCAN项目,本来是想移植过来用的,研究代码时候发现宝藏。
#define EX_PIN_INIT( _PORT, _PIN, _MODE, _PULL, _SPEED, _AF )\HAL_GPIO_Init( GPIO##_PORT, (GPIO_InitTypeDef[])\{{\ .Pin = GPIO_PIN_##_PIN,\ .Mode = GPIO_##_MODE,\ .Pull = GPIO_##_PULL,\ .Speed = GPIO_##_SPEED,\ .Alternate = GPIO_##_AF\}} )#define PIN_INIT( CONFIG ) EX_PIN_INIT( CONFIG )#define EX_PIN_DEINIT( _PORT, _PIN, ... ) HAL_GPIO_DeInit( GPIO##_PORT, GPIO_PIN_##_PIN )#define PIN_DEINIT( CONFIG ) EX_PIN_DEINIT( CONFIG )/* pin control */#define EX_GPIO_PIN_STAT( PORT, PIN, ... ) ( (GPIO##PORT->IDR & (1u<<PIN)) != 0 )#define EX_GPIO_PIN_STAT_INV( PORT, PIN, ... ) ( (GPIO##PORT->IDR & (1u<<PIN)) == 0 )#define PIN_STAT( CONFIG ) EX_GPIO_PIN_STAT( CONFIG )#define PIN_INV_STAT( CONFIG ) EX_GPIO_PIN_STAT_INV( CONFIG )/* -------------------------- */#define EX_GPIO_PIN_HI( PORT, PIN, ... ) GPIO##PORT->BSRR = (1u<<PIN)#define EX_GPIO_PIN_LOW( PORT, PIN, ... ) GPIO##PORT->BSRR = (0x10000u<<PIN)#define PIN_HI( CONFIG ) EX_GPIO_PIN_HI( CONFIG )#define PIN_LOW( CONFIG ) EX_GPIO_PIN_LOW( CONFIG )#define PIN_HiZ( CONFIG ) EX_GPIO_PIN_HI( CONFIG )#define PIN_1( CONFIG ) EX_GPIO_PIN_HI( CONFIG )#define PIN_0( CONFIG ) EX_GPIO_PIN_LOW( CONFIG )#define PIN_ONE( CONFIG ) EX_GPIO_PIN_HI( CONFIG )#define PIN_ZERO( CONFIG ) EX_GPIO_PIN_LOW( CONFIG )/* -------------------------- */#define EX_GPIO_PIN_TOGGLE( PORT, PIN, ... )\do{\ if( GPIO##PORT->ODR & (1u<<PIN) ){\ EX_GPIO_PIN_LOW( PORT, PIN );\ }\ else{\ EX_GPIO_PIN_HI( PORT, PIN );\ }\}while(0)#define PIN_TOGGLE( CONFIG ) EX_GPIO_PIN_TOGGLE( CONFIG )#define EX_PIN_PORT( PORT, ... ) PORT#define PIN_PORT( CONFIG ) EX_PIN_PORT( CONFIG )/* maximimum is 8 params */#define NUM_ARGS_(_1, _2, _3, _4, _5, _6, _7, _8, TOTAL, ...) TOTAL#define NUM_ARGS(...) NUM_ARGS_(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)#define CONCATE_(X, Y) X##Y#define CONCATE(MACRO, NUMBER) CONCATE_(MACRO, NUMBER)#define VA_MACRO(MACRO, ...) CONCATE(MACRO, NUM_ARGS(__VA_ARGS__))(__VA_ARGS__)#define PORT_ENABLE_CLOCK(...)\do{\ __IO uint32_t tmp;\ VA_MACRO(PORT_ENABLE_CLOCK, __VA_ARGS__);\ /* readback */\ tmp = RCC->AHB1ENR;\ (void)tmp;\}while(0)#define PORT_ENABLE_CLOCK1(_1) RCC->AHB1ENR |= RCC_AHB1ENR_GPIO##_1##EN#define PORT_ENABLE_CLOCK2(_1, _2) RCC->AHB1ENR |= RCC_AHB1ENR_GPIO##_1##EN |\ RCC_AHB1ENR_GPIO##_2##EN#define PORT_ENABLE_CLOCK3(_1, _2, _3) RCC->AHB1ENR |= RCC_AHB1ENR_GPIO##_1##EN |\ RCC_AHB1ENR_GPIO##_2##EN |\ RCC_AHB1ENR_GPIO##_3##EN#define PORT_ENABLE_CLOCK4(_1, _2, _3, _4) RCC->AHB1ENR |= RCC_AHB1ENR_GPIO##_1##EN |\ RCC_AHB1ENR_GPIO##_2##EN |\ RCC_AHB1ENR_GPIO##_3##EN |\ RCC_AHB1ENR_GPIO##_4##EN其中PORT_ENABLE_CLOCK这个宏用的太妙了,看看是怎么用的
#define IO_BEEP B, 15, OUT_PP, NOPULL, SPEED_FREQ_MEDIUM, NOAF#define IO_PWRBTN A, 7, OUT_PP, NOPULL, SPEED_FREQ_MEDIUM, NOAFvoid main(){ systick_config(); PORT_ENABLE_CLOCK(PIN_PORT(IO_BEEP),PIN_PORT(IO_PWRBTN)); PIN_INIT(IO_BEEP); PIN_INIT(IO_PWRBTN); PIN_LOW(IO_BEEP); PIN_LOW(IO_PWRBTN); while(1){ PIN_HI(IO_BEEP); PIN_HI(IO_PWRBTN); delay_1ms(100); PIN_LOW(IO_BEEP); PIN_LOW(IO_PWRBTN); delay_1ms(900); }}