2015年3月10日火曜日

マイコン固有の機能を使わずSPI通信


こんにちは、doesです。

CAN通信用のモジュール(MCP2515)とAVR168P間でSPI通信をする時、
参考にしたCANの参考書がマイコン固有の機能を使わずピンのHIGH/LOWを操作して
SPI通信を実装していたため、
合わせる為同じ形式でやってみました。

SPI通信とは一対多数で通信可能な同期式のシリアル通信で、
【3+1×スレーブの数】本の信号線を使用します。
このサークルで同期式の通信だとI2Cをよく使用しますが、あちらに比べると
アドレスを送ったりACKを返したりが必要なく、かなり単純な通信方式になります。
ややこしい制御は必要なく、決められた信号を送るだけでモジュールにデータを送れました。
今回は一対一の通信だったので必要な信号線は4本です。
①SS
スレーブの選択に使用するピンです。今回は1つしかスレーブがないので、
データを送る際はずっとLOW、それ以外のときはHIGHにします。
スレーブが多数ある場合はこのピンがスレーブの数分増えます。
②SCK
クロックを送ります。
デューティー比が0.5でなくても、データを送った後にHIGH→LOWと変更すればOKです。
③MISO
Master In Slave Outの略で、スレーブからデータが送られてきます。
マスター側は入力に指定しておき、受信されたデータを読み込みます。
④MOSI
Master Out Slave Inの略で、スレーブに送るデータを出力します。

通信に使用したプログラムは以下になります。
cmdbfに入ったデータ、計4バイトを続けて送信します。

  cmdbf[0]=0b00000101;
  cmdbf[1]=adrs;
  cmdbf[2]=mask;
  cmdbf[3]=data;
  SPI_SS_L;//通信開始
  for(p=0;p<4;p++){//データの数分繰り返し
    cmd=cmdbf[p];//データ代入
    for(i=0;i<8;i++){
   if(cmd & 0x80){//上位ビットから先に送信 上位ビットが0か1かでピンの状態を変更
SPI_MOSI_H;
      }else {
SPI_MOSI_L;
      }
      cmd<<=1;//ビットシフトをして次に送るデータを準備
SPI_SCK_H;//クロックを更新
SPI_SCK_L;
    }
  }
  SPI_SS_H;


この写真はcmdbf[0]に入っているデータ00000101を送信している状態で、
黄色がMOSIで青がSCKです。


0 件のコメント: