読者です 読者をやめる 読者になる 読者になる

PORTの話

 mbedでAVRなどのようなPORTnが欲しくて、それっぽいクラスを頑張って書いてました。というお話。

ソース

#include "mbed.h"
#include <stdarg.h>

template <class pinMode>
class Pins {
private:
    pinMode **pins;
    int size;
public:
    Pins(int, ...);
    Pins& operator=(int value) {
        int i;
        for(i=0; i<size; i++) {
            *pins[i] = (value & (1<<i))>>i;
        }
        return *this;
    }
    operator int()
    {
        int tmp = 0;
        int i;
        for(i=0; i<size; i++) {
            tmp |= *pins[i]<<i;
        }
        return tmp;
    }
};

template <class pinMode>
Pins<pinMode>::Pins(int len, ...)
{
    size = len;
    pins = new pinMode*[len];
    va_list list;
    int i;
    va_start(list, len);
    for(i=0; i<len; i++) {
        pins[i] = new pinMode(va_arg(list, PinName));
    }
}

int main() {
    Pins<DigitalOut> led(4, LED4, LED3, LED2, LED1);
    while(1) {
        for(int i=0; i<16; i++) {
            led=i;
            wait(0.2);
        }
    }
}

 main()でやってるのはmbedの基板上に付いてる4つのLEDをPORTに見立てて、カウンタのように光らせるってもの。
 初めてtemplateと可変長引数使いました。途中でめんどくさくなってテキトーにしか実装してません。というのも

欲しいクラスがライブラリにあった

BusOut

#include "mbed.h"

int main() {
BusOut led(LED4, LED3, LED2, LED1);
    while(1) {
        for(int i=0; i<16; i++) {
            led = i;
            wait(0.2);
        }
    }
}

 ライブラリは全部目を通すべきですねー。BusIn, BusOut, BusInOutをつかえば16bitまでをまとめて操作できるみたいです。注意するのはLSBから書いていくところでしょうかね。あるいはPortIn, PortOut, PortInOutを使っても同様なことが出来るかもしれません。(まだ試してない)
 クラスの宣言はIDEからクラスのリファレンス見てもよく分からないので、ヘッダファイルを読んだ方がわかりやすいと思います。ヘッダファイルのコメントからおおよそ理解できます。

おまけ

 OLEDを買ったのでmbed光らせるところまではやってみました。

 SPIから操作できるというのは簡単で良いですね、それとキャラクタLCDのように何秒待ってどうこうって操作が最初のリセットくらいしか考えなくていいのも扱いやすいです。
 後で使いやすくクラス書いてみることにしましょう。