YS電子工作ラボ

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

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



<仕様>
  ・ 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"を書き込み
読み出して表示
 




<解説> 記載してある内容は要点だけです。 詳細はプロジェクトファイルを精読願います。
       (以下は、Harmony v2.04 をもとに作成しています。最新のバージョンとは異なることがあるかもしれませんので注意してください。)
 
 ■ MHCは、以下のように設定します。

  ■ Options

項目 ①Config設定 
Device & Project Configuration
  > PIC32MZ2048 Device Configuration
②SPI設定1
Harmony Framework Configuration > Drivers
 > SPI
MHC
備考 デフォルトからの変更要領:
 FPLLIDIV: DIV3
 FPLLICLK: PLL_POSC
 POSCMOD: EC

システムクロック周波数: 200MHz
外部OSC: 24MHz
タイマ用ペリフェラルクロック
     周波数(PBCLK3): 100MHz


#pragma config FNOSC = SPLL
#pragma config POSCMOD = EC
#pragma config FPLLIDIV = DIV_3
#pragma config FPLLICLK = PLL_POSC
#pragma config FPLLMULT = MUL_50
#pragma config FPLLODIV = DIV_2 
デフォルトからの変更要領:
 □Use SPI Driver? チェックを入れる
 □Use Interrupt Mode? チェックをはずす
 □Use Polled Mode? チェックを入れる
 □Use Standard Buffer? チェックを入れる
 
項目 ③SPI設定2
Harmony Framework Configuration > Drivers
 > SPI
 
MHC    
備考 デフォルトからの変更要領:
 SPI Mocule ID: SPI_ID_2
 □Use Polled Mode? チェックを入れる
 Clock Mode: DRV_SPI_CLOCK_MODE_IDLE_LOW_EDGE_FALL
 

   ■ Pin Settins

項目 ④ポート設定
MHC
備考 デフォルトからの変更要領:
 RA0/Function: GPIO_OUT
        (CS用出力ポート設定)
 RG6/Function: SCK2
        (SPI2のSCK設定)
 RG7/Function: SDI2
        (SPI2のSDI設定) 
 RG8/Function: SDO2
        (SPI2のSDO設定) 




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


 ■ app.cに、青字部分を追加します。 Harmonyが生成する他のファイルの修正は不要です。

   ① stdio.h と1lcd_lib_XC32.hをインクルードします。
     stdio.hをインクルードしないと sprintfがあるのでコンパイルで警告がででしまいます。
      #include "stdio.h"
      #include "1lcd_lib_XC32.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;
      ……
      ……


   ⑤ フラッシュメモリに文字列を書き込む関数を作成しておきます。
      ・ SPI2用に特化されています。
      ・ 動作が分かりやすいように、Harmonyのライブラリ関数の下の//の後に等価なレジスタコマンドを併記してあります。
      void ysSPIPut(unsigned char data) //SPIバッファへ書き込み
      {
         //SPI2の場合
         while(!PLIB_SPI_TransmitBufferIsEmpty(SPI_ID_2));//送信バッファーが空になるまで待つ
         // while(!SPI2STATbits.SPITBE); //送信バッファーが空になるまで待つ
      ……
      ……


   ⑥ 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" フラッシュメモリに書き込んだ後、読みだして液晶に表示します。
  

以下、app.c