雛形を作りなおしているので、そのついでにGPIOを操作するマクロを作ってみました。
基本的にSTM32F1用。
マクロ
#ifndef __hardware_H #define __hardware_H #include "includes.h" #define HW(name, x, type) name##_##x##_##type #define HW_OUT(name, x, val) GPIO_WriteBit(HW(name, x, PORT), HW(name, x, PIN), (val) ? HW(name, x, ACTIVE) : !HW(name, x, ACTIVE)) #define HW_IN(name, x) (GPIO_ReadInputDataBit(HW(name, x, PORT), HW(name, x, PIN)) == HW(name, x, ACTIVE)) #define HW_OT(name, x) (GPIO_ReadOutputDataBit(HW(name, x, PORT), HW(name, x, PIN)) == HW(name, x, ACTIVE)) #define HW_TGL(name, x) HW_OUT(name, x, !HW_OT(name, x)); #define LED_1_RCC RCC_APB2Periph_GPIOD #define LED_1_PORT GPIOD #define LED_1_PIN GPIO_Pin_4 #define LED_1_ACTIVE 0 #define SW_1_RCC RCC_APB2Periph_GPIOA #define SW_1_PORT GPIOA #define SW_1_PIN GPIO_Pin_0 #define SW_1_ACTIVE 1 #endif /* __hardware_H */LED1はアクティブLOW接続でResetで点灯、Setで消灯。
SW1はアクティブHIGH接続で押された時にSet。
使用例
void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(HW(LED, 1, RCC), ENABLE); GPIO_InitStructure.GPIO_Pin = HW(LED, 1, PIN); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(HW(LED, 1, PORT), &GPIO_InitStructure); } void SW_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(HW(SW, 1, RCC), ENABLE); GPIO_InitStructure.GPIO_Pin = HW(SW, 1, PIN); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(HW(SW, 1, PORT), &GPIO_InitStructure); }
スイッチを読む場合
if (HW_IN(SW, 1)) { ... } else { ... }
LEDを点灯させる場合
HW_OUT(LED, 1, 1);
LEDを消灯させる場合
HW_OUT(LED, 1, 0);
LEDを切り替える場合
HW_TGL(LED, 1);
もちろんスイッチやLED以外にも使用可能です。
ほとんど便利じゃないし、forで回したりできないので、ベタ書きとほとんど変わらないですが。
あとUnity(テストハーネス)使ってる人はわかると思いますが、マクロでごにょごにょやってるとエラった時にメッセージが非常に難解です。
今回はHWを接頭辞として使っていますが、LED(1, PORT)やSW(1, PIN)のほうが直感的な気がします。