hardware-notes 原文存档

openmv ssd1306的使用

oledopenmvssd1306

`import time import framebuf from pyb import SPI  # register definitions SET_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)         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_data(self, buf):         self.temp[0] = self.addr << 1         self.temp[1] = 0x40 # Co=0, D/C#=1         self.i2c.start()         self.i2c.write(self.temp)         self.i2c.write(buf)         self.i2c.stop()                    class 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(SPI.MASTER, 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(SPI.MASTER,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(1)         self.res.low()         time.sleep(10)         self.res.high()`