ArduinoのSPIやTWI(Wire)って、基本的にはデータの書き込みと読み込みするだけなのに全く仕様が違うのですぐ使い方を忘れてしまう。
そろそろボケ始めてるだけのことかもしれないが(笑)、とにかく毎回使い方を調べたりするのが面倒臭いのでSPI/TWIを共通仕様で使えるようなシンプルなインターフェース・クラスを考えてみた。
基本仕様はシンプルに初期化と終了及び書き込みと読み込みのみ。その他のインターフェース特有のパラメタ等は実装先クラスで対応する。
void begin(void)
void end(void)
void write(const uint8_t *buf, uint8_t len)
uint8_t read(uint8_t *buf, uint8_t len)
uint8_t writeAndRead(const uint8_t *wbuf, uint8_t wlen, uint8_t *rbuf, uint8_t rlen)
これくらいなら覚えておけるだろう。たぶん。(笑)
【基本インターフェース・クラス(PBUSIF)】
1 |
void begin(void) |
初期化を行う。
1 |
void end(void) |
終了処理を行う。
1 |
void write(const uint8_t *buf, uint8_t len) |
データを書き込む。
1 |
uint8_t read(uint8_t *buf, uint8_t len) |
データを読み込む。戻り値は読み込んだバイト数。
1 |
uint8_t writeAndRead(const uint8_t *wbuf, uint8_t wlen, uint8_t *rbuf, uint8_t rlen) |
データ(wbuf, wlen)を書き込み後にデータ(rbuf, rlen)を読み込む。戻り値は読み込んだバイト数。
【SPI実装クラス(SPIBUS)】
1 2 |
template<uint8_t CS, uint32_t CLOCK = 4000000, uint8_t MODE = SPI_MODE3, uint8_t BITORDER = MSBFIRST> class SPIBUS : public PBUSIF |
uint8_t CS … チップセレクト・ピン番号
uint32_t CLOCK … SPIバスクロック(省略値は4MHz)
uint8_t MODE … SPIモード(省略値はSPI_MODE3)
uint8_t BITORDER … ビット・オーダー(省略値はMSBFIRST)
【TWI実装クラス(TWIBUS)】
1 2 |
template<uint8_t SLAVE, uint32_t CLOCK = 100000> class TWIBUS : public PBUSIF |
uint8_t SLAVE … スレーブ・アドレス
uint32_t CLOCK … TWIバス・クロック (省略値は100KHz)
【使い方の例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include "spibuf.h" #include "twibus.h" SPIBUS<チップセレクト・ピン番号> spi; TWIBUS<スレーブ・アドレス> twi; void setup() { spi.begin(); twi.begin(); } void loop() { spi.write(...); spi.read(...); spi.writeAndRead(...); twi.write(...); twi.read(...); twi.writeAndRead(...); } |
【ライブラリ】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
/* pbusif.h - Peripheral BUS Interface Class Copyright (c) 2020 Sasapea's Lab. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __PBUSIF_H #define __PBUSIF_H #include <stdint.h> #include <stdbool.h> class PBUSIF { public: PBUSIF(void) { } virtual ~PBUSIF(void) { } virtual void begin(void) { } virtual void end(void) { } virtual void write(const uint8_t *buf, uint8_t len) { writeAndRead(buf, len, 0, 0); } virtual uint8_t read(uint8_t *buf, uint8_t len) { return writeAndRead(0, 0, buf, len); } virtual uint8_t writeAndRead(const uint8_t *wbuf, uint8_t wlen, uint8_t *rbuf, uint8_t rlen) = 0; }; #endif |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
/* spibus.h - SPI Implementation Class for Arduino SPI Copyright (c) 2020 Sasapea's Lab. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __SPIBUS_H #define __SPIBUS_H #include "pbusif.h" #include "SPI.h" template<uint8_t CS, uint32_t CLOCK = 4000000, uint8_t MODE = SPI_MODE3, uint8_t BITORDER = MSBFIRST> class SPIBUS : public PBUSIF { private: SPISettings _mode; public: SPIBUS(void) { _mode = SPISettings(CLOCK, BITORDER, MODE); } virtual ~SPIBUS(void) { } virtual void begin(void) override { digitalWrite(CS, HIGH); pinMode(CS, OUTPUT); SPI.begin(); } virtual void end(void) override { SPI.end(); pinMode(CS, INPUT); } virtual uint8_t writeAndRead(const uint8_t *wbuf, uint8_t wlen, uint8_t *rbuf, uint8_t rlen) override { uint8_t cnt = 0; SPI.beginTransaction(_mode); digitalWrite(CS, LOW); if (wbuf) { while (wlen--) SPI.transfer(wbuf[cnt++]); } cnt = 0; if (rbuf) { while (rlen--) rbuf[cnt++] = SPI.transfer(0xFF); } digitalWrite(CS, HIGH); SPI.endTransaction(); return cnt; } }; #endif |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
/* twibus.h - TWI Implementation Class for Arduino Wire Copyright (c) 2020 Sasapea's Lab. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __TWIBUS_H #define __TWIBUS_H #include "pbusif.h" #include "Wire.h" template<uint8_t SLAVE, uint32_t CLOCK = 100000> class TWIBUS : public PBUSIF { public: TWIBUS(void) { } virtual ~TWIBUS(void) { } virtual void begin(void) override { Wire.begin(); } virtual void end(void) override { Wire.end(); } virtual uint8_t writeAndRead(const uint8_t *wbuf, uint8_t wlen, uint8_t *rbuf, uint8_t rlen) override { uint8_t cnt = 0; Wire.setClock(CLOCK); if (wbuf && wlen) { Wire.beginTransmission(SLAVE); Wire.write(wbuf, wlen); if (Wire.endTransmission(!(rbuf && rlen)) != 0) return 0; // transmit failed. } if (rbuf && rlen) { Wire.requestFrom(SLAVE, rlen); cnt = Wire.readBytes(rbuf, rlen); } return cnt; } }; #endif |