
Raspberry Pi Pico の SPI
RP2040 には、2チャンネルの独立した SPI コントローラ(SPI0 / SPI1)を持っており、Raspberry Pi Pico では GP[0] ~ GP[27] の各端子から利用可能になっています. 今回はこの機能を使って、液晶ディスプレイの接続と EEPROM の読み書きを試してみました.ATM0130B3 液晶ディスプレイを接続する
ATM0130B3 は、240x(RGB)x240 1.3インチサイズのフルカラーグラフィック液晶ディスプレイです.今回は秋月電子の2.54mm ピッチ変換基板付きのコントロールキットを使用して接続します.ピッチ変換基板上にはレベル変換の回路も搭載されているため、Raspberry Pi Pico とそのまま接続可能です.
ハードウェア接続
下に Raspberry Pi Pico の I/O 端子と ATM0130B3 変換基板間の配線を示します.必要部品はすべて変換基板上に実装されていますので、SPI の4端子 /CS, D/C, RES の各信号線、電源・GND 端子をそれぞれ接続します.

ソフトウェア(Micro Python コード)
これまでと同様、Micro Python を使用します. MicroPython ライブラリのドキュメントを参照し、シリアルペリフェラルインタフェース バスプロトコル(SPI)に使う SPI クラスの使用例を確認しながらコーディングしていきます.
123456789# SPI の設定
spi
=
SPI(
0
, baudrate
=
8000000
, polarity
=
0
, phase
=
0
, bits
=
8
, firstbit
=
SPI.MSB, sck
=
Pin(
2
), miso
=
Pin(
4
), mosi
=
Pin(
3
))
# buf に含まれる bytes 型オブジェクトをデバイスに書き込む
spi.write(buff)
# read_buf に読込みながら write_buf の bytes 型オブジェクトを書き込む
# 両バッファは同じでも異なっていても良いが、同じ長さでなければならない
spi.write_readinto(buff, buff)
秋月電子のサイトにあるサンプルコードを参考に Micro Python で記述していきます./CS, D/C, RES の各信号線は GPIO として制御します.
raspi_pico_spi1.py 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344from
machine
import
Pin
from
machine
import
SPI
import
time
chars
=
[
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x21
,
0x08
,
0x40
,
0x10
,
0x00
,
0x52
,
0x94
,
0x00
,
0x00
,
0x00
,
0x52
,
0x95
,
0xF5
,
0x7D
,
0x4A
,
0x23
,
0xE8
,
0xE2
,
0xF8
,
0x80
,
0xC6
,
0x44
,
0x44
,
0x4C
,
0x60
,
0x64
,
0xA8
,
0x8A
,
0xC9
,
0xA0
,
0x61
,
0x10
,
0x00
,
0x00
,
0x00
,
0x11
,
0x10
,
0x84
,
0x10
,
0x40
,
0x41
,
0x04
,
0x21
,
0x11
,
0x00
,
0x01
,
0x2A
,
0xEA
,
0x90
,
0x00
,
0x01
,
0x08
,
0xE2
,
0x10
,
0x00
,
0x00
,
0x00
,
0x06
,
0x11
,
0x00
,
0x00
,
0x01
,
0xF0
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x63
,
0x00
,
0x00
,
0x44
,
0x44
,
0x40
,
0x00
,
0x74
,
0x67
,
0x5C
,
0xC5
,
0xC0
,
0x23
,
0x08
,
0x42
,
0x11
,
0xC0
,
0x74
,
0x42
,
0x22
,
0x23
,
0xE0
,
0xF8
,
0x88
,
0x20
,
0xC5
,
0xC0
,
0x11
,
0x95
,
0x2F
,
0x88
,
0x40
,
0xFC
,
0x3C
,
0x10
,
0xC5
,
0xC0
,
0x32
,
0x11
,
0xE8
,
0xC5
,
0xC0
,
0xF8
,
0x44
,
0x44
,
0x21
,
0x00
,
0x74
,
0x62
,
0xE8
,
0xC5
,
0xC0
,
0x74
,
0x62
,
0xF0
,
0x89
,
0x80
,
0x03
,
0x18
,
0x06
,
0x30
,
0x00
,
0x03
,
0x18
,
0x06
,
0x11
,
0x00
,
0x11
,
0x11
,
0x04
,
0x10
,
0x40
,
0x00
,
0x3E
,
0x0F
,
0x80
,
0x00
,
0x41
,
0x04
,
0x11
,
0x11
,
0x00
,
0x74
,
0x42
,
0x22
,
0x00
,
0x80
,
0x74
,
0x42
,
0xDA
,
0xD5
,
0xC0
,
0x74
,
0x63
,
0x1F
,
0xC6
,
0x20
,
0xF4
,
0x63
,
0xE8
,
0xC7
,
0xC0
,
0x74
,
0x61
,
0x08
,
0x45
,
0xC0
,
0xE4
,
0xA3
,
0x18
,
0xCB
,
0x80
,
0xFC
,
0x21
,
0xE8
,
0x43
,
0xE0
,
0xFC
,
0x21
,
0xE8
,
0x42
,
0x00
,
0x74
,
0x61
,
0x78
,
0xC5
,
0xE0
,
0x8C
,
0x63
,
0xF8
,
0xC6
,
0x20
,
0x71
,
0x08
,
0x42
,
0x11
,
0xC0
,
0x38
,
0x84
,
0x21
,
0x49
,
0x80
,
0x8C
,
0xA9
,
0x8A
,
0x4A
,
0x20
,
0x84
,
0x21
,
0x08
,
0x43
,
0xE0
,
0x8E
,
0xEB
,
0x58
,
0xC6
,
0x20
,
0x8C
,
0x73
,
0x59
,
0xC6
,
0x20
,
0x74
,
0x63
,
0x18
,
0xC5
,
0xC0
,
0xF4
,
0x63
,
0xE8
,
0x42
,
0x00
,
0x74
,
0x63
,
0x1A
,
0xC9
,
0xA0
,
0xF4
,
0x63
,
0xEA
,
0x4A
,
0x20
,
0x74
,
0x20
,
0xE0
,
0x87
,
0xC0
,
0xF9
,
0x08
,
0x42
,
0x10
,
0x80
,
0x8C
,
0x63
,
0x18
,
0xC5
,
0xC0
,
0x8C
,
0x63
,
0x18
,
0xA8
,
0x80
,
0x8C
,
0x63
,
0x5A
,
0xD5
,
0x40
,
0x8C
,
0x54
,
0x45
,
0x46
,
0x20
,
0x8C
,
0x62
,
0xA2
,
0x10
,
0x80
,
0xF8
,
0x44
,
0x44
,
0x43
,
0xE0
,
0x72
,
0x10
,
0x84
,
0x21
,
0xC0
,
0x8A
,
0xBE
,
0x4F
,
0x90
,
0x80
,
0x70
,
0x84
,
0x21
,
0x09
,
0xC0
,
0x22
,
0xA2
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x03
,
0xE0
,
0x41
,
0x04
,
0x00
,
0x00
,
0x00
,
0x00
,
0x1C
,
0x17
,
0xC5
,
0xE0
,
0x84
,
0x2D
,
0x98
,
0xC7
,
0xC0
,
0x00
,
0x1D
,
0x08
,
0x45
,
0xC0
,
0x08
,
0x5B
,
0x38
,
0xC5
,
0xE0
,
0x00
,
0x1D
,
0x1F
,
0xC1
,
0xC0
,
0x32
,
0x51
,
0xC4
,
0x21
,
0x00
,
0x03
,
0xE3
,
0x17
,
0x85
,
0xC0
,
0x84
,
0x2D
,
0x98
,
0xC6
,
0x20
,
0x20
,
0x18
,
0x42
,
0x11
,
0xC0
,
0x10
,
0x0C
,
0x21
,
0x49
,
0x80
,
0x84
,
0x25
,
0x4C
,
0x52
,
0x40
,
0x61
,
0x08
,
0x42
,
0x11
,
0xC0
,
0x00
,
0x35
,
0x5A
,
0xC6
,
0x20
,
0x00
,
0x2D
,
0x98
,
0xC6
,
0x20
,
0x00
,
0x1D
,
0x18
,
0xC5
,
0xC0
,
0x00
,
0x3D
,
0x1F
,
0x42
,
0x00
,
0x00
,
0x1B
,
0x37
,
0x84
,
0x20
,
0x00
,
0x2D
,
0x98
,
0x42
,
0x00
,
0x00
,
0x1D
,
0x07
,
0x07
,
0xC0
,
0x42
,
0x38
,
0x84
,
0x24
,
0xC0
,
0x00
,
0x23
,
0x18
,
0xCD
,
0xA0
,
0x00
,
0x23
,
0x18
,
0xA8
,
0x80
,
0x00
,
0x23
,
0x1A
,
0xD5
,
0x40
,
0x00
,
0x22
,
0xA2
,
0x2A
,
0x20
,
0x00
,
0x23
,
0x17
,
0x85
,
0xC0
,
0x00
,
0x3E
,
0x22
,
0x23
,
0xE0
,
0x11
,
0x08
,
0x82
,
0x10
,
0x40
,
0x21
,
0x08
,
0x42
,
0x10
,
0x80
,
0x41
,
0x08
,
0x22
,
0x11
,
0x00
,
0x00
,
0x11
,
0x51
,
0x00
,
0x00
]
spi
=
SPI(
0
, baudrate
=
8000000
, polarity
=
0
, phase
=
0
, bits
=
8
, firstbit
=
SPI.MSB, sck
=
Pin(
2
), miso
=
Pin(
4
), mosi
=
Pin(
3
))
(spi)
cs
=
Pin(
5
, Pin.OUT)
dc
=
Pin(
14
, Pin.OUT)
res
=
Pin(
15
, Pin.OUT)
led
=
Pin(
25
, Pin.OUT)
fig_color
=
0
cxahar_color
=
0
char_color_bg
=
0
char_x
=
0
char_y
=
0
queue
=
[
0
,
0
,
0
,
0
,
0
]
def
putPixel(color):
writeData(color >>
8
)
writeData(color &
0xFF
)
def
setWindow(x, y, w, h):
writeReg(
0x2A
)
writeData(
0x00
)
writeData(x)
writeData(
0x00
)
writeData(x
+
w
-
1
)
writeReg(
0x2B
)
writeData(
0x00
)
writeData(y)
writeData(
0x00
)
writeData(y
+
h
-
1
)
writeReg(
0x2c
)
def
writeCharQueue():
global
char_x
global
char_y
global
char_color
global
char_color_bg
setWindow(char_x, char_y,
5
,
8
);
for
i
in
range
(
5
):
for
j
in
range
(
8
):
if
((queue[i] & (
0x80
>> j)) >
0
):
putPixel(char_color)
else
:
putPixel(char_color_bg)
setWindow(char_x
+
5
, char_y,
1
,
8
);
for
i
in
range
(
8
):
putPixel(char_color_bg);
def
setCharQueue(ch):
global
chars
if
((
ord
(ch) >
=
0x20
)
and
(
ord
(ch) <
=
0x7E
)) :
c
=
ord
(ch)
-
0x20
for
i
in
range
(
5
) :
queue[i]
=
chars[
5
*
c
+
i]
else
:
for
i
in
range
(
5
) :
queue[i]
=
0xFF
#print(str(queue))
def
print_str(
str
):
global
char_x
global
char_y
if
(char_x >
235
):
char_x
=
0
char_y
+
=
8
if
(char_y >
232
):
char_x
=
0
char_y
=
0
else
:
index
=
0
for
item
in
str
:
setCharQueue(
str
[index])
cs.value(
0
)
writeCharQueue()
char_x
+
=
6
cs.value(
1
)
index
+
=
1
def
setCharPlace(x, y):
global
char_x
global
char_y
char_x
=
x;
char_y
=
y;
def
setFigColor(r, g, b):
global
fig_color
color
=
0
;
color
=
b >>
3
;
color |
=
((g &
0xFC
) <<
3
)
color |
=
((r &
0xF8
) <<
8
)
fig_color
=
color
#print('figcolor : ' + hex(fig_color))
def
setCharColor(r, g, b):
global
char_color
color
=
0
;
color
=
b >>
3
;
color |
=
((g &
0xFC
) <<
3
)
color |
=
((r &
0xF8
) <<
8
)
char_color
=
color
#print('char_color : ' + hex(char_color))
def
setCharColorBG(r, g, b):
global
char_color_bg
color
=
0
;
color
=
b >>
3
;
color |
=
((g &
0xFC
) <<
3
)
color |
=
((r &
0xF8
) <<
8
)
char_color_bg
=
color
#print('char_color_bg : ' + hex(char_color_bg))
def
writeReg(reg):
dc.value(
0
)
buff
=
bytearray(
1
)
buff[
0
]
=
reg
spi.write(buff)
#print('writeReg ' + hex(buff[0]))
def
writeData(data):
dc.value(
1
)
buff
=
bytearray(
1
)
buff[
0
]
=
data
spi.write(buff)
#print('writeData ' + hex(buff[0]))
def
drawRectangle(x, y, w, h):
global
fig_color
led.value(
1
)
loop
=
w
*
h
colorH
=
fig_color >>
8
colorL
=
fig_color &
0x00FF
#print('ColorH = ' + hex(colorH))
#print('ColorL = ' + hex(colorL))
#color = 240
#colorH = 255
#colorL = 255
cs.value(
0
)
# set window
writeReg(
0x2A
)
writeData(
0x00
)
writeData(x)
writeData(
0x00
)
writeData(x
+
w
-
1
)
writeReg(
0x2B
)
writeData(
0x00
)
writeData(y)
writeData(
0x00
)
writeData(y
+
h
-
1
)
writeReg(
0x2c
);
dc.value(
1
)
for
i
in
range
(loop):
buff
=
bytearray(
1
)
buff[
0
]
=
colorH
spi.write(buff)
buff[
0
]
=
colorL
spi.write(buff)
#spi.write(hex(colorH))
#spi.write(hex(colorL))
#writeData(colorH)
#writeData(colorL)
#print(i)
cs.value(
1
)
led.value(
0
)
(
'draw finished'
)
def
begin():
cs.value(
1
)
res.value(
1
)
time.sleep(
0.02
)
res.value(
0
)
time.sleep(
0.02
)
res.value(
1
)
time.sleep(
0.02
)
(
'Reset'
)
cs.value(
0
)
led.value(
1
)
writeReg(
0x11
)
time.sleep(
0.1
)
writeReg(
0x36
)
writeData(
0x00
)
writeReg(
0x3A
)
writeData(
0x55
)
##--------------------------------ST7789V Frame rate
writeReg(
0xb2
)
writeData(
0x0c
)
writeData(
0x0c
)
writeData(
0x00
)
writeData(
0x33
)
writeData(
0x33
)
time.sleep(
0.002
)
writeReg(
0xb7
)
writeData(
0x75
)
time.sleep(
0.002
)
##---------------------------------ST7789V Power
writeReg(
0xc2
)
writeData(
0x01
)
time.sleep(
0.002
)
writeReg(
0xc3
)
writeData(
0x10
)
time.sleep(
0.002
)
writeReg(
0xc4
)
writeData(
0x20
)
time.sleep(
0.002
)
writeReg(
0xc6
)
writeData(
0x0f
)
writeReg(
0xb0
)
writeData(
0x00
)
writeData(
0xf0
);
# RRRR RGGGG GGGB BBBB
time.sleep(
0.002
)
writeReg(
0xD0
)
writeData(
0xA4
)
writeData(
0xA1
)
time.sleep(
0.002
)
## --------------------------------ST7789V gamma
writeReg(
0x21
)
time.sleep(
0.002
)
writeReg(
0xbb
)
writeData(
0x3b
)
time.sleep(
0.002
)
writeReg(
0xE0
)
# Set Gamma
writeData(
0xF0
)
writeData(
0x0b
)
writeData(
0x11
)
writeData(
0x0e
)
writeData(
0x0d
)
writeData(
0x19
)
writeData(
0x36
)
writeData(
0x33
)
writeData(
0x4b
)
writeData(
0x07
)
writeData(
0x14
)
writeData(
0x14
)
writeData(
0x2c
)
writeData(
0x2e
)
time.sleep(
0.002
)
writeReg(
0xE1
)
# Set Gamma
writeData(
0xF0
)
writeData(
0x0d
)
writeData(
0x12
)
writeData(
0x0b
)
writeData(
0x09
)
writeData(
0x03
)
writeData(
0x32
)
writeData(
0x44
)
writeData(
0x48
)
writeData(
0x39
)
writeData(
0x16
)
writeData(
0x16
)
writeData(
0x2d
)
writeData(
0x30
)
writeReg(
0x2A
)
writeData(
0x00
)
writeData(
0x00
)
writeData(
0x00
)
writeData(
0xEF
)
writeReg(
0x2B
)
writeData(
0x00
)
writeData(
0x00
)
writeData(
0x00
)
writeData(
0xEF
)
writeReg(
0x29
)
# Display on
time.sleep(
0.002
)
writeReg(
0x2c
)
cs.value(
1
)
led.value(
0
)
(
'Init finished'
)
def
colorBar():
for
i
in
range
(
8
):
g
=
255
*
(
1
-
((i &
0x04
) >>
2
))
r
=
255
*
(
1
-
((i &
0x02
) >>
1
))
b
=
255
*
(
1
-
((i &
0x01
)))
setFigColor(r, g, b)
drawRectangle(i
*
30
,
0
,
30
,
180
)
for
i
in
range
(
240
):
setFigColor(i, i, i)
drawRectangle(i,
180
,
1
,
60
)
begin()
setFigColor(
0
,
0
,
0
)
drawRectangle(
0
,
0
,
240
,
240
)
colorBar()
setCharPlace(
0
,
160
)
setCharColor(
0
,
0
,
0
)
setCharColorBG(
255
,
255
,
255
)
実行結果
実行結果を下に示します.カラーバーと文字列が正しく表示されました.
EEPROM を接続する
続いては SPI インターフェースのシリアル EEPROM との接続を試してみます.使用するデバイスは ROHM 社製 BR25L320 デバイスです. (下の写真はピッチ変換基板に実装した状態です)
ハードウェア接続
下に Raspberry Pi Pico の I/O 端子と BR25L320 間の配線を示します.SPI と電源・GND 端子のほか、書込み保護制御用の /WP, HOLD 信号を Raspberry Pi Pico の GP に接続します.

ソフトウェア(Micro Python コード)
raspi_pico_spi2.py 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687from
machine
import
Pin
from
machine
import
SPI
import
time
spi
=
SPI(
0
, baudrate
=
100000
, polarity
=
0
, phase
=
0
, bits
=
8
, firstbit
=
SPI.MSB, sck
=
Pin(
2
), miso
=
Pin(
4
), mosi
=
Pin(
3
))
(spi)
cs
=
Pin(
5
, Pin.OUT)
wp
=
Pin(
0
, Pin.OUT)
hold
=
Pin(
1
, Pin.OUT)
cs.value(
1
)
wp.value(
0
)
hold.value(
0
)
def
enablewrite():
cs.value(
0
)
wp.value(
1
)
hold.value(
1
)
wen
=
bytearray(
1
)
wen[
0
]
=
0x06
spi.write(wen)
(
"Write enabled("
+
hex
(wen[
0
])
+
")."
)
cs.value(
1
)
wp.value(
0
)
hold.value(
0
)
def
disablewrite():
cs.value(
0
)
wp.value(
1
)
hold.value(
1
)
wen
=
bytearray(
1
)
wen[
0
]
=
0x04
spi.write(wen)
(
"Write disabled("
+
hex
(wen[
0
])
+
")."
)
cs.value(
1
)
wp.value(
0
)
hold.value(
0
)
def
writeData(addr, data):
cs.value(
0
)
wp.value(
1
)
hold.value(
1
)
buff
=
bytearray(
4
)
buff[
0
]
=
0x02
buff[
1
]
=
(addr &
0xFF00
) >>
8
buff[
2
]
=
(addr &
0x00FF
)
buff[
3
]
=
(data &
0xFF
)
spi.write(buff)
(
"W : "
+
hex
(buff[
0
]))
(
"W : "
+
hex
(buff[
1
]))
(
"W : "
+
hex
(buff[
2
]))
(
"W : "
+
hex
(buff[
3
]))
cs.value(
1
)
wp.value(
0
)
hold.value(
0
)
def
readData(addr):
cs.value(
0
)
wp.value(
1
)
hold.value(
1
)
buff
=
bytearray(
4
)
buff[
0
]
=
0x03
buff[
1
]
=
(addr &
0xFF00
) >>
8
buff[
2
]
=
(addr &
0x00FF
)
buff[
3
]
=
0x00
spi.write_readinto(buff, buff)
(
"R : "
+
hex
(buff[
3
]))
cs.value(
1
)
wp.value(
0
)
hold.value(
0
)
enablewrite()
writeData(
0x0A1B
,
0xAA
)
disablewrite()
(
"----------------"
)
readData(
0x0A1B
)
(
"----------------"
)
実行結果

書き込み時、読み出し時それぞれの波形を示します.




参考
ATM0130B3 使用フルカラー液晶コントロールキットMicroPython ライブラリのドキュメント
BR25L320 デバイス
1件のコメント