SPIの実験2

〔ArduinoとPIC16F819で通信と基礎編〕 [SPIデバイスを複数個接続する] 〔マイコンのトップに戻る〕


前回のSPI実験ではAduino(マスター)とPIC16F819(スレーブ)で通信を行ってみました。
PIC12F1822が手に入ったのでこれに有るSPI(MSSP)機能の勉強がてらSPI実験2を行いました。
今回はPIC12F1822(マスター)とPIC16F819(スレーブ)で通信をしてみます。
SPIの概要などの基本とPIC16F819(スレーブ)操作は前回のSPI実験を参照して下さい。

配線

接続図2  左図の様に接続します。
 今回、SSは接続しません。
 12F1822からデータを1バイトずつ1秒毎に
 送信します。
 16F819はデータを受信したら1バイト毎に
 LCDのモニターに送ります。
 下の写真が別途作成したモニターです。
 モニターの作成はこちらを参照して下さい。  モニター写真

PIC12F1822のピン構成
接続図1

PIC12F1822の操作

HI-TECH C Compiler for PIC10/12/16 MCUs(Lite Mode)V9.80コンパイラでの説明です。
次の順番で行って行きます。(マスター設定です

@SDO出力ピンの選択
 SDOSEL = 0 ; // 7番ピン(RA0)をSDOピンに設定
 SDOSEL = 1 ; // 3番ピン(RA4)をSDOピンに設定(今回はこちらを選択)

ASSP1CON1レジスタの設定
 SSP1CON1=0b00100001 ;
       緑数字部分:クロック極性 0:LOW(アイドルは0V、アクティブは5V)
                    1:HIGH(アイドルは5V、アクティブは0V)
       赤数字部分:SCKの生成クロック選択とマスター・スレーブの選択
              '0000' = Fosc/4
              '0001' = Fosc/16
              '0010' = Fosc/64
              '0011' = TMR2の出力の1/2
              '0100' = スレーブモードでSS使う
              '0101' = スレーブモードでSS使わない
              '1010' = Fosc/(4*(SSP1ADD+1)) : SSP1ADDは8ビットレジスタ
              (尚、'0100'と'0101'以外はマスター選択です)
             それ以外の数字部分はこのまま('001')使用します。

BSSP1STATレジスタの設定
 SSP1STAT=0b00000000 ;
       緑数字部分:スレーブなら 0
             マスターなら 0:入力データの中央でサンプリング
                    1:入力データの末尾の縁でサンプリング
       赤数字部分:クロック位相 0:アイドルからアクティブへ変化した時データ送信
                      極性LOW( ___| ̄|___ )   極性HIGH(  ̄|___| ̄ )
                    1:アクティブからアイドルへ変化した時データ送信
                      極性LOW( ___| ̄|___ )   極性HIGH(  ̄|___| ̄ )
       青数字部分:SSP1BUFの受信状態 1:受信完了 0:受信未完了

C割込みの許可
 SSP1IF= 0 ; // SPIの割込みフラグを初期化する
 SSP1IE= 1 ; // SPIの割込みを許可する
 PEIE = 1 ;  // 周辺装置割込みを許可する
 GIE = 1 ;  // 全割込み処理を許可する

DSSP1BUFにデータをセットすれば送信されます。

スレーブにする場合の操作

上図のピン構成の様にSSピン入力が2本有るので使用する場合は選択しないといけません。
 SSSEL = 0 ;    // 4番ピン(RA3)側をSSピンに選択する
 SSSEL = 1 ;    // 7番ピン(RA0)側をSSピンに選択する
 とします、もちろん選択したピンはデジタル入力に設定しておきます。

PIC(12F1822)側のプログラム例

MPLABにてプロジェクトを作成して新規ファイルにコピーペーストして貼り付けて下さい。
次にコンパイルPIC書き込みを実行して下さい。
16F819からのデータは受信していません、データを送るだけのプログラムです。
---------------------------------------------------------------------
#include <pic.h>
#include <htc.h>               // delay用

#define _XTAL_FREQ 4000000    // delay用に必要(クロック4MHzを指定)

// コンフィギュレーション1の設定
// CLKOUTピンをRA4ピンで使用する(CLKOUTEN_OFF):内部クロック使用する(INTIO)
// 外部クロック監視しない(FCMEN_OFF):外部・内部クロックの切替えでの起動はなし(IESO_OFF)
// 電源電圧降下常時監視機能ON(BOREN_ON):電源ONから64ms後にプログラムを開始する(PWRTEN_ON)
// ウオッチドッグタイマー無し(WDTE_OFF):
// 外部リセット信号は使用せずにデジタル入力(RA3)ピンとする(MCLRE_OFF)
// プログラムメモリーを保護しない(CP_OFF):データメモリーを保護しない(CPD_OFF)
__CONFIG(CLKOUTEN_OFF & FOSC_INTOSC & FCMEN_OFF & IESO_OFF & BOREN_ON &
         PWRTE_ON & WDTE_OFF & MCLRE_OFF & CP_OFF & CPD_OFF) ;
// コンフィギュレーション2の設定
// 動作クロックを32MHzでは動作させない(PLLEN_OFF)
// スタックがオーバフローやアンダーフローしたらリセットをする(STVREN_ON)
// 低電圧プログラミング機能使用しない(LVP_OFF)
// Flashメモリーを保護しない(WRT_OFF):電源電圧降下常時監視電圧(2.5V)設定(BORV_25)
__CONFIG(PLLEN_OFF & STVREN_ON & WRT_OFF & BORV_25 & LVP_OFF);

// 指定した時間(numx10ms)だけウエイトを行う処理関数
void Wait(unsigned int num)
{
     int i ;

     // numで指定した回数だけ繰り返す
     for (i=0 ; i<num ; i++) {
          __delay_ms(10) ;     // 10msプログラムの一時停止
     }
}
// メインの処理
void main()
{
	int i ;

     OSCCON = 0b01101010 ;     // 内部クロックは4MHzとする
     ANSELA = 0b00000000 ;     // アナログは使用しない(すべてデジタルI/Oに割当てる)
     TRISA  = 0b00001100 ;     // RA2ピン以外を全て出力に割当てる(RA3は入力専用)
     PORTA  = 0b00000000 ;     // 出力ピンの初期化(全てLOWにする)

     // SPIモードの設定と初期化
     SDOSEL   = 1 ;            // 3番ピン(RA4)をSDOピンに設定
     SSP1CON1 = 0b00100001 ;   // クロック極性はLOW マスタモードでFOSC/16のクロックに設定
     SSP1STAT = 0b00000000 ;   // クロック位相は0、アイドル(0V)→アクティブ(5V)時にデータ送信 *2)
     SSP1IF = 0 ;              // SPIの割込みフラグを初期化する
     SSP1IE = 1 ;              // SPIの割込みを許可する
     PEIE   = 1 ;              // 周辺装置割込み有効
     GIE    = 1 ;              // 全割込み処理を許可する

     Wait(500) ;  // 5秒後に開始

     while(1) {
          // LCDに表示しやすい用にキャラクター文字を送っています。
          for (i = 0x30 ; i < 0x7b ; i++) {
	          SSP1BUF = (char)i ;
               Wait(100) ;  // 1秒毎に送る
          }
     }
}
---------------------------------------------------------------------
こんな感じでテストしました。
実験風景

まとめ



今後は、SPI機器(センサーかSDカード)を購入して実験3を再開します。
ちなみに、「マイクロSDシールド(Arduino)買って見ました!」の記事は有ります。
PIC16F1938を利用してMMC/SDCにアクセス(読み書き)する記事追記しました、こちらを参照下さい。
PICのSPIでEEPROM(AT93C86)と接続して読み書きを行って見ますの記事はこちらを参照下さい。

「SPIのマスタープログラムが動作しない」と言う人はこちらの記事を参考にしてみて下さい。 *1)



記事一部変更(*2) 2016/06/13
追記(*1) 2012/02/27


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.