編集履歴一覧に戻る
meyon230のアイコン画像

meyon230 が 2023年11月01日01時20分33秒 に編集

リンク先URL変更

メイン画像の変更

メイン画像が変更されました

本文の変更

SPI (Serial Peripheral Interface) とはどんな通信方式なのかを勉強して、シフトレジスタ 74HC597 (PISO) から Arduino へ、SPI でデータを受けとる実験をしてみました。

-

この記事は「[meyon's STUDY](http://meyon.gonna.jp/study/electronic/9863/)」に投稿した記事の抜粋です。

+

この記事は「[meyon's STUDY](https://meyon.gonna.jp/study/electronic/9863/)」に投稿した記事の抜粋です。

なお、Arduino 公式サイトのアナウンスに従い、用語の言い換えをしています。新しい用語については [Arduino & Serial Peripheral Interface (SPI)](https://docs.arduino.cc/learn/communication/spi) を参照してください。 ## 74HC597 から Arduinoへデータを受ける方法

-

![接続図](http://meyon.gonna.jp/study/wp-content/uploads/spiReceivingConnectionDiagram_431599.png)

+

![接続図](https://meyon.gonna.jp/study/wp-content/uploads/spiReceivingConnectionDiagram_431599.png)

データを受信する場合も、Arduino からデータを送ります。このとき送信するデータはダミーデータです。SPI.transfer(dummyData) でダミーデータが $\text{COPI}$ に送信され、同時に受信した $\text{CIPO}$ のデータは戻り値として出力されます。 ダミーデータは 74HC597 では利用しませんから、$\text{COPI}$ はどこへも接続しません。利用するのは送信時に出力されるシリアルクロック $\text{SCK}$ で、74HC597 のシフトクロック $\text{SH}_\text{CP}$ に接続します。 74HC597 側では、チップセレクト $\overline\text{CS}$ を受けてパラレルロード $\overline\text{PL}$ を生成し、ストレージレジスタからシフトレジスタへデータを渡します。そして $\text{SCK}$ に同期してデータを $\text{CIPO}$ へ送出します。 送信が完了すると $\overline\text{CS}$ が HIGH になりますので、これをストレージクロック $\text{ST}_\text{CP}$ として、外部からのパラレルデータをストレージレジスタへ読み込みます。つまり、74HC597 から送られてくるデータは、一回前の通信が完了したときのデータということになります。

-

![タイミングダイヤグラム](http://meyon.gonna.jp/study/wp-content/uploads/spiReceivingTimingDiagram_431599.png)

+

![タイミングダイヤグラム](https://meyon.gonna.jp/study/wp-content/uploads/spiReceivingTimingDiagram_431599.png)

コントローラ (Arduino) 側では、チップセレクト $\overline\text{CS}$ を LOW にすることで通信を開始し、終了したら HIGH にもどす。SPI.transfer() を実行するとシリアルクロック $\text{SCK}$ が送出される。$\text{COPI}$ に出力されるデータは、ペリフェラル側では利用しない。 ペリフェラル (74HC597) 側。$\overline\text{CS}$ は $\text{ST}_\text{CP}$ につながっているが、LOW になっても何も起こらない。 $\overline\text{CS}$ の立ち下がりエッジで、一定時間のパラレルロード $\overline\text{PL}$ パルスを生成する。これにより、シリアルデータ $\text{Q7}$ に データ $\text{D7}$ が出力される。 $\text{SH}_\text{CP}$ ($\text{SCK}$) の立ち上がりエッジでデータをシフトし、8ビットのデータが $\text{CIPO}$ へ送られる。コントローラも、データを $\text{SCK}$ の立ち上がりエッジで読み込み、SPI.transfer() の戻り値として出力する。 受信が終了し $\overline\text{CS}$ が HIGH になると、それがストレージクロック $\text{ST}_\text{CP}$ となり、新たなデータがストレージレジスタへ読み込まれる。 ## 回路図

-

![回路図](http://meyon.gonna.jp/study/wp-content/uploads/spiReceiving_schematic_431599.png)

+

![回路図](https://meyon.gonna.jp/study/wp-content/uploads/spiReceiving_schematic_431599.png)

Arduino は Nano Every です。使用するピンは、$\text{SCK}$ が D13、$\text{CIPO}$ が D12、$\overline\text{CS}$ は D8 です。UNO や NANO では $\overline\text{CS}$ は D10 ですので、間違えないように。$\text{COPI}$ (D11) は使用しません。 左の Dip スイッチで 8ビットのデータを生成、それをシフトレジスタ 74HC597 に読み込み、Arduino へ送ります。 下部の NOR ゲート 74HC02 を使った回路はワンショットパルス回路。チップセレクト $\overline\text{CS}$ が LOW になったときに、パラレルデータをロードするための $\overline\text{PL}$ を生成します。パルス幅は 90nsほどになっています。 ## スケッチ 9行目。Arduino Nano Every では $\overline\text{CS}$ のピンモードを設定してやらないとうまく動きません。UNO や NANO では必要ないです。 Dipスイッチで生成した 8ビットデータが、シリアルモニタに出力されます。 ```C++:spi_receiving_test.ino // Sketch for 74HC597 to Arduino SPI-Test 2023.9.10 meyon #include <SPI.h> SPISettings mySettings(8000000, MSBFIRST, SPI_MODE0); void setup() { // In Nano Every,SS is pin-D8, Mode setting required pinMode(SS, OUTPUT); Serial.begin(9600); SPI.begin(); } void loop() { static byte receivedValue = 0; SPI.beginTransaction(mySettings); digitalWrite(SS, LOW); receivedValue = SPI.transfer(0xff); digitalWrite(SS, HIGH); SPI.endTransaction(); Serial.println(receivedValue, BIN); delay(50); } ```