Renesas Synergy™

FAQ 1006546 : 78K0/Kx2のCSIによるSPI・EEPROMの制御プログラム例(78K0/Kx2)

[はじめに]
SPIの概要やSPIインタフェースのEEPROMについては「FAQ 1006544 : CSIによるSPIメモリの制御(78K0/Kx2他)」を参照してください。ここでは下記の接続例に示したEEPROMを2個接続した場合に対応した具体的な制御プログラムについて説明します。また、制御プログラムの使い方についても簡単に触れておきます。



[78K0/Kx2の処理例]
78K0/Kx2でのEEPROMの制御処理は以下の部分で構成します。内部で使用するサブルーチン以外はC言語からの使用を意識して、名前と入出力パラメータ(引数と戻り値)を決めています。例えば引数として、読み出しや書き込みでは以下のパラメータを用います。
第1パラメータ(AX渡し):EEPROMのアドレス
第2パラメータ(スタック渡し):バッファ・メモリのアドレス
第3パラメータ(スタック渡し):転送データ数で1~255及び0(256バイト)

(1)初期化部
ポート、CSI10、割り込みの初期化を行ないます。ここでは2.7VPOCを使用することで、リセット解除後にはそのまま動作させます。基本的にベクタ割り込みは使用しないので、割り込みは禁止状態とします。

(2)EEPROM選択処理
P13~17をCSに使用することで、最大5つの中から一つを選択します。この処理では、単に作業領域に対象とするEEPROMの番号(Xレジスタ渡しで、1~5の値)からCS信号に対応したビット・パターンをセットするのみで、その値をCS信号の制御で用いるだけです。

(3)CS信号出力処理
EEPROMへの実際のアクセス時にCS信号をONにしたり(ロウ・レベルにする)、OFF(ハイ・レベルにする)したりするための内部処理ルーチンです。P1の内容を読み出して、CS信号に該当するビットを反転させてP1に書き戻しています。

(4)ステータスの確認
EEPROMがデータ書き込み中かどうかをチェックします。内部でEEPROMへの書き込みやデータの読み出しを行なう前に使用します。

(5)書き込み許可
対象のEEPROMのCS信号をONにして、「WREN」コマンドを送ります。コマンド転送完了後CS信号をOFFにします。このコマンドによりEEPROMは書き込み可能状態になります。

(6)書き込み禁止
対象のEEPROMのCS信号をONにして、「WRDI」コマンドを送ります。コマンド転送完了後CS信号をOFFにします。このコマンドによりEEPROMは書き込み禁止状態になります。

(7)ステータス・レジスタの読み出し
対象のEEPROMのCS信号をONにして、「RDSR」コマンドを送り、ステータス・レジスタの状態を1バイトのデータで読み出します。読み出し完了後、CS信号をOFFにします。ステータス・レジスタのビットの意味は [ステータス・レジスタ]を参照してください。

(8)ステータス・レジスタへの書き込み
対象のEEPROMのCS信号をONにして、「WRSR」コマンドを送り、引き続いてステータス・レジスタにセットする1バイトのデータを書き込みます。書き込みデータの転送完了後CS信号をOFFにします。
通常はブロック毎のプロテクトの制御(ビット2,3)に使用します。

(9)データの読み出し1
512バイト以下の(従って、アドレスは1バイトでA8はコマンドで指定)容量のEEPROMから256バイト以下のデータを読み出します。EEPROMのステータスを確認し、書き込み中でなければ、指定されたパラメータでの読み出しを行ないます。

(10)データの読み出し2
1Kバイト以上の(ただし、アドレスは2バイト)容量のEEPROMから256バイト以下のデータを読み出します。EEPROMのステータスを確認し、書き込み中でなければ、指定されたパラメータでの読み出しを行ないます。

(11)データの書き込み1
512バイト以下の(従って、アドレスは1バイトでA8はコマンドで指定)容量のEEPROMに256バイト以下のデータを書き込みます。EEPROMのステータスを確認し、書き込み中でなければ、書き込み許可コマンドを発行し、指定されたパラメータでの書き込みを行ないます。
EEPROMへのデータ転送だけしか行なわないので、実際にEEPROMで書き込みが完了するまでは別の処理を並行して行なうことができます。なお、この間のEEPROMへのアクセスは、ステータス・レジスタの読み出し以外は行なわないようにしてください。

(12)データの書き込み2
1Kバイト以上の(ただし、アドレスは2バイト)容量のEEPROMに256バイト以下のデータを書き込みます。EEPROMのステータスを確認し、書き込み中でなければ、書き込み許可コマンドを発行し、指定されたパラメータでの書き込みを行ないます。
アドレス長が異なる以外は「データ書き込み1」と同じです。

(13)書き込み完了待ち
データ書き込み後に、実際にEEPROMでのデータ書き込み完了を待ちます。データ書き込みを行なった後はこの処理を実行するか、ステータス・レジスタを読み出して、ビット0が0になった(書き込みが完了した)ことを確認してください。

(14)バイト転送完了待ち
1バイトのデータ転送が完了したかを割り込み要求フラグをポーリングすることで待ち合わせます。転送が完了して、割り込み要求フラグがセットされたことを確認したら、フラグをクリアして戻ります。これは内部処理だけで使用します。

[アセンブラでのプログラム例]
このプログラム例では他のプログラムからこのプログラムの処理を使えるように、以下の10個のサブルーチンをパブリック宣言しています。これらは、アセンブラから使う場合やC言語のプログラムから使う場合も考慮しています。アセンブラから使用する場合には大文字の名前をEXTRN宣言してください。C言語のプログラムから使う場合には_で始まる名前をextern宣言(例えば、extern _selprom のように_を一つにして宣言)してください。

	PUBLIC	__selprom,SELPROM	; アクセスするEEPROMを選択
PUBLIC __writeenb,WRITEENB ; 書き込み許可にする
PUBLIC __writedis,WRITEDIS ; 書き込み禁止にする
PUBLIC __readst,READST ; ステータス・レジスタのリード
PUBLIC __writest,WRITEST ; ステータス・レジスタへのライト
;
PUBLIC __read_spi_block1,READBLOCK1
; 512バイト以下のEEPROMからのデータ・リード
PUBLIC __read_spi_block2,READBLOCK2
; 1Kバイト以上のEEPROMからのデータ・リード
PUBLIC __write_spi_block1,WRITEBLOCK1
; 512バイト以下のEEPROMへのデータ・ライト
PUBLIC __write_spi_block2,WRITEBLOCK2
; 1Kバイト以上のEEPROMへのデータ・ライト
;
PUBLIC __waitwt,WAITWT ; 書き込み完了待ち

また、内部で使用する作業領域の宣言や値の定義を前もって行なっています。

;
; 使用EEPROM数の定義
;
; EEPROMは5個を最大としてP13から順にP17を
; CS信号に割り当てるものとします。
; ポートの有効利用のために使用する最大数を定義します。
; 接続するEEPROMの個数に合わせてROMNOの値を変更。
;
ROMNO EQU 2 ; ここでは2個としておく

;
; EEPROMのコマンド
;
WRENC EQU 00000110b ; 書き込み許可
WRDIC EQU 00000100b ; 書き込み禁止
RDSRC EQU 00000101b ; ステータス・レジスタのリード
WRSRC EQU 00000001b ; ステータス・レジスタへの書き込み
READC EQU 00000011b ; データ読み出し
WRITEC EQU 00000010b ; データ書き込み

WDATA DSEG SADDR
CSFLAG:
DS 1 ; CS信号用データ
RxCOUNT:
DS 1 ; 受信データ用カウンタ
TxCOUNT:
DS 1 ; 送信データ用カウンタ

(1)初期化部
ポートやCSI10の動作モードを設定します。ここではベクタ割り込みを使用しないので、割り込みはマスクしておきます。

;
; ポートやCSI10のイニシャライズ
;
MOV P1,#11111011b ; 出力ラッチの設定
MOV PM1,#00000010b ; SI10/P11以外は出力に
MOV CSIC10,#00000000b ; 初期値と同じ
; |||||+++--------: シリアルクロックはfPRS/2
; |||++-----------: タイプ1
; +++-------------: 0に固定
MOV CSIM10,#01000000b ; MSBファースト、送受信モード
; ||+|++++--------; 0に固定
; || +------------; MSBファースト
; |+--------------; 送受信モード
; +---------------; 動作禁止
;
MOV PCC,#0
SET1 CSIMK10 ; CSI10の割り込みマスク
CLR1 CSIIF10 ; 割り込み要求フラグのクリア
SET1 CSIE10 ; CSI10の動作許可

(2)EEPROM選択処理
Xレジスタで指定(1~ROMNO)されたEEPROMに対応したCS信号のビット位置パターンを作成します。接続しているEEPROMの数をROMNOで定義しておくことで、それ以上が指定された場合にはエラーを戻します(なお、0はチェックしていません。)
最初にこのルーチンでEEPROMを選択することで、以降の処理でEEPROMの番号指定を省略します。EEPROMが1個のみの場合にはこの処理はなくても構いません。
(以降のプログラム例では外部から使用するサブルーチンはアセンブラで使用する場合(内部使用)に加えてC言語から使用する場合用に名前を2つ定義しています。)

;
; EEPROMの選択
; <機能>
; 引数で指定されたEEPROMをアクセス対象に設定します。
;ここではCS用のビットイメージを抽出して作業領域に保存します。
;実際のCS信号出力はCSOUTサブルーチンで行ないます。
;
; <入力パラメータ(引数)> 
; X :選択するROMの番号(1~ROMNO)を引数とする
; <戻り値>
; CF :エラーならキャリー・フラグをセットして戻る
;bit _ selprom(unsigned char spi_adr)

__selprom:
SELPROM:
MOV A,#ROMNO ; 選択する番号を最大数と比較して、
CMP A,X ; 大きければキャリー・フラグをセット
BC $EXITS ; して処理を終了する。
MOV A,#00000100B ; CS信号ビットへの変換
SELLOOP:
ROL A,1 ; CS信号を上位ビットへシフト
DEC X ; ROM番号を-1
BNZ $SELLOOP ; 目的のビット位置まで繰り返す
MOV CSFLAG,A ; CSフラグに結果を格納

EXITS:
RET

(3)CS信号出力処理
EEPROMへのCS信号のON/OFF処理を行なうプログラムです。ここで、上記のEEPROM選択処理の結果のビット・パターンを使用して、P1を制御して、実際にCS信号の制御を行ないます。実際の処理はP1のビットの反転処理ですので、必ず初期状態が決まっている必要があります。
EEPROMが1個の場合には、P1を直接ビット操作した方が簡単です。

;
; CS信号の出力
; <機能>
; 前もって作業領域に設定した内容に基づきCS信号出力の状態を
;反転します。
;
; <入力パラメータ(引数)> なし
; <戻り値> なし
;
CSOUT:
MOV A,P1 ; ポートの状態をリード
XOR A,CSFLAG ; CSビットを反転
MOV P1,A ; ポートから出力
RET

(4)ステータスの確認
EEPROMのステータス・レジスタを読み出すことで、書き込み動作中かをチェックします。EEPROMへのデータ転送開始時にEEPROMのステータス確認のために内部で使用します。

;
; EEPROMが書き込み処理中かのチェック
;
; <機能>
; EEPROMのステータス・レジスタを確認し、書き込み処理中
;ならばキャリ・フラグをセットして戻る
;
; <入力パラメータ(引数)> なし
; <戻り値>
; CF : 0 : 書き込み中ではない/ 1 : 書き込み中
;

CHKRDY:
PUSH BC ; レジスタをセーブ
CALL !READST ; ステータス・レジスタのチェック
MOV A,C
POP BC
ROR A,1 ; 書き込み中フラグをキャリへ
RET

(5)書き込み許可
対象のEEPROMに「WREN」コマンドを転送します。

;	書き込み許可コマンド発行
; <機能>
; 指定されているEEPROMを書き込み許可に設定します。
;
; <入力パラメータ(引数)> なし
; <戻り値> なし
;void _writeenb(void)

__writeenb:
WRITEENB:
CALL !CSOUT ; 対象のEEPROMを選択
MOV SOTB10,#WRENC ; コマンドをセット

WRITEENBLOOP: ; 転送完了割り込みを待つ
CALL !CSIRDY ; コマンド転送完了待ち
; コマンド完了でCSを解除
BR $CSOUT ; EEPROMの選択解除

(6)書き込み禁止
対象のEEPROMに「WRDI」コマンドを転送します。

;
; 書き込み禁止コマンド発行
; <機能>
; 指定されているEEPROMを書き込み禁止に設定します。
;
; <入力パラメータ(引数)> なし
; <戻り値> なし
;void _writedis(void)

__writedis:
WRITEDIS:
CALL !CSOUT ; 対象のEEPROMを選択
MOV SOTB10,#WRDIC ; コマンドをセット
BR $WRITEENBLOOP ; 完了待ち処理へ

(7) ステータス・レジスタの読み出し
対象のEEPROMに「RDSR」コマンドを転送し、EEPROMからのステータス・レジスタの内容を受け取ります。

;
; ステータス・レジスタのリード・コマンド
; <機能>
; 指定されているEEPROMのステータス・レジスタを読み出します。
;
; <入力パラメータ(引数)> なし
; <戻り値>
; C : 戻り値として、読み出したステータスが入ります
;
;unsigned char _readst(void)

__readst:
READST:
CALL !CSOUT ; 対象のEEPROMを選択
MOV SOTB10,#RDSRC ; コマンドをセット
CALL !CSIRDY ; コマンド転送完了待ち
MOV SOTB10,#0FFH ; 受信起動用にダミー書き込み
CALL !CSIRDY ; ステータス転送完了待ち
MOV A,SIO10 ; 受信データを読み出す
MOV C,A ; 戻り値をセット
BR $CSOUT ; CSを解除

(8) ステータス・レジスタへの書き込み
対象のEEPROMに「WRSR」コマンドを送り、引き続いてステータス・レジスタに設定する値を転送します。

;
; ステータス・レジスタへの書き込みコマンド
; <機能>
; 引数で渡された値を、指定されているEEPROMのステータス・
;レジスタに書き込みます。
;
; <入力パラメータ(引数)>
; X : 引数として書き込み値が入る
; <戻り値> なし
;void _writest(unsigned char st)

__writest:
WRITEST:
; CALL !WRITEENB ; 書き込み許可(一度設定すれば個別設定は不要)
CALL !CSOUT ; 対象のEEPROMを選択
MOV SOTB10,#WRSRC ; コマンドをセット
CALL !CSIRDY ; コマンド転送完了待ち
MOV A,X
MOV SOTB10,A ; ステータスの送信
CALL !CSIRDY ; ステータス転送完了待ち
BR $CSOUT ; CSを解除

(9)データの読み出し1
512バイト以下の容量のEEPROMから256バイト以下のデータを読み出します。
EEPROMが書き込み中でなければ、指定されたパラメータでの書き込みを行ないます。この際、指定されたEEPROMのアドレスが256番地より大きい場合にはリードコマンドのビット3をセットします。コマンドに引き続いて、アドレスを1バイト転送し、以降はEEPROMからのデータを読み出します。データの読み出しでは、ダミー・データとしてFFを書き込んで転送を起動します。読み出しが完了したら、CS信号をOFFにすることで、EEPROMに読み出しの完了を通知します。

;
; データの読み出し1
;
; <機能>
; 512バイト以下の容量のEEPROMに対して、引数として渡された
;パラメータで読み出しを行ないます。
; EEPROMが書き込み動作中でなければ指定された読み出しを実行し
;キャリー・フラグをクリアして戻ります。
; EEPROMが書き込み動作中なら、読み出しは行なわず、キャリー・
;フラグをセットして戻ります。
;
; <入力パラメータ(引数)>
; AX : 第1の引数 :EEPROM内のアドレス
; SP+2,3: 第2の引数 :バッファ・メモリのアドレス
; SP+4 : 第3の引数 :読み出しデータ数
;
; <戻り値>
; CF : 0 : 正常終了/ 1 : 書き込み動作中で処理中止
;
;bit _read_spi_block1(int reg_adr, unsigned char *data, unsigned char size)

__read_spi_block1:
READBLOCK1:
PUSH HL
PUSH AX
CALL !CHKRDY ; 書き込み中でないかチェック
BC $BUSYEXIT ; 書き込み中なら処理を中止
MOVW AX,SP ; 2つ目以降の引数を取り出す準備
MOVW HL,AX ; ポインタをHLレジスタに設定
CALL !CSOUT ; CS信号を出力
MOV A,[HL+1] ; EEPROMのアドレス上位を読み出す
AND A,#1 ; 256バイト以上かのチェック
ROL A,1
ROL A,1
ROL A,1 ; A8をビット3に移動
OR A,#READC ; リードコマンドを生成する
MOV SOTB10,A ; コマンドを送信
CALL !CSIRDY ; コマンド転送完了待ち
READBLOCK:
MOV A,[HL] ; アドレス下位を取り出す
MOV SOTB10,A ; アドレスを送信
MOV A,[HL+8] ; 転送データ数を取り出す
MOV RxCOUNT,A ; データ数を作業領域にコピー
MOV A,[HL+6] ; バッファ・アドレス下位を取り出す
MOV X,A
MOV A,[HL+7] ; 上位アドレスを取り出す。
MOVW HL,AX ; HLレジスタにアドレスを設定
CALL !CSIRDY ; アドレス転送完了待ち(不要)
;
; データ受信処理
;
READLOOP:
MOV SOTB10,#0FFH ; 受信用ダミー・データ書き込み
CALL !CSIRDY ; 受信完了待ち
MOV A,SIO10 ; 受信データの読み出し
MOV [HL],A ; 受信データをバッファへ
INCW HL ; ポインタを更新
DEC RxCOUNT ; 残りデータ数カウント
BNZ $READLOOP ; データ数分繰り返す。
CALL !CSOUT ; CS信号をきる
CLR1 CY ; エラー・フラグをクリア

BUSYEXIT: ; レジスタを復帰して戻る
POP AX
POP HL
RET

(10)データの読み出し2
1Kバイト以上の容量のEEPROMから256バイト以下のデータを読み出します。
EEPROMが書き込み中でなければ、指定されたパラメータでの書き込みを行ないます。この際、リードコマンドに引き続いて、アドレスを上位から順に2バイト転送し、以降はEEPROMからのデータを読み出します(以降はデータ読み出し1と共通なので、プログラムも共通化)。

;
; データの読み出し2
;
; <機能>
; 1kバイト以上の容量のEEPROMに対して、引数として渡された
;パラメータで読み出しを行ないます。
; EEPROMが書き込み動作中でなければ指定された読み出しを実行し
;キャリー・フラグをクリアして戻ります。
; EEPROMが書き込み動作中なら、読み出しは行なわず、キャリー・
;フラグをセットして戻ります。
;
; <入力パラメータ(引数)>
; AX : 第1の引数 :EEPROM内のアドレス
; SP+2,3: 第2の引数 :バッファ・メモリのアドレス
; SP+4 : 第3の引数 :読み出しデータ数
;
; <戻り値>
; CF : 0 : 正常終了/ 1 : 書き込み動作中で処理中止
;
;bit _read_spi_block2(int reg_adr, unsigned char *data, unsigned char size)

__read_spi_block2:
READBLOCK2:
PUSH HL
PUSH AX
CALL !CHKRDY ; 書き込み中でないかチェック
BC $BUSYEXIT ; 書き込み中なら処理を中止
MOVW AX,SP ; 2つ目以降の引数を取り出す準備
MOVW HL,AX ; ポインタをHLレジスタに設定
CALL !CSOUT ; CS信号を出力
MOV SOTB10,#READC ; リードコマンドを送信
CALL !CSIRDY ; コマンド転送完了待ち
MOV A,[HL+1] ; EEPROMのアドレス上位を読み出す
MOV SOTB10,A ; アドレスの上位を送信
CALL !CSIRDY ; アドレス転送完了待ち
BR $READBLOCK ; 下位アドレス送信以降のデータ受信処理へ

(11)データの書き込み1
512バイト以下の容量のEEPROMに256バイト以下のデータを書き込みます。EEPROMのステータスを確認し、書き込み中でなければ、書き込み許可コマンドを発行します。書き込むアドレスが256番地を超える場合には、コマンドのビット3をセットしたライトコマンドを発行し、続いて、EEPROMのアドレスを1バイト転送します。以降は指定されたパラメータでの書き込み(実際は転送)を行ないます。指定されたデータの転送が完了するとCS信号をOFFにして、EEPROMに転送完了を通知します。EEPROMはステータス・レジスタのビット0を1にして実際の書き込み動作を開始します。このプログラムでは、書き込み完了を待つ処理は行いません。従って、転送が完了し、EEPROMが書き込みを行なっているときに別の処理を行なうことができます。

;
; データの書き込み1
;
; <機能>
; 512バイト以下の容量のEEPROMに対して、引数として渡された
;パラメータで書き込みを行ないます。
; EEPROMが書き込み動作中でなければ指定された書き込みを実行し
;キャリー・フラグをクリアして戻ります。
; EEPROMが書き込み動作中なら、書き込みは行なわず、キャリー・
;フラグをセットして戻ります。
;
; <入力パラメータ(引数)>
; AX : 第1の引数 :EEPROM内のアドレス
; SP+2,3: 第2の引数 :バッファ・メモリのアドレス
; SP+4 : 第3の引数 :書き込みデータ数
;
; <戻り値>
; CF : 0 : 正常終了/ 1 : 書き込み動作中で処理中止
;
;bit _write_spi_block1(int reg_adr, unsigned char *data, unsigned char size)

__write_spi_block1:
WRITEBLOCK1:
PUSH HL
PUSH AX
CALL !CHKRDY ; 書き込み中でないかチェック
BC $EXITWRITE ; 書き込み中なら処理を中止
; CALL !WRITEENB ; 書き込み許可(一度設定すれば個別設定は不要)
MOVW AX,SP ; 2つ目以降の引数を取り出す準備
MOVW HL,AX ; ポインタをHLレジスタに設定
CALL !CSOUT ; CS信号を出力
MOV A,[HL+1] ; EEPROMのアドレス上位を読み出す
AND A,#1 ; 256バイト以上かのチェック
ROL A,1
ROL A,1
ROL A,1 ; A8をビット3に移動
OR A,#WRITEC ; ライトコマンドを生成する
MOV SOTB10,A ; コマンドを送信
CALL !CSIRDY ; コマンド転送完了待ち
WRITEBLOCK:
MOV A,[HL] ; アドレス下位を取り出す
MOV SOTB10,A ; アドレスを送信
MOV A,[HL+8] ; 転送データ数を取り出す
MOV TxCOUNT,A ; データ数を作業領域にコピー
MOV A,[HL+6] ; バッファ・アドレス下位を取り出す
MOV X,A
MOV A,[HL+7] ; 上位アドレスを取り出す。
MOVW HL,AX ; HLレジスタにアドレスを設定
CALL !CSIRDY ; アドレス転送完了待ち(不要)
;
; データ送信処理
;
WRITELOOP:
MOV A,[HL] ; 4:送信データの読み出し
MOV SOTB10,A ; 5:送信データ書き込み
INCW HL ; 4:ポインタを更新
CALL !CSIRDY ; :受信完了待ち
DEC TxCOUNT ; 4:残りデータ数カウント
BNZ $WRITELOOP ; 6:データ数分繰り返す。
CALL !CSOUT ; CS信号をきる
CLR1 CY ; エラー・フラグをクリア

EXITWRITE:
POP AX
POP HL
RET

(12)データの書き込み2
1Kバイト以上の容量のEEPROMに256バイト以下のデータを書き込みます。EEPROMのアドレスが2バイトになるだけで、その後の処理はデータ書き込み1と同じです。

;
; データの書き込み2
;
; <機能>
; 1Kバイト以上の容量のEEPROMに対して、引数として渡された
;パラメータで書き込みを行ないます。
; EEPROMが書き込み動作中でなければ指定された書き込みを実行し
;キャリー・フラグをクリアして戻ります。
; EEPROMが書き込み動作中なら、書き込みは行なわず、キャリー・
;フラグをセットして戻ります。
;
; <入力パラメータ(引数)>
; AX : 第1の引数 :EEPROM内のアドレス
; SP+2,3: 第2の引数 :バッファ・メモリのアドレス
; SP+4 : 第3の引数 :書き込みデータ数
;
; <戻り値>
; CF : 0 : 正常終了/ 1 : 書き込み動作中で処理中止
;
;bit _write_spi_block2(int reg_adr, unsigned char *data, unsigned char size)

__write_spi_block2:
WRITEBLOCK2:
PUSH HL
PUSH AX
CALL !CHKRDY ; 書き込み中でないかチェック
BC $BUSYEXIT ; 書き込み中なら処理を中止
; CALL !WRITEENB ; 書き込み許可(一度設定すれば個別設定は不要)
MOVW AX,SP ; 2つ目以降の引数を取り出す準備
MOVW HL,AX ; ポインタをHLレジスタに設定
CALL !CSOUT ; CS信号を出力
MOV SOTB10,#WRITEC ; ライトコマンドを送信
CALL !CSIRDY ; コマンド転送完了待ち
MOV A,[HL+1] ; アドレス上位を取り出す
MOV SOTB10,A ; アドレス上位を送信
CALL !CSIRDY ; 転送完了待ち
BR $WRITEBLOCK ; 下位アドレス以降の処理へ

(13)書き込み完了待ち
EEPROMのステータス・レジスタを読み出すことで、書き込み動作中かをチェックします。書き込みが完了していなければ、完了するまで確認処理を繰り返します。データ書き込み処理の後処理として使用します。

;
; 書き込み完了待ち
;
; <機能>
; EEPROMへのデータ転送後、CS信号が立ち上がると転送された
;データが実際に書き込みがおこなわれる。ここでは、完了するまで待つ。
;
; <入力パラメータ(引数)> なし
; <戻り値> なし
;
;void _waitwt(void)

__waitwt:
WAITWT:
PUSH BC ; レジスタをセーブ

WAITLOOP:
CALL !READST ; ステータス・レジスタのチェック
MOV A,C
ROR A,1 ; 書き込み中フラグをキャリー・フラグへ
BC $WAITLOOP ; 書き込み中ならループ
POP BC
RET

(14) バイト転送完了待ち
1バイトのデータ転送が完了したかを割り込み要求フラグをポーリングすることで待ち合わせます。内部で転送完了の待ち合わせで使用します。

;
; CSIの転送完了待ち
; <機能>
; CSIでの転送完了を割り込み要求フラグをポーリングして待ち、
; 転送完了したら、割り込み要求フラグをクリアして戻る。
; <入力パラメータ(引数)> なし
; <戻り値> なし
;

CSIRDY:
NOP
BF CSIIF10,$CSIRDY
CLR1 CSIIF10 ; 割り込み要求フラグをクリア
RET


[C言語でのプログラム例]
ここではC言語でプログラムを作成した場合のプログラム例を示します。大きな構成や外部のプログラムとのインタフェースなどはアセンブラ記述のプログラムと同じです。ただし、制御構造の記述の関係で変更した部分もあります。

(1)宣言及び定義部分
ここでは、関数のプロトタイプ宣言やSPIのコマンドの定義、変数の定義等を行なっています。

//
//  このモジュールはSPIによるEEPROMの
// 制御関数の例です(C言語記述)です。
//
#pragma SFR
#pragma NOP
void putspi(unsigned char data); // 1文字送信
unsigned char getspi(void); // 1文字受信
bit selprom(unsigned char spi_adr); // ROM選択
bit chkrdy(void); // 書き込み完了チェック
void writeenb(void); // 書き込み許可設定
void writedis(void); // 書き込み禁止設定
unsigned char readst(void); // ステータス・レジスタの読み出し
void writest(unsigned char st); // ステータス・レジスタへの書き込み
bit read_spi_block1(int reg_adr, unsigned char *data, unsigned char size);
// 512バイト以下のEEROMからの読み出し
bit read_spi_block2(int reg_adr, unsigned char *data, unsigned char size);
// 1kバイト以上のEEROMからの読み出し
bit write_spi_block1(int reg_adr, unsigned char *data, unsigned char size);
// 512バイト以下のEEROMへの書き込み
bit write_spi_block2(int reg_adr, unsigned char *data, unsigned char size);
// 1kバイト以上のEEROMへの書き込み
void waitwt(void); // 転送データの書き込み完了を待つ

/*------------------------------------------------------*/
/* */
/* SPI関連のコマンド定義 */
/* */
/*------------------------------------------------------*/

#define WRENC 0b00000110 // 書き込み許可
#define WRDIC 0b00000100 // 書き込み禁止
#define RDSRC 0b00000101 // ステータス・レジスタのリード
#define WRSRC 0b00000001 // ステータス・レジスタへの書き込み
#define READC 0b00000011 // データ読み出し
#define WRITEC 0b00000010 // データ書き込み

#define ROMNO 2 // 接続したEEPROMの数

static sreg unsigned char csflag; // CS生成用データ

(2)1文字送信関数
内部で使用するための関数で1文字分のデータをシリアル・チャネルを介してEEPROMに転送します。転送完了は割り込み要求(CSIIF10)をポーリングして確認します。EEPROMへの送信は全てこの関数を介して行ないます。

/*------------------------------------------------------------*/
/* */
/* シリアル送信処理 */
/* */
/* <機能> */
/* 引数で渡された8ビットのデータをシリアルで転送します。 */
/*転送が完了したら戻ります。 */
/* */
/* <入力パラメータ(引数)> */
/* 送信データ */
/* <戻り値> なし */
/* */
/*------------------------------------------------------------*/

void putspi(unsigned char data)
{
SOTB10 = data; // データをシリアルで送信
while(CSIIF10 == 0){ // 転送完了待ち
NOP();
}
CSIIF10 = 0; // 転送完了割り込みをクリア
}

(3) 1文字受信関数
この関数は、EEPROMからの1文字分のデータをシリアル・チャネル経由で受信します。

/*------------------------------------------------------------*/
/* */
/* シリアル受信処理 */
/* */
/* <機能> */
/* 8ビットのデータをシリアルで転送(受信)します。 */
/*転送が完了したら受信データを持って戻ります。 */
/* */
/* <入力パラメータ(引数)> なし */
/* <戻り値> */
/* 受信データ */
/* */
/*------------------------------------------------------------*/

unsigned char getspi(void)
{
unsigned char work;
SOTB10 = 0xff; // 受信のためのダミー・データ送信
while(CSIIF10 == 0){ // 転送完了待ち
NOP();
}
CSIIF10 = 0; // 転送完了割り込みをクリア
work = SIO10; // 受信データの読み出し
return work;
}

(4) EEPROMの選択関数
複数のEEPROMを接続した場合にどのEEPROMかを前もって設定するための関数です。1~ROMNOの値を引数として関数をコールしてください。

/*--------------------------------------------------------------*/
/* */
/* EEPROMの選択 */
/* */
/* <機能> */
/* 引数で指定されたEEPROMをアクセス対象に設定します。 */
/*ここではCS用のビットイメージを抽出して作業領域に保存します。 */
/*実際のCS信号出力はCSOUT関数で行ないます。 */
/* */
/* <入力パラメータ(引数)> */
/* EEPROMの番号 */
/* <戻り値> */
/* エラーならフラグをセットして戻る */
/* */
/*--------------------------------------------------------------*/

bit selprom(unsigned char spi_adr)
{
unsigned char work;
if(spi_adr > ROMNO) return 1;
work = 0b00000100;
csflag = work << spi_adr;
}

(5) EEPROMが書き込み中かのチェック関数
EEPROMが書き込み中でないかをステータス・レジスタにより確認するための内部で使用する関数です。

/*--------------------------------------------------------------*/
/* */
/* EEPROMが書き込み処理中かのチェック */
/* */
/* <機能> */
/* EEPROMのステータス・レジスタを確認し、書き込み処理中 */
/*ならばフラグをセットして戻る */
/* */
/* <入力パラメータ(引数)> なし */
/* <戻り値> */
/* 0 : 書き込み中ではない/ 1 : 書き込み中 */
/* */
/*--------------------------------------------------------------*/

bit chkrdy(void)
{
unsigned char work;
work = readst(); // ステータスレジスタの読み出し
return work & 0b00000001; // 結果を戻り値にセット
}

(6) CS信号の制御関数
EEPROMの選択関数で指定されたEEPROMに対するCS信号の出力を制御するための内部関数です。

/*--------------------------------------------------------------*/
/* */
/* CS信号の出力 */
/* <機能> */
/* 前もって作業領域に設定した内容に基づきCS信号出力の状態を */
/*反転します。 */
/* */
/* <入力パラメータ(引数)> なし */
/* <戻り値> なし */
/* */
/*--------------------------------------------------------------*/

void csout(void)
{
P1 = P1 ^ csflag; // CS 信号を反転
}

(7) 書き込み許可関数
選択されているEEPROMにWRENコマンドを転送します。EEPROMに書き込みを行なう場合には最初にこの処理を行なう必要があります。

/*--------------------------------------------------------------*/
/* */
/* 書き込み許可コマンド発行 */
/* <機能> */
/* 指定されているEEPROMを書き込み許可に設定します。 */
/* */
/* <入力パラメータ(引数)> なし */
/* <戻り値> なし */
/* */
/*--------------------------------------------------------------*/

void writeenb(void)
{
P1 = P1 ^ csflag; // CS 信号を反転
putspi(WRENC); // 書き込み許可コマンドを転送
P1 = P1 ^ csflag; // CS 信号を反転
}

(8) 書き込み禁止関数
選択されているEEPROMにWRDIコマンドを転送し、書き込み禁止にします。

/*--------------------------------------------------------------*/
/* */
/* 書き込み禁止コマンド発行 */
/* <機能> */
/* 指定されているEEPROMを書き込み禁止に設定します。 */
/* */
/* <入力パラメータ(引数)> なし */
/* <戻り値> なし */
/* */
/*--------------------------------------------------------------*/

void writedis(void)
{
P1 = P1 ^ csflag; // CS 信号を反転
putspi(WRDIC); // 書き込み禁止コマンドを転送
P1 = P1 ^ csflag; // CS 信号を反転
}

(9) ステータス・レジスタの読み出し関数
選択されているEEPROMからステータス・レジスタの内容を読み出します。ステータス・レジスタのビットの意味は[ステータス・レジスタ]を参照してください。

/*--------------------------------------------------------------*/
/* */
/* ステータス・レジスタのリード */
/* <機能> */
/* 指定されているEEPROMのステータス・レジスタを読み出す */
/* */
/* <入力パラメータ(引数)> なし */
/* <戻り値> */
/* 読み出したステータス */
/* */
/*--------------------------------------------------------------*/

unsigned char readst(void)
{
unsigned char work;
P1 = P1 ^ csflag; // CS 信号を反転
putspi(RDSRC); // コマンドを転送
work = getspi(); // ステータスの読み出し
P1 = P1 ^ csflag; // CS 信号を反転
return work;
}

(10) ステータス・レジスタへの書き込み関数
選択されているEEPROMのステータス・レジスタへの書き込みを行ないます。書き込むデータは個々のEEPROMで異なります。通常は、領域ごとのライト・プロテクトを設定するために使用します。

/*--------------------------------------------------------------*/
/* */
/* ステータス・レジスタへの書き込み */
/* 引数で渡された値を、指定されているEEPROMのステータス・ */
/*レジスタに書き込みます。 */
/* */
/* <入力パラメータ(引数)> */
/* :書き込み値 */
/* <戻り値> なし */
/* */
/*--------------------------------------------------------------*/

void writest(unsigned char st)
{
// writeenb(); // 書き込み許可に設定
P1 = P1 ^ csflag; // CS 信号を反転
putspi(WRSRC); // コマンドを転送
putspi(st); // 設定データを転送
P1 = P1 ^ csflag; // CS 信号を反転
}

(11) データ読み出し関数1
選択されているEEPROM(容量が512バイトまでのもの)からデータを読み出します。読み出すデータ数は最大256バイトまでです。デバイスの容量より多いデータ数を指定したときの動作はEEPROMに依存します。

/*----------------------------------------------------------------------*/
/* */
/* データの読み出し1 */
/* */
/* <機能> */
/* 512バイト以下の容量のEEPROMに対して、引数として渡された */
/*パラメータで読み出しを行ないます。 */
/* EEPROMが書き込み動作中でなければ指定された読み出しを実行し */
/*エラー・フラグをクリアして戻ります。 */
/* EEPROMが書き込み動作中なら、読み出しは行なわず、エラー・ */
/*フラグをセットして戻ります。 */
/* */
/* <入力パラメータ(引数)> */
/* 第1の引数 :EEPROM内のアドレス */
/* 第2の引数 :読み出したデータを格納するメモリのアドレス */
/* 第3の引数 :読み出しデータ数 */
/* */
/* <戻り値> */
/* 0 : 正常終了/ 1 : 書き込み動作中で処理中止 */
/* */
/*----------------------------------------------------------------------*/

bit read_spi_block1(int reg_adr, unsigned char *data, unsigned char size)
{
unsigned char work;
int count; // 受信データ数のカウンタ
if(chkrdy()) return 1; // 書き込み中ならエラーで戻る
P1 = P1 ^ csflag; // CS 信号を反転
if(reg_adr > 0xff){
work = READC | 0b00001000;
}else work = READC;
putspi(work); // コマンドを転送
work = reg_adr & 0xff; //
putspi(work); // アドレスを転送
if(size){
count = size;
}else count = 0x100; // 入力が0なら100Hに
do{
work = getspi(); // データの受信
*data++ = work;
}while(--count);
P1 = P1 ^ csflag; // CS 信号を反転(選択解除)
}

(12) データ読み出し関数2
選択されているEEPROM(容量が1K~64Kバイトまでのもの)からデータを読み出します。読み出すデータ数は最大256バイトまでです。デバイスの容量より多いデータ数を指定したときの動作はEEPROMに依存します。

/*----------------------------------------------------------------------*/
/* */
/* データの読み出し2 */
/* */
/* <機能> */
/* 1kバイト以上の容量のEEPROMに対して、引数として渡された */
/*パラメータで読み出しを行ないます。 */
/* EEPROMが書き込み動作中でなければ指定された読み出しを実行し */
/*エラー・フラグをクリアして戻ります。 */
/* EEPROMが書き込み動作中なら、読み出しは行なわず、エラー・ */
/*フラグをセットして戻ります。 */
/* */
/* <入力パラメータ(引数)> */
/* 第1の引数 :EEPROM内のアドレス */
/* 第2の引数 :バッファ・メモリのアドレス */
/* 第3の引数 :読み出しデータ数 */
/* */
/* <戻り値> */
/* 0 : 正常終了/ 1 : 書き込み動作中で処理中止 */
/* */
/*----------------------------------------------------------------------*/

bit read_spi_block2(int reg_adr, unsigned char *data, unsigned char size)
{
unsigned char work;
int count; // 受信データ数のカウンタ
if(chkrdy()) return 1; // 書き込み中ならエラーで戻る
P1 = P1 ^ csflag; // CS 信号を反転
putspi(READC); // コマンドを転送
work = reg_adr / 0x100; // 上位アドレスを抽出
putspi(work); // アドレスを転送
work = reg_adr & 0xff; // 下位アドレスを抽出
putspi(work); // アドレスを転送

if(size){
count = size;
}else count = 0x100; // 入力が0なら100Hに
do{
work = getspi(); // データの受信
*data++ = work;
}while(--count);
P1 = P1 ^ csflag; // CS 信号を反転(選択解除)
}

(13) データ書き込み関数1
選択されているEEPROM(容量が512バイトまでのもの)にデータを書き込みます。読み出すデータ数は最大256バイトまでです。デバイスの容量より多いデータ数を指定したときの動作はEEPROMに依存します。

/*----------------------------------------------------------------------*/
/* */
/* データの書き込み1 */
/* */
/* <機能> */
/* 512バイト以下の容量のEEPROMに対して、引数として渡された */
/*パラメータで書き込みを行ないます。 */
/* EEPROMが書き込み動作中でなければ指定された書き込みを実行し */
/*エラー・フラグをクリアして戻ります。 */
/* EEPROMが書き込み動作中なら、書き込みは行なわず、エラー・ */
/*フラグをセットして戻ります。 */
/* */
/* <入力パラメータ(引数)> */
/* 第1の引数 :EEPROM内のアドレス */
/* 第2の引数 :書き込みデータの格納されたバッファ・メモリのアドレス */
/* 第3の引数 :書き込みデータ数 */
/* */
/* <戻り値> */
/* 0 : 正常終了/ 1 : 書き込み動作中で処理中止 */
/* */
/*----------------------------------------------------------------------*/

bit write_spi_block1(int reg_adr, unsigned char *data, unsigned char size)
{
unsigned char work;
int count; // 送信データ数のカウンタ
if(chkrdy()) return 1; // 書き込み中ならエラーで戻る
P1 = P1 ^ csflag; // CS 信号を反転
if(reg_adr > 0xff){
work = WRITEC | 0b00001000;
}else work = WRITEC;
putspi(work); // コマンドを転送
work = reg_adr & 0xff; //
putspi(work); // アドレスを転送

if(size){
count = size;
}else count = 0x100; // 入力が0なら100Hに
do{
putspi(*data++); // 送信データ書き込み
}while(--count);
P1 = P1 ^ csflag; // CS 信号を反転(選択解除)
}

(14) データ書き込み関数2
選択されているEEPROM(容量が1K~64Kバイトまでのもの)にデータを書き込みます。読み出すデータ数は最大256バイトまでです。デバイスの容量より多いデータ数を指定したときの動作はEEPROMに依存します。

/*----------------------------------------------------------------------*/
/* */
/* データの書き込み2 */
/* */
/* <機能> */
/* 1kバイト以上の容量のEEPROMに対して、引数として渡された */
/*パラメータで書き込みを行ないます。 */
/* EEPROMが書き込み動作中でなければ指定された書き込みを実行し */
/*エラー・フラグをクリアして戻ります。 */
/* EEPROMが書き込み動作中なら、書き込みは行なわず、エラー・ */
/*フラグをセットして戻ります。 */
/* */
/* <入力パラメータ(引数)> */
/* 第1の引数 :EEPROM内のアドレス */
/* 第2の引数 : 書き込みデータの格納されたバッファ・メモリのアドレス */
/* 第3の引数 :書き込みデータ数 */
/* */
/* <戻り値> */
/* 0 : 正常終了/ 1 : 書き込み動作中で処理中止 */
/* */
/*----------------------------------------------------------------------*/

bit write_spi_block2(int reg_adr, unsigned char *data, unsigned char size)
{
unsigned char work;
int count; // 送信データ数のカウンタ
if(chkrdy()) return 1; // 書き込み中ならエラーで戻る
P1 = P1 ^ csflag; // CS 信号を反転
putspi(WRITEC); // コマンドを転送
work = reg_adr /0x100; // 上位アドレスを抽出
putspi(work); //
work = reg_adr & 0xff; //
putspi(work); // アドレスを転送

if(size){
count = size;
}else count = 0x100; // 入力が0なら100Hに
do{
putspi(*data++); // 送信データ書き込み
}while(--count);
P1 = P1 ^ csflag; // CS 信号を反転(選択解除)
}

(15)書き込み完了待ち関数
EEPROMに書き込みを行なったときに書き込みが完了するまで待つための関数です。ステータス・レジスタを読み出して書き込みが完了するまで待ちます。

/*----------------------------------------------------------------------*/
/*                                                                      */
/*                              書き込み完了待ち                        */
/*                                                                      */
/* <機能>                                                            */
/* EEPROMへのデータ転送後、CS信号が立ち上がると転送された              */
/*データが実際に書き込みがおこなわれる。ここでは、完了するまで待つ。    */
/*                                                                      */
/* <入力パラメータ(引数)> なし                                    */
/* <戻り値> なし                                                    */
/*                                                                      */
/*----------------------------------------------------------------------*/

void waitwt(void)
{
	while(readst() & 0b00000001);
}


[プログラム例の使用方法1]
ここでは、アセンブラ記述での使用方法の例を示します。

(1)宣言部
ここでは上で説明したプログラム例のサブルーチンを使用するための宣言を行ないます。また、データを格納するためのバッファ・メモリ領域も定義します。受信用はDS擬似命令で領域を確保し、送信用には固定データを準備しています。

;
;	 このプログラムはSPI制御ルーチンモジュールを使用して
;	EEPROMをアクセスする例を示します。
;
;	参照する制御サブルーチン
;
	EXTRN	SELPROM		; アクセスするEEPROMを選択
	EXTRN	WRITEENB	; 書き込み許可にする
	EXTRN	WRITEDIS	; 書き込み禁止にする
	EXTRN	READST		; ステータス・レジスタのリード
	EXTRN	WRITEST		; ステータス・レジスタへのライト
;
	EXTRN	READBLOCK1
		; 512バイト以下のEEPROMからのデータ・リード
	EXTRN	READBLOCK2
		; 1Kバイト以上のEEPROMからのデータ・リード
	EXTRN	WRITEBLOCK1
		; 512バイト以下のEEPROMへのデータ・ライト
	EXTRN	WRITEBLOCK2
		; 1Kバイト以上のEEPROMへのデータ・ライト
;
	EXTRN	WAITWT		; 書き込み完了待ち

;
;	作業領域の定義
;

	DSEG
RxBUFF1:				; 受信用データ・バッファ
	DS	16
RxBUFF2:
	DS	16
RxBUFF3:
	DS	16
;
;	送信テスト用データ
;
	CSEG
TxDATA1:
	DB	0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
TxDATA2:
	DB	0,1,2,4,8,16,32,64,128,64,32,16,8,4,2,1

(2)読み出し処理
EEPROMからデータを読み出すにはEEPROMを選択し、必要なパラメータをスタックやレジスタにセットしてREADBLOCK1(512バイト以下のEEPROMの場合)またはREADBLOCK2(1K~64KバイトのEEPROMの場合)をサブルーチン・コールします。エラー(EEPROMが書き込み中)の場合にはキャリー・フラグがセットされて戻ってくるので、エラー処理に分岐させてください。

	MOV	X,#1
	CALL	!SELPROM

;
;	512バイト以下のEEPROMの読み出し例
;
RxTEST:
	MOVW	AX,#16			; 読み出しデータ数セット
	PUSH	AX
	MOVW	AX,#RxBUFF1		; バッファ・アドレスをセット
	PUSH	AX
	MOVW	AX,#33H			; EEPROM内部アドレス
	CALL	!READBLOCK1
	POP	AX
	POP	AX
	BC	$ERRORLOOP		; エラーならエラー処理へ

(3)書き込み処理
EEPROMにデータを書き込むには最初にEEPROMを選択し、書き込みを許可状態にする必要があります。その後、必要なパラメータをスタックやレジスタにセットして、512バイト以下のEEPROMの場合にはWRITEBLOCK1を、1K~64Kの場合にはWRITEBLOCK2をサブルーチン・コールします。サブルーチンから戻ってきた段階でエラーが発生していなければ、EEPROMは転送されたデータを実際に書き込んでいます。この間に必要に応じて、他の処理を行なってください。書き込みの完了はWAITWTをコールすることで、書き込み完了まで待ち合わせます。

	MOV	X,#1
	CALL	!SELPROM
	CALL	!WRITEENB		; 書き込み許可に
;
;	256~512のEEPROMへの書き込み例
;
	MOVW	AX,#16			; データ数のセット(16バイト)
	PUSH	AX
	MOVW	AX,#TxDATA2		; バッファ・アドレスのセット
	PUSH	AX
	MOVW	AX,#0155H		; EEPROM内部アドレス
	CALL	!WRITEBLOCK1
	POP	AX
	POP	AX
	BC	$ERRORLOOP		; エラーならエラー処理へ

	ここに必要に応じて他の処理を入れる

	CALL	!WAITWT			; 書き込み完了待ち


[プログラム例の使用方法2]
ここでは、C言語記述での使用方法の例を示します。使用する制御プログラムがアセンブラ記述のものかC言語記述のものかは呼び出す関数の名前が異なるだけです。C言語記述の制御プログラムを使用する場合には、関数の名前の先頭にある'_'を削除するだけで上記のC言語記述の制御プログラム例を使用できます。

(1)宣言部
ここでは上で説明したプログラム例(アセンブラ記述分)のサブルーチンを使用するための宣言を行ないます。

#pragma	SFR
extern bit _selprom(unsigned char spi_adr);	// ROM選択
extern void _writeenb(void);			// 書き込み許可設定
extern void _writedis(void);			// 書き込み禁止設定
extern unsigned char _readst(void);		// ステータス・レジスタの読み出し
extern void _writest(unsigned char st);	// ステータス・レジスタへの書き込み
extern bit _read_spi_block1(int reg_adr, unsigned char *data, unsigned char size);
// 512バイト以下のEEROMからの読み出し
extern bit _read_spi_block2(int reg_adr, unsigned char *data, unsigned char size);
// 1kバイト以上のEEROMからの読み出し
extern bit _write_spi_block1(int reg_adr, unsigned char *data, unsigned char size);
// 512バイト以下のEEROMへの書き込み
extern bit _write_spi_block2(int reg_adr, unsigned char *data, unsigned char size);
// 1kバイト以上のEEROMへの書き込み
extern void _waitwt(void);			// 転送データの書き込み完了を待つ

これ以外に、このファイル中にある関数のプロトタイプ宣言や読み出しデータ用のバッファ・メモリや固定データを書き込む際のデータ・パターンなどを宣言しています。

void hdwinit(void);
bit rxtest(void);
bit	txtest(void);
unsigned char	eep_read_buf1[16];	// read buffer
unsigned char	eep_read_buf2[16];	// read buffer
unsigned char	eep_read_buf3[16];	// read buffer

typedef unsigned char data16[16];
const data16 txdata1 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
const data16 txdata2 = {0,1,2,4,8,16,32,64,128,64,32,16,8,4,2,1};

(2)読み出し処理
ここではステータス・レジスタの読み出しと、データの読み出しの例を示します。ここではrxtestとして関数の形にしてあり、制御プログラムでエラーが発生した場合にはそのままエラーをもって戻るようになっています。
この例では、1番のEEPROMを選択し、ステータス・レジスタの内容を読み出し、その後に、256番地未満のアドレス(0x33)と256番地以上のアドレス(0x1cc)から16バイトのデータを読み出し、その後EEPROMを切り替えて、512番地以上(0x33aa)のアドレスから読み出しています。

bit rxtest(void)
{
	unsigned char work;
	if(_selprom(1) == 1) return 1;
	work = _readst();
	if(_read_spi_block1(0x33, eep_read_buf1, 16)) return 1;

	if(_read_spi_block1(0x1cc, eep_read_buf2, 16)) return 1;

	if(_selprom(2) == 1) return 1;
	if(_read_spi_block2(0x33cc, eep_read_buf3, 16)) return 1;
}

(3)書き込み処理
書き込みについても関数の形にしてあります。対象とするEEPROMを選択した後に、書き込み許可状態にして、データの書き込みを行なっています。

bit	txtest(void)
{
	if(_selprom(1) == 1) return 1;
	_writeenb();                                            // 書き込み許可
	if(_write_spi_block1(0xaa, txdata1, 16))return 1;

//	ここに他の処理を入れてもよい

	_waitwt();
	if(_write_spi_block1(0x155, txdata2, 16))return 1;

//	ここに他の処理を入れてもよい

	_waitwt();
	if(_selprom(2) == 1) return 1;
	_writeenb();                                            // 書き込み許可
	if(_write_spi_block2(0x55aa, txdata1, 16))return 1;

//	ここに他の処理を入れてもよい

	_waitwt();
}
 
他にご質問がございましたら、リクエストを送信してください