lugl4313820 发表于 2022-8-7 14:16

【米尔MYB-YT507开发板试用体验】python点亮SSD1306

<p><a href="https://bbs.eeworld.com.cn/thread-1211854-1-1.html">【米尔MYB-YT507开发板试用体验】i2c驱动 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1211920-1-1.html">【米尔MYB-YT507开发板试用体验】tkinter Button学习 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1212553-1-1.html">【米尔MYB-YT507开发板试用体验】串口输出 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1212699-1-1.html">【米尔MYB-YT507开发板试用体验】利用tornado快速创建web服务器 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1212705-1-1.html">【米尔MYB-YT507开发板试用体验】使用Python获取计算机内存及CPU信息 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1212951-1-1.html">【米尔MYB-YT507开发板试用体验】安装pyecharts模块 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1212963-1-1.html">【米尔MYB-YT507开发板试用体验】python显示内存、CPU实时情况1 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1212967-1-1.html">【米尔MYB-YT507开发板试用体验】python显示内存、CPU实时情况2 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)</a></p>

<p>前面驱动了i2c总线。为了更好展示i2c的驱动能力与方法,这几天找了资料,成功驱动了OLED的显示屏:</p>

<p>代码如下:</p>

<pre>
<code>#!/usr/bin/env python
# -*- coding:utf-8 -*-

from smbus import SMBus
from PIL import Image, ImageDraw

I2C_ADAPTER = 4
SSD1306_ADDR = 0x3C

class SSD1306Vals:
    CMD_PREFIX =         0x00
    DATA_PREFIX =          0x40

    MEMORY_MODE =          0x20
    COL_ADDR =             0x21
    PAGE_ADDR =            0x22
    DISABLE_SCROLL =       0x2E
    SET_START_LINE =       0x40
    SET_CONTRAST =         0x81
    SET_CHARGE_PUMP =      0x8D
    SET_SEGMENT_REMAP =    0xA0
    DISPLAY_VRAM =         0xA4
    DISPLAY_FORCE_WHITE =0xA5
    DISPLAY_NORMAL =       0xA6
    MULTIPLEX_RATIO =      0xA8
    DISPLAY_OFF =          0xAE
    DISPLAY_ON =         0xAF
    SET_COM_SCAN_DIR =   0xC8
    SET_DISPLAY_OFFSET =   0xD3
    SET_DISPLAY_CLK_DIV =0xD5
    SET_PRECHARGE_PERIOD = 0xD9
    SET_COMPINS =          0xDA
    SET_VCOM_LEVEL =       0xDB

class SSD1306:
    def __init__(self, bus=4, addr=0x3C):
      # create interfacing objects
      self.bus = SMBus(bus)
      self.addr = addr
      self.fb = bytearray( * (128 * 64 // 8))

      # create PIL objects
      self.img = Image.new("1", (128, 64), 0)
      self.draw = ImageDraw.Draw(self.img)

    def cmd(self, cmd, *args):
      self.bus.write_i2c_block_data(self.addr, SSD1306Vals.CMD_PREFIX, + list(args))
    def data(self, data):
      self.bus.write_i2c_block_data(self.addr, SSD1306Vals.DATA_PREFIX, list(data))

    def flip(self):
      # convert PIL image data into framebuffer data
      for coord, pix in enumerate(self.img.getdata()):
            x, y = coord % 128, coord // 128
            idx, shift = x + ((y // 8) * 128), y &amp; 0x7
            if pix == 1:
                self.fb |= 1 &lt;&lt; shift
            else:
                self.fb &amp;= ~(1 &lt;&lt; shift)
            
      # write framebuffer
      self.cmd(SSD1306Vals.PAGE_ADDR, 0, 0xFF)
      self.cmd(SSD1306Vals.COL_ADDR, 0, 127)
      for i in range(0, 128 * 64 // 8, 8):
            self.data(self.fb)

    def power(self, val):
      self.cmd(SSD1306Vals.DISPLAY_ON if val else SSD1306Vals.DISPLAY_OFF)

    def init(self):
      self.cmd(SSD1306Vals.DISPLAY_OFF)
      self.cmd(SSD1306Vals.SET_DISPLAY_CLK_DIV, 0x80) # suggested ratio
      self.cmd(SSD1306Vals.MULTIPLEX_RATIO, 63) # height - 1
      self.cmd(SSD1306Vals.SET_DISPLAY_OFFSET, 0)
      self.cmd(SSD1306Vals.SET_START_LINE | 0)
      self.cmd(SSD1306Vals.SET_CHARGE_PUMP, 0x14)
      self.cmd(SSD1306Vals.MEMORY_MODE, 0)
      self.cmd(SSD1306Vals.SET_SEGMENT_REMAP | 1)
      self.cmd(SSD1306Vals.SET_COM_SCAN_DIR)
      self.cmd(SSD1306Vals.SET_COMPINS, 0x12)
      # drive the display at a lower contrast to prevent burnout
      # remember, this poor panel is going to be running 24/7!
      # "normal" value: 0xC8
      self.cmd(SSD1306Vals.SET_CONTRAST, 0x00)
      self.cmd(SSD1306Vals.SET_PRECHARGE_PERIOD, 0xF1)
      self.cmd(SSD1306Vals.SET_VCOM_LEVEL, 0x40)
      self.cmd(SSD1306Vals.DISPLAY_VRAM)
      self.cmd(SSD1306Vals.DISPLAY_NORMAL)
      self.cmd(SSD1306Vals.DISABLE_SCROLL)
      self.cmd(SSD1306Vals.DISPLAY_ON)
      print(1)
      self.flip()
## Helper functions
def draw_progress(draw: ImageDraw, xy, wh, val, max):
    draw.rectangle((xy, (xy + wh, xy + wh)), fill=0, outline=1)
    draw.rectangle(((xy + 2, xy + 2), (xy + 2 + int((wh - 4) * val / max), xy + 2 + wh - 4)), fill=1)

def draw_text_center(draw: ImageDraw, y, text):
    w, _ = draw.textsize(text)
    draw.text((64 - (w // 2), y), text, fill=1)
def draw_text_right(draw: ImageDraw, y, text):
    draw.text((0, y), text, fill=1)
def draw_text_left(draw: ImageDraw, y, text):
    w, _ = draw.textsize(text)
    draw.text((128 - w, y), text, fill=1)

if __name__ == "__main__":
    display = SSD1306(I2C_ADAPTER, SSD1306_ADDR)
    display.init()
    display.draw.rectangle((123, 0, 127, 16), fill=1)
    display.draw.text((0,0),"ssd1306 DEMO",fill=1)
    display.draw.text((0,16),"MYB-YT507",fill=1)
    display.draw.text((16,32),"by lugl@qq.com",fill=1)
    display.draw.text((16,48),"HELLO EEWORLD",fill=1)
    display.flip()</code></pre>

<p>将文件拷到开发板,运行,效果如下:</p>

<p> &nbsp;&nbsp;下一步,动态展示开发板CPU、内存的信息。</p>
页: [1]
查看完整版本: 【米尔MYB-YT507开发板试用体验】python点亮SSD1306