YS電子工作ラボ

<V.3版>

SP I 制御による
  フラッシュメモリ読み書き

                                   (→プロジェクトファイル(Harmony Ver.3版 MHC v3.6.0) ダウンロード



<仕様>
  ・ SPIインターフェースをもつフラッシュメモリへの読み書きをおこなう
  ・ フラッシュメモリは マイクロチップのSST25VF016(メモリ容量: 16Mビット)とする

  ・ PIC32MZが立ち上がったら キャラクタ液晶の表示テストとして以下を表示する。
    1行目 …… SPI Module
    2行目 …… Start Test 1


  ・ その後、フラッシュメモリの先頭アドレスはすべて同じ の0x00005678 として以下を順次行う。
    ① セクタを消去後、 文字列 "Hellow World"を書き込む
       1秒後 書き込んだ文字列をすべて読みだす。
       読み出した文字列を以下の要領で液晶の2行目に表示する。
        1行目 …… 1st
        2行目 …… Str=Hellow World
       
       2秒間表示する。

    ②  セクタを消去後、 文字列 "PIC32MZ Run"を書き込む
       1秒後 書き込んだ文字列をすべて読みだす。
       読み出した文字列を以下の要領で液晶の2行目に表示する。
        1行目 …… 2nd
        2行目 …… Str=PIC32MZ Run
       
       2秒間表示

    ③   セクタを消去後、 文字列 "SPI Flash"を書き込む
       1秒後 書き込んだ文字列をすべて読みだす。
       読み出した文字列を以下の要領で液晶の2行目に表示する。
        1行目 …… 3rd
        2行目 …… Str=SPI Flash

  ・ PIC(PIC32MZ2048EFH100)側のSPI制御に関する諸元は以下とする。
    SPIモジュール: SPI2
    マスター/スレーブモード: マスター 
    クロックモード: LOW/アイドル時、 クロックがActive→idleに変化した時データ変化(Clock Edge Fall control)
               MCHでのClockMode設定 → DRV_SPI_CLOCK_MODE_IDLE_LOW_EDGE_FALL
    データ幅: 8ビット
    SPI転送クロック周波数: 1MHz
    データ抽出タイミング: データの後縁
    ポート: SDI : RG7
          SDO: RG8
          SCK: RG6
          CS:  RA0

  ・ HarmonyのSPIライブラリはダイナミックタイプとする。

<回路図> (→ PDFファイル




<外観> PIC32MZ評価ボード(→購入方法)を使った実験品の外観です。
      汎用モジュール評価ボード(段積みボード)には本テーマと関係ない部品が多々実装されています。



<動作結果> ( → 動画:1080pのHD動画を見ることができます。)  

   キャラクタ液晶画面 
キャラクタ液晶の表示テスト
PIC32MZ起動直後 
"Hellow World"を書き込み
読み出して表示 
"PIC32MZ Run"を書き込み
読み出して表示
 "Spi Flash"を書き込み
読み出して表示
 




<解説> 記載してある内容は要点だけです。 詳細はプロジェクトファイルを精読願います。

 ステップ1:   MHC作成

項目 1. [Clock Diagram]タブで、クロックの構成を外付け24MHz水晶発振器用、システムクロック200MHzに設定します。
 POSCMOD: → EC
 FPLLICLK: → POSC
 FPLLIDIV: → DIV_3
2. [Pin Settings]タブでの設定
■ピン17のRA0ポート
 Name: → CS
 Function: → GPIO
 Direction(TRIS): → Out
■ピン10のRG6ポート
 Function: → SCK2
■ピン11のRG7ポート
 Function: → SDI2
■ピン12のRG8ポート
 Function: → SDO2
3. [Prpject Graph]タブでの設定
■追加コンポーネント
 CORE, SPI2, SPI
■ コンポーネント間の接続
 SPI2 -  SPI
■コンポーネント設定
 ClockPolarity Select bit:
 →Idele state for clock is a low level; active state is a
    high level

 SPI clock edge select bit
 →Serial output data changes on transition from
    active clock state to Idel stae
MHC






  ステップ2


 ■ キャラクタ液晶表示のライブラリ 1lcd_lib_XC32.h と 1lcd_lib_XC32.cを main.cと同じフォルダにコピーして、プロジェクトに追加します。
     (詳細→ キャラクタ液晶表示方法 参照


 ■ app.cに、青字部分を追加します。 

   ① stdio.h 、1lcd_lib_XC32.h、definitions.hをインクルードします。
     stdio.hをインクルードしないと sprintfがあるのでコンパイルで警告がででしまいます。
      #include "stdio.h"
      #include "1lcd_lib_XC32.h"

      #include "definitions.h"


   ② プログラムをみやすくするために、SST25VF016Bへの制御コマンドを定義しておきます。
      #define ysSST25_CMD_READ (unsigned)0x03 //Read instruction, 03H,
      #define ysSST25_CMD_WRITE (unsigned)0x02 //Page-Program instruction, 02H //To program up to 256 Bytes
      ……
      ……



   ③ 読み書きするフラッシュメモリのアドレス、読み書きする文字列などを定義しておきます。
      unsigned int adrStr = 0x00005678; //読み書きするSPIフラッシュの先頭アドレス
      char* str;
      char str_Hellow[] = "Hellow World";
      char str_PIC32MZ[] = "PIC32MZ Run";
      char str_SpiFlash[] = "Spi Flash";
      …… 
      ……


   ④ delay_us( )、delay_ms( ) と云う NOPを利用した 1μsec、1msecの遅延関数を作成しておきます。
      void delay_us(volatile unsigned int usec) //1μsec遅延
      {
         volatile int count;
      ……
      ……


   ⑤ フラッシュメモリに文字列を書き込む関数を作成しておきます。

  void ysSPIPut(unsigned char data) //SPIバッファへ書き込み
  {
    while(!SPI2STATbits.SPITBE); //送信バッファーが空になるまで待つ

    SPI2BUF = data; //送受信バッファにデータを書き込む
    //SPI2_Write(&data, sizeof(data)); //★ 動作せず
    //DRV_SPI_WriteTransferAdd(spi_Handle, &data, sizeof(data), &transferHandle); //★動作せず

    while(!SPI2STATbits.SPIRBF); //受信完了(バッファフル)まで待つ

    return;
  }


  unsigned char ysSPIGet (void) //SPIバッファの取得
  {
    unsigned char spiData = 0;

    spiData = SPI2BUF; //送受信バッファのデータを読込む
    //DRV_SPI_ReadTransferAdd(spi_Handle, &spiData, sizeof(spiData), &transferHandle);//★動作せず
    //SPI2_Read(&spiData, sizeof(spiData));//★動作せず

    return spiData;
  }




   ⑥ APP_Initialize( )の中で lcd_init()でキャラクタ液晶を初期化したあと 液晶に"SPI Module"と"Start Test 1"を表示させます。
      lcd_init(); // LCD初期化
      lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF
      ……
      ……


   ⑦ PLIB_SPI_Enable(SPI_ID_2); でSPI2モジュールを有効にした後、ysSST25ResetWriteProtection(); でフラッシュメモリのライト
      プロテクトを解除します。
       PLIB_SPI_Enable(SPI_ID_2); //SPIモジュール イネーブル
      // SPI2CONbits.ON = 1; //SPI2 有効
      ysSST25ResetWriteProtection(); //SPIフラッシュメモリ ライトプロテクト解除


   ⑧ ・ ysSST25SectorErase( ); でフラッシュメモリのアドレスadrStr(0x00005678)からはじまる1セクタを消去します。
     ・ ysSST25WriteArray(); で先頭アドレスをadrStrとして文字列str_Hellow("Hellow World")をフラッシュメモリに書き込みます。
     ・ 100msec待ちます。
     ・ 液晶の1行目に "1st"を表示します。
     ・ ysSST25ReadArray() ; でフラッシュメモリのadrStrから17バイト読み出します。
     ・ 読みだした文字を液晶の2行目に表示します。  
     ・ 2000 msec待ちます。
        ysSST25SectorErase(adrStr); //セクタ消去
       //ysSST25ChipErase(); //チップ消去

       ysSST25WriteArray(adrStr, str_Hellow, sizeof(str_Hellow)); ////文字列書き込み

       delay_ms(100);

       lcd_cmd(0x80); //1目の先頭へ
       sprintf(Buf,"1st "); //
       lcd_str(Buf); //液晶表示

       lcd_cmd(0xC0); //2行目の先頭へ

       str = &Buf[0]; // ポインタにアドレスを代入
       ysSST25ReadArray(adrStr, str, 17) ; //文字列読出し

       sprintf(Buf,"%s",str);
       sprintf(Buf2"Str=%s ",Buf);
       lcd_str(Buf2);

       delay_ms(2000);




   ⑨ 同様にして "PIC32MZ Run" と "SPI Flash" フラッシュメモリに書き込んだ後、読みだして液晶に表示します。


   ⑩ Harmony ver.3 では、エンハンストバッファーが有効になっているようなので無効にする必要があります。

  void ysEnhancedBuffer_Disable(void) //エンハンストバッファー 無効化関数
  //Harmony ver.3 ではデフォルトで Enhanced Bufferがイネーブルになっている。
  {
    //Enhanced Buffer mode is disabled
    SPI2CONbits.ENHBUF = 0; //エンハンスト バッファー 無効 //b16 ENHBUF: Enhanced Buffer Enable bit
  }





以下、app.c 全文