树莓派使用python操作原生SPI总线驱动NOKIA5110屏

 

前段时间入手了树莓派3B+,正好手里还有以前做项目留下的NOKIO 5110屏,于是想用树莓派搭配5110屏使用。

  1. 硬件接线

首先,确定raspberryPI与5110的连线:

1.1 NOKIA 5110的接口

5110接口如下图:

树莓派使用python操作原生SPI总线驱动NOKIA5110屏_第1张图片

RST:LCD复位信号

SCE:SPI片选 低有效

D/C:数据/命令切换  0:命令,1:数据 

SDIN:SPI MOSI 数据输入

SCLK:SPI 时钟

VCC:电源 3.3~5V

LED:背光控制开头

GND:地

 

 

 

 

 

 

 

 

5110与raspberry的连线

因为树莓派自带SPI总线,具有2个片选信号,支持连接两个SPI设备,我们选择用CE0。

如下表:

树莓派使用python操作原生SPI总线驱动NOKIA5110屏_第2张图片

打开raspberryPI的SPI接口功能

树莓派的SPI接口功能默认被禁用,需要手动使能,否则是普通的GPIO口。

在Raspbian系统中,选择【系统菜单--首选项--Raspberry Pi Configuration】,打开树莓派配置对话框,切换到【interfaces】,将SPI项选择“Enable”,即可打开SPI功能(需要重启):

树莓派使用python操作原生SPI总线驱动NOKIA5110屏_第3张图片

 

2. python操作raspberryPI SPI方法

python操作树莓派的SIP接口需要使用库“spidev”。

spidev库在pypi上的介绍如下:

安装:

pip install spidev

说明:

This project contains a python module for interfacing with SPI devices from user space via the spidev linux kernel driver.

用法:

import spidev
spi = spidev.SpiDev()
spi.open(bus, device)
to_send = [0x01, 0x02, 0x03]
spi.xfer(to_send)

python操作5110代码

因为之前使用AVR驱动5110,手中有相应的C代码,现在将对应的代码改写为python代码。

首先是字模代码:

AVR C代码的字模数据使用二维数组,存放为AVR的PROGMEM数据,如下:

树莓派使用python操作原生SPI总线驱动NOKIA5110屏_第4张图片

而在树莓派中使用python驱动,使用字典则是更好的选择,使用字符作为key,需要字模数据作为value; 在打印字符时,使用待显示的字符即可方便地获取相应字模数据。

char_dict = {
    " ": [0x00, 0x00, 0x00, 0x00, 0x00],  # sp
    "!": [0x00, 0x00, 0x2f, 0x00, 0x00],  # !
    "\"": [0x00, 0x07, 0x00, 0x07, 0x00], # "
    "#": [0x14, 0x7f, 0x14, 0x7f, 0x14],  # #
    "$": [0x24, 0x2a, 0x7f, 0x2a, 0x12],  # $
    "%": [0x62, 0x64, 0x08, 0x13, 0x23],  # %
    "&": [0x36, 0x49, 0x55, 0x22, 0x50],  # &
    "'": [0x00, 0x05, 0x03, 0x00, 0x00],  # '
    "(": [0x00, 0x1c, 0x22, 0x41, 0x00],  # (
    ")": [0x00, 0x41, 0x22, 0x1c, 0x00],  # )
    "*": [0x14, 0x08, 0x3E, 0x08, 0x14],  # * - 10
    "+": [0x08, 0x08, 0x3E, 0x08, 0x08],  # +
    ",": [0x00, 0x00, 0xA0, 0x60, 0x00],  # ,
    "-": [0x08, 0x08, 0x08, 0x08, 0x08],  # -
    ".": [0x00, 0x60, 0x60, 0x00, 0x00],  # .
    "/": [0x20, 0x10, 0x08, 0x04, 0x02],  # /
    "0": [0x3E, 0x51, 0x49, 0x45, 0x3E],  # 0 - 16
    "1": [0x00, 0x42, 0x7F, 0x40, 0x00],  # 1
    "2": [0x42, 0x61, 0x51, 0x49, 0x46],  # 2
    "3": [0x21, 0x41, 0x45, 0x4B, 0x31],  # 3
    "4": [0x18, 0x14, 0x12, 0x7F, 0x10],  # 4 - 20
    "5": [0x27, 0x45, 0x45, 0x45, 0x39],  # 5
    "6": [0x3C, 0x4A, 0x49, 0x49, 0x30],  # 6
    "7": [0x01, 0x71, 0x09, 0x05, 0x03],  # 7
    "8": [0x36, 0x49, 0x49, 0x49, 0x36],  # 8
    "9": [0x06, 0x49, 0x49, 0x29, 0x1E],  # 9
    ":": [0x00, 0x36, 0x36, 0x00, 0x00],  # :
    ";": [0x00, 0x56, 0x36, 0x00, 0x00],  # ;
    "<": [0x08, 0x14, 0x22, 0x41, 0x00],  # <
    "=": [0x14, 0x14, 0x14, 0x14, 0x14],  # =
    ">": [0x00, 0x41, 0x22, 0x14, 0x08],  # > -30
    "?": [0x02, 0x01, 0x51, 0x09, 0x06],  # ?
    "@": [0x32, 0x49, 0x59, 0x51, 0x3E],  # @
    "A": [0x7C, 0x12, 0x11, 0x12, 0x7C],  # A
    "B": [0x7F, 0x49, 0x49, 0x49, 0x36],  # B
    "C": [0x3E, 0x41, 0x41, 0x41, 0x22],  # C
    "D": [0x7F, 0x41, 0x41, 0x22, 0x1C],  # D
    "E": [0x7F, 0x49, 0x49, 0x49, 0x41],  # E
    "F": [0x7F, 0x09, 0x09, 0x09, 0x01],  # F
    "G": [0x3E, 0x41, 0x49, 0x49, 0x7A],  # G
    "H": [0x7F, 0x08, 0x08, 0x08, 0x7F],  # H - 40
    "I": [0x00, 0x41, 0x7F, 0x41, 0x00],  # I
    "J": [0x20, 0x40, 0x41, 0x3F, 0x01],  # J
    "K": [0x7F, 0x08, 0x14, 0x22, 0x41],  # K
    "L": [0x7F, 0x40, 0x40, 0x40, 0x40],  # L
    "M": [0x7F, 0x02, 0x0C, 0x02, 0x7F],  # M
    "N": [0x7F, 0x04, 0x08, 0x10, 0x7F],  # N
    "O": [0x3E, 0x41, 0x41, 0x41, 0x3E],  # O
    "P": [0x7F, 0x09, 0x09, 0x09, 0x06],  # P
    "Q": [0x3E, 0x41, 0x51, 0x21, 0x5E],  # Q
    "R": [0x7F, 0x09, 0x19, 0x29, 0x46],  # R - 50
    "S": [0x46, 0x49, 0x49, 0x49, 0x31],  # S
    "T": [0x01, 0x01, 0x7F, 0x01, 0x01],  # T
    "U": [0x3F, 0x40, 0x40, 0x40, 0x3F],  # U
    "V": [0x1F, 0x20, 0x40, 0x20, 0x1F],  # V
    "W": [0x3F, 0x40, 0x38, 0x40, 0x3F],  # W
    "X": [0x63, 0x14, 0x08, 0x14, 0x63],  # X
    "Y": [0x07, 0x08, 0x70, 0x08, 0x07],  # Y
    "Z": [0x61, 0x51, 0x49, 0x45, 0x43],  # Z
    "[": [0x00, 0x7F, 0x41, 0x41, 0x00],  # [
    "\\": [0x55, 0x2A, 0x55, 0x2A, 0x55], # \55 - 60
    "]": [0x00, 0x41, 0x41, 0x7F, 0x00],  # ]
    "^": [0x04, 0x02, 0x01, 0x02, 0x04],  # ^
    "_": [0x40, 0x40, 0x40, 0x40, 0x40],  # _
    "`": [0x00, 0x01, 0x02, 0x04, 0x00],  # `
    "a": [0x20, 0x54, 0x54, 0x54, 0x78],  # a
    "b": [0x7F, 0x48, 0x44, 0x44, 0x38],  # b
    "c": [0x38, 0x44, 0x44, 0x44, 0x20],  # c
    "d": [0x38, 0x44, 0x44, 0x48, 0x7F],  # d
    "e": [0x38, 0x54, 0x54, 0x54, 0x18],  # e
    "f": [0x08, 0x7E, 0x09, 0x01, 0x02],  # f - 70
    "g": [0x18, 0xA4, 0xA4, 0xA4, 0x7C],  # g
    "h": [0x7F, 0x08, 0x04, 0x04, 0x78],  # h
    "i": [0x00, 0x44, 0x7D, 0x40, 0x00],  # i
    "j": [0x40, 0x80, 0x84, 0x7D, 0x00],  # j
    "k": [0x7F, 0x10, 0x28, 0x44, 0x00],  # k
    "l": [0x00, 0x41, 0x7F, 0x40, 0x00],  # l
    "m": [0x7C, 0x04, 0x18, 0x04, 0x78],  # m
    "n": [0x7C, 0x08, 0x04, 0x04, 0x78],  # n
    "o": [0x38, 0x44, 0x44, 0x44, 0x38],  # o
    "p": [0xFC, 0x24, 0x24, 0x24, 0x18],  # p - 80
    "q": [0x18, 0x24, 0x24, 0x18, 0xFC],  # q
    "r": [0x7C, 0x08, 0x04, 0x04, 0x08],  # r
    "s": [0x48, 0x54, 0x54, 0x54, 0x20],  # s
    "t": [0x04, 0x3F, 0x44, 0x40, 0x20],  # t
    "u": [0x3C, 0x40, 0x40, 0x20, 0x7C],  # u
    "v": [0x1C, 0x20, 0x40, 0x20, 0x1C],  # v
    "w": [0x3C, 0x40, 0x30, 0x40, 0x3C],  # w
    "x": [0x44, 0x28, 0x10, 0x28, 0x44],  # x
    "y": [0x1C, 0xA0, 0xA0, 0xA0, 0x7C],  # y
    "z": [0x44, 0x64, 0x54, 0x4C, 0x44],  # z - 90
    "{": [0x00, 0x08, 0x36, 0x41, 0x00],  # {
    "|": [0x00, 0x00, 0x7F, 0x00, 0x00],  # |
    "}": [0x00, 0x41, 0x36, 0x08, 0x00],  # }
    "~": [0x08, 0x10, 0x08, 0x04, 0x08],  # ~
}

5110操作代码:

pin_led = 32
pin_rst = 36
pin_sec = 38
pin_dc = 40

class LCD5110(object):
    """LCD 5110"""

    def __init__(self, bus, device):
        # init the pin mode
        GPIO.setwarnings(False)
        GPIO.setmode(GPIO.BOARD)
        for pin in [pin_sec, pin_dc, pin_led, pin_rst]:
            GPIO.setup(pin, GPIO.OUT)

        # initinal the bus
        self.spi = spidev.SpiDev()
        self.spi.open(bus, device)
        self.spi.max_speed_hz = 1000000

    def lcd_init(self):
        GPIO.output(pin_rst, 0)
        time.sleep(0.05)
        GPIO.output(pin_rst, 1)

        self.lcd_write(0, [0x21])   # 使用扩展指令集
        self.lcd_write(0, [0xC8])   # 设置Vop = 0x48
        self.lcd_write(0, [0x06])   # 设置温度系数:0b10
        self.lcd_write(0, [0x13])   # 设置偏置系数:3
        self.lcd_write(0, [0x20])   # 使用基本指令集
        self.lcd_write(0, [0x0C])   # 设置显示配置:D=1,E=0:普通模式
        self.lcd_write(0, [0x40])   # 设置y地址:0
        self.lcd_write(0, [0x80])   # 设置x地址:0
        pass

    def lcd_write(self, dc, data):
        """
        write data/cmd to lcd5110
        :param dc: D/C
        :param data: data to be writed
        :return:
        """
        GPIO.output(pin_dc, dc)
        time.sleep(0.00001)
        self.spi.writebytes(data)
        pass

    def lcd_clear(self):
        """
        clear the lcd5110
        :return:
        """
        self.lcd_write(0, [0x80])
        self.lcd_write(0, [0x40])
        for d in range(0, 505):
            self.lcd_write(1, [0])
        pass

    def lcd_printc(self, char):
        """
        show a chacter to lcd5110
        :param char: chacter
        :return:
        """
        chr_codelist = char_dict[char]
        for code in chr_codelist:
            self.lcd_write(1, [code])
            # time.sleep(0.0001)
        # self.lcd_write(1, chr_codelist)
        pass

    def lcd_go_xy(self, x, y):
        """
        光标定位,左上角为(0,0)
        :param x: 列地址(0-83)
        :param y: 行地址(0-5)
        :return:
        """
        self.lcd_write(0, [x+128])
        self.lcd_write(0, [y+64])

    def lcd_prints(self, s):
        """
        print a string to lcd5110
        :param s: string
        :return:
        """
        for c in s:
            for code in c:
                lcd.lcd_write(1, [code])
        pass

显示示例:

lcd = LCD5110(0, 0)
lcd.lcd_init()
lcd.lcd_clear()
lcd.lcd_go_xy(0, 0)
time.sleep(0.001)

# 依次显示全部字符
for code in char_dict.values():
    lcd.lcd_write(1, code)
    time.sleep(0.1)

将编写的python代码传到raspberryPI中,使用PuTTY工具SSH连接,进入存放代码的目录并运行,即可在5110的屏幕上看到显示的全部字符。

树莓派使用python操作原生SPI总线驱动NOKIA5110屏_第5张图片

 

后记:

最后,使用示例代码打算依次显示自定义字模中的字符,但显示的顺序和代码中定义的顺序并不一致?下一节将记录过程中的问题与解决方法。

你可能感兴趣的:(树莓派,SPI)