今回はSD-CARDと入出力する部分をプログラムしていきます。
Aレジスタは、そのまま、出力ポートのビットイメージになります。
Aレジスタは、あらかじめクリアして、CSビットをLレベルにしています。

まず、マイコンから出力する部分ですが、クロックパルスが出力されている期間中にHレベルまたは、Lレベルにします。
実際に出力するデータはDレジスターに格納して置き、1クロックパルスごと(1ビットデータごとに)に左シフトし、最上位7ビット目をキュリーフラグに格納します。
さらにAレジスターを左シフトし、先ほどキャリーフラグに格納されたデータを最下位0ビット目に格納します。
そのあと、CLKパルスのLレベルをセットします。
NOP命令にて時間稼ぎをしてから、CLKパルスをHレベルにセットします。

続いて、マイコンへの入力ですが、ここではクロックパルスの立ち上がり直後のDOビットの状態を読み込んでいます。
つまり、先ほど、CLKパルスをHレベルにセットした直後となります。

入力ポートから読み込まれたデータは、Aレジスター7ビットに格納されるので、左シフトで一旦キャリーフラグに格納します。
入力データはEレジスターに格納するので、Eレジスタを左シフトし、キャリーフラグのデータを最下位0ビットに格納します。

以上の動作を8回繰り返すことで、1バイト分のデータの入出力を行います。

[asm] spi_8bit: ;outdata Dreg,inputdata Ereg
push bc
ld c,0x00
ld b,0x08
loopspi:
xor a
rlc d
rra
res S_CLK,a ;CLK L
out0 (OUTPUTP),a
nop
nop
nop
nop
nop
nop
set S_CLK,a ;CLK H
out0 (OUTPUTP),a
in0 a,(INPUTP)
rlca
rl e
djnz loopspi
xor a
out0 (OUTPUTP),a
pop bc
ret

[/asm]

実際のクロックパルスはduty比は50%になっていません。使用しているSD-CARDでは通信できているので良しとしていますが、気になるようでしたらduty比を調整した方がいいかもしれません。
通信周波数は約208KHzです。
下記は通信波形です。CRC(0x95)の出力状態を示しています。
上段がDI、中段がCS、下段がCLKです。

次回は、ソフトウェアリセットのシーケンスを作成したいと思います。

おすすめの記事