トップページ > dsPIC入門 > dsPICでSPI通信(3)

マスター側のプログラム

簡単な動作確認をします

それでは、2つのdsPICを組み合わせて簡単なSPI通信のプログラムを書いてみます。 ここではデバッグの基本として、何かアクションがあった場合に適当な文字列をUARTで PCへ送信することにします。

  1. 最初にマスターからスレーブへ文字を送信
  2. スレーブでは受信した文字をデバッグUARTでPCへ送信
  3. 今度はスレーブからマスターへ文字を送信
  4. マスター側で受信し、もともと来る予定だった文字と一致すればLED点灯

・・・という流れのプログラムをマスター、スレーブに分けて書いていきます。なお、dsPIC同士の通信ではなく 相手が何かのモジュールの場合はdsPICがマスターとなることが多いので、このマスター側プログラムだけを 書けばよいことになります。

これから書くプログラムのマスターはテストボード2(右)、 スレーブはテストボード1(左)です。 あまり重要ではありませんが、2つの回路ではLEDを光らせるポートが異なるので自分が忘れないために・・・(汗)

マスター側のソースコード


//********************************************************************
//SPIテスト(マスター) @dsPIC30F4012
//********************************************************************


//********************************************************************
//ヘッダファイル
#include "p30f4012.h"
#include "spi.h"


//********************************************************************
//コンフィギュレーション
_FOSC(CSW_FSCM_OFF & XT_PLL8);//10MHzセラロックを使っているのでクロックは80MHz。
_FWDT(WDT_OFF);
_FBORPOR(PBOR_ON & BORV_20 & PWRT_64 & MCLR_EN);
_FGS(CODE_PROT_OFF);


//********************************************************************
//SPIの設定パラメータ(マスター、送信有り、クロックは最も遅く設定)

unsigned int spi_config1 = FRAME_ENABLE_OFF & FRAME_SYNC_INPUT & ENABLE_SDO_PIN & 
                           SPI_MODE16_OFF & SPI_SMP_ON & SPI_CKE_OFF & MASTER_ENABLE_ON &
                           CLK_POL_ACTIVE_LOW & PRI_PRESCAL_64_1 & SEC_PRESCAL_8_1  ;

unsigned int spi_config2 = SPI_ENABLE & SPI_IDLE_CON & SPI_RX_OVFLOW_CLR;


//********************************************************************
//メイン関数

int main(void)
{

 //受信した文字を格納する変数
 unsigned char temp;

 //デバッグ用に、ポートEのLEDを使用します。
 TRISE = 0x00;
 PORTE = 0x00;
 //-------------------------------------------------------------------


 //SPI初期設定
 OpenSPI1(spi_config1,spi_config2);

 //もう一方の基板が受信待機状態になるまで、十分待ちます。
 wait();
 wait();
 wait();

 //-------------------------------------------------------------------
 //'a'を送信
 WriteSPI1('a');

 //送信完了まで待つ
 wait();

 //'b'を送信
 WriteSPI1('b');

 //送信完了まで待つ
 wait();

 //'b'を送信
 WriteSPI1('c');

 //送信完了まで待つ
 wait();
 //-------------------------------------------------------------------
 
 //デバッグ用。すべて文字を送信した時点でLEDを1つ点灯。
 PORTE = 0x01;


 //データが送られてくるまで待機
 while(!DataRdySPI1());
 
 //データが来たらLEDを2つ点灯。
 PORTE = 0x03;


 //1文字受信
 temp = ReadSPI1();

 //もし送られてきたデータが'd'なら・・・
 if(temp == 'd')
 {
  //LEDをすべて点灯。
  PORTE = 0xff;

  //ここでストップ。
  while(1);
 }

}


//********************************************************************
//送信待ち関数(ただの時間稼ぎ・・・)

void wait(void)
{
 unsigned long t;

 for(t=0;t<10000;t++)
 {

 }
}
//********************************************************************

SPIの初期設定:OpenSPI1()関数

void OpenSPI1(unsigned int config1,unsigned int config2)

SPIモジュールを使うために、初期設定をする関数です。 引数は2つあります。1つ目の引数はSPI通信の各種設定について、2つ目の引数はSPIモジュールのハードウェア的な 設定についてです。毎度のことですが、最初に変数を宣言してやる場合、 マクロを入れる変数はunsigned int型となります。


config1 : SPIの各種設定

フレーム化について

「フレーム化」は、常にクロックを出し続けて“/SS”ピンを通信の同期信号として使う特殊なSPI通信です。 これをを使うかどうかを決めます。


フレーム同期パルス方向

“SDO”ピン(出力信号ピン)ON・OFF

もしSPI通信において常に受信動作しかしない場合は、出力ピンである“SDO”ピンを無効にすることができます。

1回あたりの通信データ数

データをサンプリングするタイミング

いずれにせよ、マスター・スレーブ間で同じ設定にする必要があります。


出力データが変化するエッジタイミング

SPI通信の同期クロックは、通常“H”レベルで信号出力ごとに“L”レベルへ落とす場合と、逆に 通常“L”レベルで信号出力ごとに“H”レベルへ上げる場合があります。どちらにするかは、 コンフィグによります。ここでは「アクティブ」と「非アクティブ」の間でどちらからどちらへ信号が変化した 場合に出力とするかを設定します。


マスター・スレーブの設定

同期クロック極性

第一プリスケーラ値

第二プリスケーラ値

SPIのクロックには、マイコンの設定クロックを4で割った値に、 第一プリスケーラの値と第二プリスケーラの値を掛け合わせた周波数が使われます。


config2 : SPIモジュールのハード的な設定

SPIモジュールのON・OFF
アイドルモードの設定

受信オーバーフロービットについて

このマクロを記述すると、SPIステータスレジスタのオーバーフロービットがクリアされます。

SPI用関数について

データ送信の時間待ちについて

コンパイル時の注意点




前へ   次へ