1474|0

6964

帖子

11

TA的资源

版主

楼主
 

【米尔MYB-YT507开发板试用体验】python点亮SSD1306 [复制链接]

 

【米尔MYB-YT507开发板试用体验】i2c驱动 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

【米尔MYB-YT507开发板试用体验】tkinter Button学习 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

【米尔MYB-YT507开发板试用体验】串口输出 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

【米尔MYB-YT507开发板试用体验】利用tornado快速创建web服务器 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

【米尔MYB-YT507开发板试用体验】使用Python获取计算机内存及CPU信息 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

【米尔MYB-YT507开发板试用体验】安装pyecharts模块 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

【米尔MYB-YT507开发板试用体验】python显示内存、CPU实时情况1 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

【米尔MYB-YT507开发板试用体验】python显示内存、CPU实时情况2 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

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

代码如下:

#!/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([0] * (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, [cmd] + 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 & 0x7
            if pix == 1:
                self.fb[idx] |= 1 << shift
            else:
                self.fb[idx] &= ~(1 << 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[i : i+8])

    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[0] + wh[0], xy[1] + wh[1])), fill=0, outline=1)
    draw.rectangle(((xy[0] + 2, xy[1] + 2), (xy[0] + 2 + int((wh[0] - 4) * val / max), xy[1] + 2 + wh[1] - 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()

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

   下一步,动态展示开发板CPU、内存的信息。

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表