2015年9月29日火曜日

GPIOを操作するマクロを作る

久しぶりにSTM32F1で遊んでいます。
雛形を作りなおしているので、そのついでに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)のほうが直感的な気がします。

0 件のコメント:

コメントを投稿