SPI通信がひと段落!!(SPI2)
🩴

SPI通信がひと段落!!(SPI2)

Tags
Published
June 7, 2018
SPI通信がひと段落!!
今日はSPI通信をしました。昨日考えていたアプローチの一つをしたらあっさり成功してしまいました。ソフトウェアリセットを使って、自分のアドレスが1秒間受信されなかったらもしかしたらバグってるのではないかと判断し、自ら自分をリセットします。こういったプログラムです。ポーリングではなくアルゴリズムです。ただ2台以上(マルチプル)で試したことがないので、今日試したいです。これができたら完璧です。
プログラムを載せておきます。そろそろバージョン管理しないとどこかで躓きますね。

Master

#include "mbed.h" #define MOSI PB_15 //MOSI #define MISO PB_14 //MISO #define SCK PB_13 //SCK #define CS1 PB_12 //SS #define ADDRESS1 1000//303k8へ送るアドレス。千くらいを使うので4桁 #define ADDRESS2 2000//303k8へ送るアドレス。千くらいを使うので4桁 #define COMMAND1 100 #define COMMAND2 200 SPI spi(MOSI, MISO, SCK); //SPI DigitalOut cs(CS1); //SSピン Serial pc(USBTX, USBRX); //Serial short data = 0x00; int main(void){ spi.format(16, 3);//16bit.mode3 spi.frequency(8000000); /* SPI Frequency 1MHz(1000000Hz) */ pc.baud(115200); cs = 1;//HIGHにしておかないとスレーブが誤認識する。 pc.printf("SPI Communication Master Mode\n"); while(1) { cs = 0;//アドレスで指定した通信相手のCSピンをLOWにして呼び出し spi.write(ADDRESS1+COMMAND1);//全員にアドレスを送信 data = spi.write(0);//読み込み cs = 1;//SSピンをHIGHにして通信終了 pc.printf("receive data %d\n", data);//受け取ったデータの表示 wait_ms(10); } }

Slave

#include "mbed.h" #define Slave1//プリプロセッサの処理 #ifdef Slave1//プリプロセッサ側で判断 (Slave1は定義されていますか?) //定義されていたら #define OWN_ADDRESS 1 #else //定義されていなかったら #define OWN_ADDRESS 2 #endif #define COMMAND1 100 #define Address_Check (data/1000) == OWN_ADDRESS //アドレスチェックのマクロ関数 SPISlave spi(A6, A5, A4, A3);//MOSI,MISO,SCK,SS InterruptIn ss(A3); //割り込みピン DigitalOut led(D13); //LED Serial pc(USBTX, USBRX); //Serial Ticker CheckBuffer; Timer Reset; short data = 0x00; bool can_reply = 0;//返信できるかどうかのフラグ //タイマ割り込みでデータ受信があるかのチェック(/50us) void SPI_CHECK(){ if(spi.receive() == 1) { data = spi.read(); } if(Reset.read_ms() > 1000) { NVIC_SystemReset();//ソフトウェアリセット } } //SS割り込み void msgReceived(void){ //・・wait_ms(1); CheckBuffer.detach();//タイマー割り込みの禁止 if(spi.receive() == 1) {//データが来ていたら読み込み data = spi.read();//読み込み } if(Address_Check) {//自分のアドレスかどうかをチェックする //自分のアドレスだったら led = 1; spi.reply(200);//返信データのセット Reset.reset();//監視タイマーリセット pc.printf("receive data %d\n", data); }else{ //自分のアドレス以外 led = 0; } CheckBuffer.attach_us(&SPI_CHECK,50);//タイマー割り込みのセット } void setup(){//セットアップ関数 spi.format(16, 3);//16bit.mode3 spi.frequency(8000000); /* SPI Frequency 1MHz(1000000Hz) */ pc.baud(115200); ss.mode(PullUp);//プルアップしておけばバグりにくい pc.printf("SPI Communication Slave Mode\n"); ss.fall(&msgReceived);//SSピンのピン割り込み spi.reply(0x00);//最初の返信データのセット Reset.start();//ソフトウェアリセットをする為の監視タイマー CheckBuffer.attach_us(&SPI_CHECK,50);//タイマー割り込みのセット } //main process int main(void) { setup();//セットアップ while(1) {//while1 led = !led; wait_ms(30); } }
今回のslabeプログラムはハードウェアリセットじゃなくてソフトウェアリセットを利用しました。NVIC_SystemReset();というのを使えばソフトウェア的にリセットを掛けられます。バグった時の一つのアプローチとして使えるといいですね。あともう一つ工夫があります。
#ifndef Name でコンパイル時の処理を加えました。これでスレーブ2個を一つのプログラムで分けれますね。他にもコメントバリバリ打ち込んでいるので誰にもわからないと言わせないようにかけていると思ってます。いつかはこのSPI通信もちゃんと実用化できる日が来るのですね。SPIが完全にできたらハードウェアに取り掛かります。 優先順位
 
  1. デバイスが動くかどうかの確認
  1. 設計
  1. 組み上げ
  1. プログラミング
ですね。このうち、設計の段階でプログラムのライブラリの作成も決まってくるのでそろそろSPIをオブジェクト指向で書きます。今日は3ページでした。プログラムを打ち込めば文字数かけげますね。

Loading Comments...