原理介紹
NOKIA 5110 是一款基於圖形顯示的LCD螢幕(如下圖所示),主要這款螢幕,被手機大廠NOKIA 用來裝置在5110 系列手機,因而大受歡迎並且有很多的應用。
Nokia 5110 LCD使用的PCD8544控制器,NOKIA 3110用的也是這款控制器,PCD8554是一款低功耗的CMOS LCD控制器,用於驅動48行84列的圖形顯示,並且採用串列匯流排界面與微控制器相連,大大減少了週邊控制線的數量,在使用時十分的方便,而且相對於LCD1602、LCD12864 都有著自己的獨特優勢。可利用NOKIA 5110單色圖形LCD來顯示資料、文字、畫出幾何圖形等在顯示幕幕上。
電路圖
程式列表
Python – pcd8544.py
"""
MicroPython Nokia 5110 PCD8544 84x48 LCD driver
Reference: https://github.com/mcauser/micropython-pcd8544
"""
from micropython import const
from utime import sleep_us
# Function set 0010 0xxx
FUNCTION_SET = const(0x20)
POWER_DOWN = const(0x04)
ADDRESSING_VERT = const(0x02)
EXTENDED_INSTR = const(0x01)
# Display control 0000 1x0x
DISPLAY_BLANK = const(0x08)
DISPLAY_ALL = const(0x09)
DISPLAY_NORMAL = const(0x0c)
DISPLAY_INVERSE = const(0x0d)
# Temperature control 0000 01xx
TEMP_COEFF_0 = const(0x04)
TEMP_COEFF_1 = const(0x05)
TEMP_COEFF_2 = const(0x06) # default
TEMP_COEFF_3 = const(0x07)
# Bias system 0001 0xxx
BIAS_1_100 = const(0x10)
BIAS_1_80 = const(0x11)
BIAS_1_65 = const(0x12)
BIAS_1_48 = const(0x13)
BIAS_1_40 = const(0x14) # default
BIAS_1_24 = const(0x15)
BIAS_1_18 = const(0x16)
BIAS_1_10 = const(0x17)
class PCD8544:
def __init__(self, spi, cs, dc, rst=None):
self.width = 84
self.height = 48
self.bufferSize = (self.height * self.width // 8)
self.spi = spi
self.cs = cs # chip enable, active LOW
self.dc = dc # data HIGH, command LOW
self.rst = rst # reset, active LOW
self.cs.value(1)
self.dc.value(0)
if self.rst:
self.rst.value(1)
self.reset()
self.init()
def init(self):
# Initialise the display
self.LCDWrite(0, FUNCTION_SET|EXTENDED_INSTR) # extended command mode
self.LCDWrite(0, SET_VOP|49) # write VOP to register
self.LCDWrite(0, TEMP_COEFF_0) # set Temperature Coefficient(TCx)
self.LCDWrite(0, BIAS_1_40) # set Bias System (BSx)
self.LCDWrite(0, FUNCTION_SET) # basic command mode
self.LCDWrite(0, DISPLAY_NORMAL) # b/w mode, horizontal addressing
def reset(self):
# issue reset impulse to reset the display
self.rst.value(1)
sleep_us(100)
self.rst.value(0)
sleep_us(100) # reset impulse has to be >100 ns and <100 ms
self.rst.value(1)
sleep_us(100)
def power_on(self):
self.cs.value(1)
self.fn &= ~POWER_DOWN
self.LCDWrite(0, self.fn)
def power_off(self):
self.fn |= POWER_DOWN
self.LCDWrite(0, self.fn)
def invert(self, invert):
self.LCDWrite(0, DISPLAY_INVERSE if invert else DISPLAY_NORMAL)
def clear(self):
for i in range(0,self.bufferSize):
self.LCDWrite(1, 0x00)
def position(self, x, y):
self.LCDWrite(0, FUNCTION_SET) # basic command mode
# set cursor to column x (0~83), bank y (0~5)
self.LCDWrite(0, COL_ADDR | x) # set x pos (0~83)
self.LCDWrite(0, BANK_ADDR | y) # set y pos (0~5)
def LCDWrite(self, dcval, data):
self.dc.value(dcval)
self.cs.value(0)
self.spi.write(bytearray([data]))
self.cs.value(1)
def LCDShow(self, data):
self.position(0,0)
for i in range(0,self.bufferSize):
self.LCDWrite(1,data[i])
Python – Nokia_5110_Test_SW.py
"""
Filename: Nokia_5110_Test_SW.py
Reference: http://www.multiwingspan.co.uk/micro.php?page=nokia
Connections:
腳位定義 Nokia 5110 LCD
3V3 -> 1.VCC 3.3V logic voltage (0=off, 1=on)
GND -> 2.GND
P9(CS) -> 3.SCE Chip Enable (0=listen for input, 1=ignore input)
P10 -> 4.RST Reset pin (0=reset, 1=normal)
P11 -> 5.DC Data/Command (0=commands, 1=data)
P6(MOSI) -> 6.DIN data flow (Master out, Slave in)
P8(CLK) -> 7.SCK
3V3 -> 8.LED LIGHT Light (0=on, 1=off)
P7(MISO) ->
"""
from micropython import const
from machine import Switch #Get button KEY library
from machine import SPI, Pin
from machine import delay,RTC
from framebuf import FrameBuffer1
import utime
import pcd8544
# draw a 84x48 picture
EPYlogo_NEW_84x48 = bytearray([
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x3C, 0x7C, 0xFC, 0xFC,
0xFC, 0xE0, 0xC0, 0xC0, 0xC0, 0xE0, 0xFC, 0xFC, 0xFC, 0x7C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFC, 0xFE, 0xFF, 0xFF, 0x0F, 0x07, 0xC7, 0xE7,
0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xC7, 0x07, 0x0F, 0xFF, 0xFE,
0xFC, 0xF8, 0xF0, 0x01, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xBE, 0x9E, 0x9E, 0x9E, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x87, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x87, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x87, 0xFF, 0xFF,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFC, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xF7, 0xE7, 0xE7, 0xE7, 0xE7, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x80, 0x8F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E,
0x9F, 0x9F, 0x9F, 0x8F, 0x80, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F,
0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
])
width = 84
height = 48
bufferSize = height * width // 8
buffer = bytearray(bufferSize)
framebuf = FrameBuffer1(buffer, width, height)
today = (2021,5,1,5,48,0,0,0)
weeks={0:'Mon',1:'Tue',2:'Wed',3:'Thu',4:'Fri',5:'Sat',6:'Sun'}
months ={0:' ',1:'Jan',2:'Feb',3:'Mar',4:'Apr',5:'May',6:'Jun',
7:'Jul',8:'Aug',9:'Sep',10:'Oct',11:'Nov',12:'Dec'}
def fill_zero(n):
if n<10:
return '0' + str(n)
else:
return str(n)
def fill_blank(n):
if n<10:
return ' ' + str(n)
else:
return str(n)
# Start Function
if __name__ == '__main__':
KeyA = Switch('keya')
rtc = RTC()
rtc.datetime(today)
spi_0 = None
spi_0 = SPI(sck=Pin.board.CLK0, miso=Pin.board.MISO, mosi=Pin.board.MOSI)
cs = Pin(Pin.board.P9,Pin.OUT)
dc = Pin(Pin.board.P11,Pin.OUT)
rst = Pin(Pin.board.P10,Pin.OUT)
lcd = pcd8544.PCD8544(spi_0, cs, dc, rst)
# black screen
framebuf.fill(1)
lcd.LCDShow(buffer)
delay(2000)
# white screen
framebuf.fill(0)
lcd.LCDShow(buffer)
delay(2000)
# Display Test Bitmap
lcd.LCDShow(EPYlogo_NEW_84x48)
delay(1000)
lcd.invert(1)
delay(1000)
lcd.invert(0)
# write some text
framebuf.text('Hello',0,0,1)
framebuf.text("World!", 0, 9, 1)
lcd.LCDShow(buffer)
delay(2000)
while True:
(year, month, date, week, hour, minute, second, none1)=rtc.datetime()
YMD='%s-%s-%s' % (str(year),fill_zero(month),fill_zero(date))
WD='%s' % (weeks[week])
HmS='%s:%s:%s' % (fill_zero(hour),fill_zero(minute),fill_zero(second))
framebuf.fill(0)
framebuf.text('%s' % (YMD), 0, 0, 1) #Show date
framebuf.text(WD, 0, 9, 1) #Show week
framebuf.text(HmS, 0, 19, 1) #Show time
framebuf.text('%s' % (months[month]), 0, 29, 1) #Show month
lcd.LCDShow(buffer)
if (KeyA.value()) == True: #Press A Key
break
delay(900)
spi_0.deinit()
執行結果