1. 需下載 ssd1306 drive (基本上版本很老舊)
2. Mu Editor 的程式檔預設在 user目錄下的 mu_code
3. 串行數據線SDA (21)和串行時鐘線SCL (22) 分別接線為 PIN 21 和 PIN 22
4. OLED 為 1.3 吋 128*64 (中文字 16*16, 即每行8個中文字,英文16字)
參考程式: (會產生過舊警告 Warning: I2C(-1, ...) is deprecated, use SoftI2C(...) instead )
運行成功時面板上會顯示 Hello world!然而若修改使用 SoftI2C 則會產生 module 錯誤,需修正module.
ssd1306.py 驅動程式碼
https://github.com/micropython/micropyt ... ssd1306.py
2. Mu Editor 的程式檔預設在 user目錄下的 mu_code
3. 串行數據線SDA (21)和串行時鐘線SCL (22) 分別接線為 PIN 21 和 PIN 22
4. OLED 為 1.3 吋 128*64 (中文字 16*16, 即每行8個中文字,英文16字)
參考程式: (會產生過舊警告 Warning: I2C(-1, ...) is deprecated, use SoftI2C(...) instead )
運行成功時面板上會顯示 Hello world!
CODE:
import machineimport ssd1306# 初始化I2Ci2c = machine.I2C(scl=machine.Pin(22), sda=machine.Pin(21))#i2c = machine.SoftI2C(scl=machine.Pin(22), sda=machine.Pin(21),freq=400000)# 初始化OLED顯示器oled = ssd1306.SSD1306_I2C(128, 64, i2c)# 清除顯示器oled.fill(0)# 在顯示器上顯示文本oled.text('Hello, World!', 0, 0)oled.show()
ssd1306.py 驅動程式碼
https://github.com/micropython/micropyt ... ssd1306.py
CODE:
# MicroPython SSD1306 OLED driver, I2C and SPI interfacesimport timeimport framebuf# register definitionsSET_CONTRAST = const(0x81)SET_ENTIRE_ON = const(0xa4)SET_NORM_INV = const(0xa6)SET_DISP = const(0xae)SET_MEM_ADDR = const(0x20)SET_COL_ADDR = const(0x21)SET_PAGE_ADDR = const(0x22)SET_DISP_START_LINE = const(0x40)SET_SEG_REMAP = const(0xa0)SET_MUX_RATIO = const(0xa8)SET_COM_OUT_DIR = const(0xc0)SET_DISP_OFFSET = const(0xd3)SET_COM_PIN_CFG = const(0xda)SET_DISP_CLK_DIV = const(0xd5)SET_PRECHARGE = const(0xd9)SET_VCOM_DESEL = const(0xdb)SET_CHARGE_PUMP = const(0x8d)class SSD1306: def __init__(self, width, height, external_vcc): self.width = width self.height = height self.external_vcc = external_vcc self.pages = self.height // 8 # Note the subclass must initialize self.framebuf to a framebuffer. # This is necessary because the underlying data buffer is different # between I2C and SPI implementations (I2C needs an extra byte). self.poweron() self.init_display() def init_display(self): for cmd in ( SET_DISP | 0x00, # off # address setting SET_MEM_ADDR, 0x00, # horizontal # resolution and layout SET_DISP_START_LINE | 0x00, SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 SET_MUX_RATIO, self.height - 1, SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0 SET_DISP_OFFSET, 0x00, SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12, # timing and driving scheme SET_DISP_CLK_DIV, 0x80, SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1, SET_VCOM_DESEL, 0x30, # 0.83*Vcc # display SET_CONTRAST, 0xff, # maximum SET_ENTIRE_ON, # output follows RAM contents SET_NORM_INV, # not inverted # charge pump SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14, SET_DISP | 0x01): # on self.write_cmd(cmd) self.fill(0) self.show() def poweroff(self): self.write_cmd(SET_DISP | 0x00) def contrast(self, contrast): self.write_cmd(SET_CONTRAST) self.write_cmd(contrast) def invert(self, invert): self.write_cmd(SET_NORM_INV | (invert & 1)) def show(self): x0 = 0 x1 = self.width - 1 if self.width == 64: # displays with width of 64 pixels are shifted by 32 x0 += 32 x1 += 32 self.write_cmd(SET_COL_ADDR) self.write_cmd(x0) self.write_cmd(x1) self.write_cmd(SET_PAGE_ADDR) self.write_cmd(0) self.write_cmd(self.pages - 1) self.write_framebuf() def fill(self, col): self.framebuf.fill(col) def pixel(self, x, y, col): self.framebuf.pixel(x, y, col) def scroll(self, dx, dy): self.framebuf.scroll(dx, dy) def text(self, string, x, y, col=1): self.framebuf.text(string, x, y, col)class SSD1306_I2C(SSD1306): def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False): self.i2c = i2c self.addr = addr self.temp = bytearray(2) # Add an extra byte to the data buffer to hold an I2C data/command byte # to use hardware-compatible I2C transactions. A memoryview of the # buffer is used to mask this byte from the framebuffer operations # (without a major memory hit as memoryview doesn't copy to a separate # buffer). self.buffer = bytearray(((height // 8) * width) + 1) self.buffer[0] = 0x40 # Set first byte of data buffer to Co=0, D/C=1 self.framebuf = framebuf.FrameBuffer1(memoryview(self.buffer)[1:], width, height) super().__init__(width, height, external_vcc) def write_cmd(self, cmd): self.temp[0] = 0x80 # Co=1, D/C#=0 self.temp[1] = cmd self.i2c.writeto(self.addr, self.temp) def write_framebuf(self): # Blast out the frame buffer using a single I2C transaction to support # hardware I2C interfaces. self.i2c.writeto(self.addr, self.buffer) def poweron(self): passclass SSD1306_SPI(SSD1306): def __init__(self, width, height, spi, dc, res, cs, external_vcc=False): self.rate = 10 * 1024 * 1024 dc.init(dc.OUT, value=0) res.init(res.OUT, value=0) cs.init(cs.OUT, value=1) self.spi = spi self.dc = dc self.res = res self.cs = cs self.buffer = bytearray((height // 8) * width) self.framebuf = framebuf.FrameBuffer1(self.buffer, width, height) super().__init__(width, height, external_vcc) def write_cmd(self, cmd): self.spi.init(baudrate=self.rate, polarity=0, phase=0) self.cs.high() self.dc.low() self.cs.low() self.spi.write(bytearray([cmd])) self.cs.high() def write_framebuf(self): self.spi.init(baudrate=self.rate, polarity=0, phase=0) self.cs.high() self.dc.high() self.cs.low() self.spi.write(self.buffer) self.cs.high() def poweron(self): self.res.high() time.sleep_ms(1) self.res.low() time.sleep_ms(10) self.res.high()
統計資料: 發表於 由 dtchang — 2024-01-31, 19:20