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ライブラリはダイナミックタイプとする。
<外観> PIC32MZ評価ボード(→購入方法)を使った実験品の外観です。
汎用モジュール評価ボード(段積みボード)には本テーマと関係ない部品が多々実装されています。
<動作結果> ( → 動画:1080pのHD動画を見ることができます。)
キャラクタ液晶画面 | |
キャラクタ液晶の表示テスト PIC32MZ起動直後 |
|
"Hellow World"を書き込み 読み出して表示 |
|
"PIC32MZ Run"を書き込み 読み出して表示 |
|
"Spi Flash"を書き込み 読み出して表示 |
|
<解説> 記載してある内容は要点だけです。 詳細はプロジェクトファイルを精読願います。
(以下は、Harmony v2.04 をもとに作成しています。最新のバージョンとは異なることがあるかもしれませんので注意してください。)
■ MHCは、以下のように設定します。
■ Options
■ 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