树莓派默认自带SPI和IIC接口,本教程以SSD1306模块(见下图)为例,讲解利用 adafruit-circuitpython-ssd1306 库实现SPI/IIC协议点亮OLED屏。除了利用树莓派自带的SPI和IIC接口,也可以利用GPIO扣,通过软件模拟SPI/IIC协议实现,不过需要搞清协议的原理和时序,要求太高。
本篇是SPI协议点亮OLED,IIC协议有空再更新!!
本文使用的树莓派为 3b
本篇博文参考
树莓派笔记12:通过SPI操作OLED屏
adafruit SSD1306库 官方文档
树莓派实验室


上图是在马云家买的SSD1306 OLED模块,支持SPI和IIC两种协议。模块的的背面标明了IIC和3/4线SPI协议的切换说明:
即切换相应的电阻位置
IIC——>R1,R4,R5,R6
3SPI——>R2,R3
4SPI——>R3,R4
模块买来默认是支持4线SPI。
一、SPI协议
SPI是串行外设接口(Serial Peripheral Interface)的简写,其实就是一种总线通信协议,该总线以主从方式工作,通常是一个主设备和一个或多个从设备,一般需要4根线来进行数据通信,即SDI(数据输入)、SDO(数据输出)、SCLK(时钟)、CS(片选),相应的,有一套时序逻辑规定了通信过程。一般使用SPI的设备都配备了现成的SPI模块,只需要对相应的寄存器写入指令就可以进行通信了。
树莓派自带SPI接口,默认关闭,利用以下命令或者GUI模式下点击左上角树莓派LOGO—>首选项—>Raspberry Pi Configuration打开配置界面
1.命令行模式
sudo raspi-config
2.GUI模式
树莓派LOGO—>首选项—>Raspberry Pi Configuration
二、连线
下图一个是官方文档的连接图,其接口有8个,而我买的只有7个,定义也有点不同,可以作为参考。
另一个是皇家园林巡游者提供的接线图,和我买的一样,故参考此博主的接线。
把模块的引脚接到树莓派的GPIO上, 需要注意这里要分清GPIO引脚号是BCM编号还是实际编号。GND脚和树莓派的GND连接;VCC接到3.3V脚;D0接到树莓派的SCLK脚(第23号脚),即BCM.11脚;D1接到MOSI脚(第19号脚),即BCM.10;RES接到BCM.17脚,即第11号脚;DC接到BCM.22脚,即第15号脚;CS接到CE0脚(第24号脚)。总之,除了RES和DC是可以任意指定GPIO口,其他引脚是必须和树莓派上的指定脚连接的。
三、 软件编程
-
安装相关库
sudo apt-get update sudo apt-get install build-essential python-dev python-pip sudo pip install RPi.GPIO #树莓派Python的GPIO库
-
SSD1306 Library库安装
#如果你的python版本是2.x pip3 install adafruit-circuitpython-ssd1306 #如果你的python版本是3.x pip install adafruit-circuitpython-ssd1306
-
Pillow(PIL)库安装
#现在最新系统已经默认安装了 sudo apt-get install python3-pi
-
代码编写
import adafruit_ssd1306 import board import busio import digitalio import time from PIL import Image, ImageDraw, ImageFont WIDTH = 128 HEIGHT = 64 BORDER = 5 # SPI初始化 # pin脚信息在board库里,是BCM模式 spi = busio.SPI(board.SCK, MOSI=board.MOSI) reset_pin = digitalio.DigitalInOut(board.D17) dc_pin = digitalio.DigitalInOut(board.D22) cs_pin = digitalio.DigitalInOut(board.CE0) oled = adafruit_ssd1306.SSD1306_SPI(WIDTH, HEIGHT, spi, dc_pin, reset_pin, cs_pin) # 初始化 清除屏幕信息 oled.fill(0) oled.show() # 创建一个空白的图像 # 确保用“1”表示 1bit 的颜色 image = Image.new("1", (oled.width, oled.height)) # 获取绘制对象来绘制图像 draw = ImageDraw.Draw(image) # 绘制一个白色的背景 draw.rectangle((0, 0, oled.width, oled.height), outline=255, fill=255) # 绘制一个小的内边框 draw.rectangle((BORDER, BORDER, oled.width - BORDER - 1, oled.height - BORDER - 1), fill=0, outline=0) # 加载默认样式 font = ImageFont.load_default() # 绘制一些文字 text = "Hello World!" (font_width, font_height) = font.getsize(text) draw.text( (oled.width // 2 - font_width // 2, oled.height // 2 - font_height // 2), text, font=font, fill=255, ) # 加载图片 image2 = Image.open('/home/pi/Pictures/logo.jpeg').resize((128, 64)).convert('1') # 此处用一个循环来播放image和image2 # image就是hello,world!,image2是打开的树莓派logo图片,3秒切换为下一张 # 退出时关闭屏幕显示,否则会一直显示 try: while True: oled.image(image) oled.show() time.sleep(3) oled.image(image2) oled.show() time.sleep(3) except KeyboardInterrupt: oled.fill(0) oled.show()
四、 结果展示
image2所用的图片
实际运行图片


