简体   繁体   中英

interfacing ssd1306 with stm32f103 on registers, i2c 'data mode' not working

I want to make my first application that uses i2c on stm32, to work with ssd1306. All communication in 'command mode' is working, and display reacts for 1 byte commands. I think problem is in 'data mode' when number of bytes in one packed is increased.

Basic function to send data over i2c

void i2c1_send(uint8_t address, uint8_t *command, uint16_t length)
{
    while(I2C1->SR2 & I2C_SR2_BUSY);
    I2C1->CR1 |= I2C_CR1_START;
    while(!(I2C1->SR1 & I2C_SR1_SB));
    I2C1->DR=address;                   //7 bit address in this byte is already shifted left by one
    while(!(I2C1->SR1 & I2C_SR1_ADDR)|!(I2C1->SR2));    //waiting for address match

    for (uint16_t i=0;i<length;i++)
    {
        I2C1->DR=command[i];                    //filling buffer with command or data
        while(!(I2C1->SR1 & I2C_SR1_BTF));      //from RM: Note: The BTF bit is not set after a NACK reception
                                                //i think i need here to wait for ack response
    }
    I2C1->CR1 |= I2C_CR1_STOP;
}

Function to send commands this works fine, it sends in summary 3 bytes of data without start/stop - [startBit, Address, ControlByte, CommandByte, stopBit]

and code:

void ssd1306_sendCommand(uint8_t toSend_u8){
    uint8_t frame_u8[2] = {0, toSend_u8};
    i2c1_send((OLED_ADDRESS<<1)|0, frame_u8,2); //sending frame
}

Control byte in command mode is 0x0, according do ssd1306 datasheet, it will be shown on image later.

Finally function for sending data , which not works

void ssd1306_sendData(uint8_t* toSend_u8p,uint8_t data_lenght)
{
    uint8_t frame_u8[256];  //making frame buffor to send
    frame_u8[0] = 0x40;     //control byte with D/C = 1 ---> 0b01000000 = 0x40

    for(uint16_t i=0; i <= data_lenght; i++){
        frame_u8[1+i] = toSend_u8p[i];
    }

    i2c1_send((OLED_ADDRESS<<1)|0, frame_u8, data_lenght+1);  //data_lenght+1 because we have additional control byte
}

i2c data format drom ssd1306 datasheet:

图像

full ssd1306 datasheet

My i2c init fx

void i2c1_init()
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; //enabling gpios
    RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; //clock for i2c1
    __DSB();__DSB();__DSB();

    //i2c pins : PB6 - SCL ; PB7 - SDA

    GPIOB->CRL &= ~(GPIO_CRL_CNF6|GPIO_CRL_CNF7);
    GPIOB->CRL |= GPIO_CRL_CNF6_1|GPIO_CRL_CNF7_1|
                    GPIO_CRL_MODE7|GPIO_CRL_MODE6;      //AF function push pull for gpios

    I2C1->CR2 |= 50;
    I2C1->CCR |= I2C_CCR_FS;
    I2C1->CCR |= 30;
    I2C1->TRISE |= 51;
    I2C1->CR1 |= I2C_CR1_ACK;
    I2C1->CR1 |= I2C_CR1_PE;

}

I don't completly understand what is the problem, and why this 'data mode' is not working

This display has a HW bug on I2C interface (sampling RD/WR bit at wrong time making it incompatible with some devices like AT32UC3 without small HW hack and or SW I2C implementation) however with STM32 it should be fine.

The configuration of SSD1306 LCD is a key as without proper init the LCD does not show anything. And tend to get stuck in weird state (after miss configuration or sending VRAM data wrongly) this LCD tends to be stuck until power off/on. So when you trial and error you need to always power off the LCD which I bet you do not do so even if your code in one trial is OK you might miss it as LCD is stuck.

Also many SSD1306 drivers use page VRAM access which seems to not work for any of those SSD1306 I have tested (all where 128x64). I use horizontal addressing mode instead which works.

Here is my own old C++ driver for this I2C LCD for AT32UC3 chips:

//------------------------------------------------------------------------------------------
//--- SSD1306 I2C OLED LCD driver ver 1.004 ------------------------------------------------
//------------------------------------------------------------------------------------------
#ifndef _LCD_SSD1306_I2C_h
#define _LCD_SSD1306_I2C_h
//------------------------------------------------------------------------------------------
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF
#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA
#define SSD1306_SETVCOMDETECT 0xDB
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9
#define SSD1306_SETMULTIPLEX 0xA8
#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10
#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_MEMORYMODE 0x20
#define SSD1306_COLUMNADDR 0x21
#define SSD1306_PAGEADDR   0x22
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8
#define SSD1306_SEGREMAP 0xA0
#define SSD1306_CHARGEPUMP 0x8D
#define SSD1306_SWITCHCAPVCC 0x2
// Scrolling #defines
#define SSD1306_ACTIVATE_SCROLL 0x2F
#define SSD1306_DEACTIVATE_SCROLL 0x2E
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
//------------------------------------------------------------------------------------------
//#define I2C_send(adr,buf,siz){} // this function is used to send packet to I2C
//------------------------------------------------------------------------------------------
#ifndef _brv8_tab
#define _brv8_tab
static const U8 brv8[256] =     // 8 bit bit reversal
    {
    0,128,64,192,32,160,96,224,16,144,80,208,48,176,112,240,8,136,72,200,40,168,104,232,24,152,
    88,216,56,184,120,248,4,132,68,196,36,164,100,228,20,148,84,212,52,180,116,244,12,140,76,204,
    44,172,108,236,28,156,92,220,60,188,124,252,2,130,66,194,34,162,98,226,18,146,82,210,50,178,
    114,242,10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250,6,134,70,198,38,166,102,230,
    22,150,86,214,54,182,118,246,14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254,1,129,
    65,193,33,161,97,225,17,145,81,209,49,177,113,241,9,137,73,201,41,169,105,233,25,153,89,217,57,
    185,121,249,5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245,13,141,77,205,45,173,109,
    237,29,157,93,221,61,189,125,253,3,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243,11,139,
    75,203,43,171,107,235,27,155,91,219,59,187,123,251,7,135,71,199,39,167,103,231,23,151,87,215,55,
    183,119,247,15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255
    };
#endif
//------------------------------------------------------------------------------------------
class LCD_SSD1306_I2C
    {
public:
    int adr;                        // I2C adr
    int xs,ys,sz;               // resoluiton
    U8 _scr[((128*96)>>3)+1];   // screen buffer
    U8 *scr;
    U8 *pyx[96];                // scan lines

    void init(int _adr,int _xs,int _ys);                // initialize LCD: I2C_adr,xs,ys
    void command(U8 cmd);
    // rendering api
    void clrscr();                                  // clear screen buffer
    void rotate(int ang);                           // rotate 180 deg
    void rfsscr();                                  // copy actual screen buffer to LCD
    void pixel(int x, int y,bool col);              // set/res pixel
    void prnchr(int x,int y,char c);                // render char at x,y (y is rounded to multiple of 8)
    void prntxt(int x,int y,const char *txt);       // render text at x,y (y is rounded to multiple of 8)
    };
//------------------------------------------------------------------------------------------
void LCD_SSD1306_I2C::command(U8 cmd)
    {
    U8 buf[2]=
        {
        0x00,       // 0x40 data/command
        cmd,
        };
    I2C_send(adr,buf,2);
    }
//------------------------------------------------------------------------------------------
void LCD_SSD1306_I2C::init(int _adr,int _xs,int _ys)
    {
    int y;
    adr=_adr;
    xs=_xs;
    ys=_ys;
    sz=xs*(ys>>3);
    const bool _external_Vcc=false;

    scr=_scr+1;                                         // skip first Byte (VRAM/command selection)
    for (y=0;y<ys;y++) pyx[y]=scr+((y>>3)*xs);          // scanlines for fast direct pixel access

    clrscr();
    // Init sequence
    U8 comPins = 0x02;
    U8 contrast = 0x8F;
         if((xs == 128) && (ys == 32)) { comPins = 0x02; contrast = 0x8F; }
    else if((xs == 128) && (ys == 64)) { comPins = 0x12; contrast = (_external_Vcc) ? 0x9F : 0xCF; }
    else if((xs ==  96) && (ys == 16)) { comPins = 0x02; contrast = (_external_Vcc) ? 0x10 : 0xAF; }
    else {} // Other screens

    static U8 init0[27]=
        {
        0x00,                                           // commands
        SSD1306_DISPLAYOFF,                             // 0xAE
        SSD1306_SETDISPLAYCLOCKDIV,0x80,                // 0xD5
        SSD1306_SETMULTIPLEX,ys-1,                      // 0xA8
        SSD1306_SETDISPLAYOFFSET,0x00,                  // 0xD3 no offset
        SSD1306_SETSTARTLINE | 0x0,                     // line 0
        SSD1306_CHARGEPUMP,(_external_Vcc)?0x10:0x14,   // 0x8D
        SSD1306_MEMORYMODE,0x00,                        // 0x20 horizontal (scanlines)
        SSD1306_SEGREMAP | 0x1,
        SSD1306_COMSCANDEC,
        SSD1306_SETCOMPINS,comPins,
        SSD1306_SETCONTRAST,contrast,
        SSD1306_SETPRECHARGE,(_external_Vcc)?0x22:0xF1, // 0xd9
        SSD1306_SETVCOMDETECT,0x40,                     // 0xDB
        SSD1306_DISPLAYALLON_RESUME,                    // 0xA4
        SSD1306_NORMALDISPLAY,                          // 0xA6
        SSD1306_DEACTIVATE_SCROLL,
        SSD1306_DISPLAYON,                              // Main screen turn on
        };
    I2C_send(adr,init0,sizeof(init0));
    }
//------------------------------------------------------------------------------------------
void LCD_SSD1306_I2C::clrscr()
    {
    for (int a=0;a<sz;a++) scr[a]=0x00;
    }
//------------------------------------------------------------------------------------------
void LCD_SSD1306_I2C::rotate(int ang)
    {
    U8 a0,a1;
    int x0,y0,x1,y1;
    if (ang==180)
     for (y0=0,y1=ys-8;y0<y1;y0+=8,y1-=8)
      for (x0=0,x1=xs-1;x0<xs;x0++,x1--)
          {
          a0=brv8[pyx[y0][x0]];
          a1=brv8[pyx[y1][x1]];
          pyx[y0][x0]=a1;
          pyx[y1][x1]=a0;
          }
    }
//------------------------------------------------------------------------------------------
void LCD_SSD1306_I2C::rfsscr()
    {
    static const U8 init1[] =
        {
        0x00,                           // commands
        SSD1306_MEMORYMODE,0,           // horizontal addresing mode
        SSD1306_COLUMNADDR,0,xs-1,      // Column start/end address (0/127 reset)
        SSD1306_PAGEADDR,0,(ys>>3)-1,   // Page start/end address (0 reset)
        };
    I2C_send(adr,(U8*)init1,sizeof(init1));

    _scr[0]=0x40;                       // 0x40 VRAM
    // SW I2C can pass whole VRAM in single packet
//  I2C_send(adr,_scr,sz+1);

    // HW I2C must use packets up to 255 bytes so 128+1
    int i,n=128; U8 *p=_scr,a;
    for (i=0;i<sz;i+=n){ a=p[0]; p[0]=0x40; I2C_send(adr,p,n+1); p[0]=a; p+=n; }
    }
//------------------------------------------------------------------------------------------
void LCD_SSD1306_I2C::pixel(int x, int y,bool col)
    {
    if ((x<0)||(x>=xs)||(y<0)||(y>=ys)) return;
    if (col) pyx[y][x] |= (1<<(y&7));
    else     pyx[y][x] &= (1<<(y&7));
    }
//------------------------------------------------------------------------------------------
void LCD_SSD1306_I2C::prnchr(int x,int y,char c)
    {
    y&=0xFFFFFFF8;  // multiple of 8
    if ((y<0)||(y>ys-8)) return;
    int i,a;
    a=c; a<<=3;
    for (i=0;i<8;i++,x++,a++)
     if ((x>=0)&&(x<xs))
      pyx[y][x]=font[a];
    }
//------------------------------------------------------------------------------------------
void LCD_SSD1306_I2C::prntxt(int x,int y,const char *txt)
    {
    for (;*txt;txt++,x+=8) prnchr(x,y,*txt);
    }
//------------------------------------------------------------------------------------------
#undef I2C_send
//------------------------------------------------------------------------------------------
#endif
//------------------------------------------------------------------------------------------

so either just extract the init packets and frame sending or use this directly but in that case you need to implement I2C_send function with whatever you have at your disposal.

In such case you will also need my font:

static const U8 font[256<<3]=
    {
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x81,0x95,0xB1,0xB1,0x95,0x81,0x7E,0x7E,0xFF,0xEB,0xCF,0xCF,0xEB,0xFF,0x7E,0x0E,0x1F,0x3F,0x7E,0x3F,0x1F,0x0E,0x00,
    0x08,0x1C,0x3E,0x7F,0x3E,0x1C,0x08,0x00,0x18,0xBA,0xFF,0xFF,0xFF,0xBA,0x18,0x00,0x10,0xB8,0xFC,0xFF,0xFC,0xB8,0x10,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,
    0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF,0x70,0xF8,0x88,0x88,0xFD,0x7F,0x07,0x0F,
    0x00,0x4E,0x5F,0xF1,0xF1,0x5F,0x4E,0x00,0xC0,0xE0,0xFF,0x7F,0x05,0x05,0x07,0x07,0xC0,0xFF,0x7F,0x05,0x05,0x65,0x7F,0x3F,0x99,0x5A,0x3C,0xE7,0xE7,0x3C,0x5A,0x99,
    0x7F,0x3E,0x3E,0x1C,0x1C,0x08,0x08,0x00,0x08,0x08,0x1C,0x1C,0x3E,0x3E,0x7F,0x00,0x00,0x24,0x66,0xFF,0xFF,0x66,0x24,0x00,0x00,0x5F,0x5F,0x00,0x00,0x5F,0x5F,0x00,
    0x06,0x0F,0x09,0x7F,0x7F,0x01,0x7F,0x7F,0x40,0xDA,0xBF,0xA5,0xFD,0x59,0x03,0x02,0x00,0x70,0x70,0x70,0x70,0x70,0x70,0x00,0x80,0x94,0xB6,0xFF,0xFF,0xB6,0x94,0x80,
    0x00,0x04,0x06,0x7F,0x7F,0x06,0x04,0x00,0x00,0x10,0x30,0x7F,0x7F,0x30,0x10,0x00,0x08,0x08,0x08,0x2A,0x3E,0x1C,0x08,0x00,0x08,0x1C,0x3E,0x2A,0x08,0x08,0x08,0x00,
    0x3C,0x3C,0x20,0x20,0x20,0x20,0x20,0x00,0x08,0x1C,0x3E,0x08,0x08,0x3E,0x1C,0x08,0x30,0x38,0x3C,0x3E,0x3E,0x3C,0x38,0x30,0x06,0x0E,0x1E,0x3E,0x3E,0x1E,0x0E,0x06,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x5F,0x5F,0x06,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x14,0x7F,0x7F,0x14,0x7F,0x7F,0x14,0x00,
    0x24,0x2E,0x6B,0x6B,0x3A,0x12,0x00,0x00,0x46,0x66,0x30,0x18,0x0C,0x66,0x62,0x00,0x30,0x7A,0x4F,0x5D,0x37,0x7A,0x48,0x00,0x04,0x07,0x03,0x00,0x00,0x00,0x00,0x00,
    0x00,0x1C,0x3E,0x63,0x41,0x00,0x00,0x00,0x00,0x41,0x63,0x3E,0x1C,0x00,0x00,0x00,0x08,0x2A,0x3E,0x1C,0x1C,0x3E,0x2A,0x08,0x08,0x08,0x3E,0x3E,0x08,0x08,0x00,0x00,
    0x00,0x80,0xE0,0x60,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00,
    0x3E,0x7F,0x71,0x59,0x4D,0x7F,0x3E,0x00,0x40,0x42,0x7F,0x7F,0x40,0x40,0x00,0x00,0x62,0x73,0x59,0x49,0x6F,0x66,0x00,0x00,0x22,0x63,0x49,0x49,0x7F,0x36,0x00,0x00,
    0x18,0x1C,0x16,0x53,0x7F,0x7F,0x50,0x00,0x27,0x67,0x45,0x45,0x7D,0x39,0x00,0x00,0x3C,0x7E,0x4B,0x49,0x79,0x30,0x00,0x00,0x03,0x03,0x71,0x79,0x0F,0x07,0x00,0x00,
    0x36,0x7F,0x49,0x49,0x7F,0x36,0x00,0x00,0x06,0x4F,0x49,0x69,0x3F,0x1E,0x00,0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x80,0xE6,0x66,0x00,0x00,0x00,0x00,
    0x08,0x1C,0x36,0x63,0x41,0x00,0x00,0x00,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x41,0x63,0x36,0x1C,0x08,0x00,0x00,0x02,0x03,0x51,0x59,0x0F,0x06,0x00,0x00,
    0x3E,0x7F,0x41,0x5D,0x5D,0x1F,0x1E,0x00,0x7C,0x7E,0x13,0x13,0x7E,0x7C,0x00,0x00,0x41,0x7F,0x7F,0x49,0x49,0x7F,0x36,0x00,0x1C,0x3E,0x63,0x41,0x41,0x63,0x22,0x00,
    0x41,0x7F,0x7F,0x41,0x63,0x3E,0x1C,0x00,0x41,0x7F,0x7F,0x49,0x5D,0x41,0x63,0x00,0x41,0x7F,0x7F,0x49,0x1D,0x01,0x03,0x00,0x1C,0x3E,0x63,0x41,0x51,0x73,0x72,0x00,
    0x7F,0x7F,0x08,0x08,0x7F,0x7F,0x00,0x00,0x00,0x41,0x7F,0x7F,0x41,0x00,0x00,0x00,0x30,0x70,0x40,0x41,0x7F,0x3F,0x01,0x00,0x41,0x7F,0x7F,0x08,0x1C,0x77,0x63,0x00,
    0x41,0x7F,0x7F,0x41,0x40,0x60,0x70,0x00,0x7F,0x7F,0x0E,0x1C,0x0E,0x7F,0x7F,0x00,0x7F,0x7F,0x06,0x0C,0x18,0x7F,0x7F,0x00,0x1C,0x3E,0x63,0x41,0x63,0x3E,0x1C,0x00,
    0x41,0x7F,0x7F,0x49,0x09,0x0F,0x06,0x00,0x1E,0x3F,0x21,0x71,0x7F,0x5E,0x00,0x00,0x41,0x7F,0x7F,0x09,0x19,0x7F,0x66,0x00,0x26,0x6F,0x4D,0x59,0x73,0x32,0x00,0x00,
    0x03,0x41,0x7F,0x7F,0x41,0x03,0x00,0x00,0x7F,0x7F,0x40,0x40,0x7F,0x7F,0x00,0x00,0x1F,0x3F,0x60,0x60,0x3F,0x1F,0x00,0x00,0x7F,0x7F,0x30,0x18,0x30,0x7F,0x7F,0x00,
    0x43,0x67,0x3C,0x18,0x3C,0x67,0x43,0x00,0x07,0x4F,0x78,0x78,0x4F,0x07,0x00,0x00,0x47,0x63,0x71,0x59,0x4D,0x67,0x73,0x00,0x00,0x7F,0x7F,0x41,0x41,0x00,0x00,0x00,
    0x01,0x03,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x41,0x41,0x7F,0x7F,0x00,0x00,0x00,0x08,0x0C,0x06,0x03,0x06,0x0C,0x08,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
    0x00,0x00,0x03,0x07,0x04,0x00,0x00,0x00,0x20,0x74,0x54,0x54,0x3C,0x78,0x40,0x00,0x41,0x7F,0x3F,0x48,0x48,0x78,0x30,0x00,0x38,0x7C,0x44,0x44,0x6C,0x28,0x00,0x00,
    0x30,0x78,0x48,0x49,0x3F,0x7F,0x40,0x00,0x38,0x7C,0x54,0x54,0x5C,0x18,0x00,0x00,0x48,0x7E,0x7F,0x49,0x03,0x02,0x00,0x00,0x98,0xBC,0xA4,0xA4,0xF8,0x7C,0x04,0x00,
    0x41,0x7F,0x7F,0x08,0x04,0x7C,0x78,0x00,0x00,0x44,0x7D,0x7D,0x40,0x00,0x00,0x00,0x60,0xE0,0x80,0x80,0xFD,0x7D,0x00,0x00,0x41,0x7F,0x7F,0x10,0x38,0x6C,0x44,0x00,
    0x00,0x41,0x7F,0x7F,0x40,0x00,0x00,0x00,0x7C,0x7C,0x18,0x38,0x1C,0x7C,0x78,0x00,0x7C,0x7C,0x04,0x04,0x7C,0x78,0x00,0x00,0x38,0x7C,0x44,0x44,0x7C,0x38,0x00,0x00,
    0x84,0xFC,0xF8,0xA4,0x24,0x3C,0x18,0x00,0x18,0x3C,0x24,0xA4,0xF8,0xFC,0x84,0x00,0x44,0x7C,0x78,0x4C,0x04,0x1C,0x18,0x00,0x48,0x5C,0x54,0x54,0x74,0x24,0x00,0x00,
    0x00,0x04,0x3E,0x7F,0x44,0x24,0x00,0x00,0x3C,0x7C,0x40,0x40,0x3C,0x7C,0x40,0x00,0x1C,0x3C,0x60,0x60,0x3C,0x1C,0x00,0x00,0x3C,0x7C,0x70,0x38,0x70,0x7C,0x3C,0x00,
    0x44,0x6C,0x38,0x10,0x38,0x6C,0x44,0x00,0x9C,0xBC,0xA0,0xA0,0xFC,0x7C,0x00,0x00,0x4C,0x64,0x74,0x5C,0x4C,0x64,0x00,0x00,0x08,0x08,0x3E,0x77,0x41,0x41,0x00,0x00,
    0x00,0x00,0x00,0x77,0x77,0x00,0x00,0x00,0x41,0x41,0x77,0x3E,0x08,0x08,0x00,0x00,0x02,0x03,0x01,0x03,0x02,0x03,0x01,0x00,0x70,0x78,0x4C,0x46,0x4C,0x78,0x70,0x00,
    0x0E,0x9F,0x91,0xB1,0xFB,0x4A,0x00,0x00,0x3A,0x7A,0x40,0x40,0x7A,0x7A,0x40,0x00,0x38,0x7C,0x54,0x55,0x5D,0x19,0x00,0x00,0x02,0x23,0x75,0x55,0x55,0x7D,0x7B,0x42,
    0x21,0x75,0x54,0x54,0x7D,0x79,0x40,0x00,0x21,0x75,0x55,0x54,0x7C,0x78,0x40,0x00,0x20,0x74,0x57,0x57,0x7C,0x78,0x40,0x00,0x18,0x3C,0xA4,0xA4,0xE4,0x40,0x00,0x00,
    0x02,0x3B,0x7D,0x55,0x55,0x5D,0x1B,0x02,0x39,0x7D,0x54,0x54,0x5D,0x19,0x00,0x00,0x39,0x7D,0x55,0x54,0x5C,0x18,0x00,0x00,0x01,0x45,0x7C,0x7C,0x41,0x01,0x00,0x00,
    0x02,0x03,0x45,0x7D,0x7D,0x43,0x02,0x00,0x01,0x45,0x7D,0x7C,0x40,0x00,0x00,0x00,0x79,0x7D,0x16,0x12,0x16,0x7D,0x79,0x00,0x70,0x78,0x2B,0x2B,0x78,0x70,0x00,0x00,
    0x44,0x7C,0x7C,0x55,0x55,0x45,0x00,0x00,0x20,0x74,0x54,0x54,0x7C,0x7C,0x54,0x54,0x7C,0x7E,0x0B,0x09,0x7F,0x7F,0x49,0x00,0x32,0x7B,0x49,0x49,0x7B,0x32,0x00,0x00,
    0x32,0x7A,0x48,0x48,0x7A,0x32,0x00,0x00,0x32,0x7A,0x4A,0x48,0x78,0x30,0x00,0x00,0x3A,0x7B,0x41,0x41,0x7B,0x7A,0x40,0x00,0x3A,0x7A,0x42,0x40,0x78,0x78,0x40,0x00,
    0x9A,0xBA,0xA0,0xA0,0xFA,0x7A,0x00,0x00,0x01,0x19,0x3C,0x66,0x66,0x3C,0x19,0x01,0x3D,0x7D,0x40,0x40,0x7D,0x3D,0x00,0x00,0x18,0x3C,0x24,0xE7,0xE7,0x24,0x24,0x00,
    0x68,0x7E,0x7F,0x49,0x43,0x66,0x20,0x00,0x2B,0x2F,0xFC,0xFC,0x2F,0x2B,0x00,0x00,0xFF,0xFF,0x09,0x09,0x2F,0xF6,0xF8,0xA0,0x40,0xC0,0x88,0xFE,0x7F,0x09,0x03,0x02,
    0x20,0x74,0x54,0x55,0x7D,0x79,0x40,0x00,0x00,0x44,0x7D,0x7D,0x41,0x00,0x00,0x00,0x30,0x78,0x48,0x4A,0x7A,0x32,0x00,0x00,0x38,0x78,0x40,0x42,0x7A,0x7A,0x40,0x00,
    0x7A,0x7A,0x0A,0x0A,0x7A,0x70,0x00,0x00,0x7D,0x7D,0x19,0x31,0x7D,0x7D,0x00,0x00,0x00,0x26,0x2F,0x29,0x2F,0x2F,0x28,0x00,0x00,0x26,0x2F,0x29,0x2F,0x26,0x00,0x00,
    0x30,0x78,0x4D,0x45,0x60,0x20,0x00,0x00,0x38,0x38,0x08,0x08,0x08,0x08,0x00,0x00,0x08,0x08,0x08,0x08,0x38,0x38,0x00,0x00,0x4F,0x6F,0x30,0x18,0xCC,0xEE,0xBB,0x91,
    0x4F,0x6F,0x30,0x18,0x6C,0x76,0xFB,0xF9,0x00,0x00,0x00,0x7B,0x7B,0x00,0x00,0x00,0x08,0x1C,0x36,0x22,0x08,0x1C,0x36,0x22,0x22,0x36,0x1C,0x08,0x22,0x36,0x1C,0x08,
    0xAA,0x00,0x55,0x00,0xAA,0x00,0x55,0x00,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xDD,0xFF,0xAA,0x77,0xDD,0xAA,0xFF,0x77,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,
    0x10,0x10,0x10,0xFF,0xFF,0x00,0x00,0x00,0x14,0x14,0x14,0xFF,0xFF,0x00,0x00,0x00,0x10,0x10,0xFF,0xFF,0x00,0xFF,0xFF,0x00,0x10,0x10,0xF0,0xF0,0x10,0xF0,0xF0,0x00,
    0x14,0x14,0x14,0xFC,0xFC,0x00,0x00,0x00,0x14,0x14,0xF7,0xF7,0x00,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0x00,0xFF,0xFF,0x00,0x14,0x14,0xF4,0xF4,0x04,0xFC,0xFC,0x00,
    0x14,0x14,0x17,0x17,0x10,0x1F,0x1F,0x00,0x10,0x10,0x1F,0x1F,0x10,0x1F,0x1F,0x00,0x14,0x14,0x14,0x1F,0x1F,0x00,0x00,0x00,0x10,0x10,0x10,0xF0,0xF0,0x00,0x00,0x00,
    0x00,0x00,0x00,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0x1F,0x10,0x10,0x10,0x10,0x10,0x10,0xF0,0xF0,0x10,0x10,0x10,0x00,0x00,0x00,0xFF,0xFF,0x10,0x10,0x10,
    0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xFF,0xFF,0x10,0x10,0x10,0x00,0x00,0x00,0xFF,0xFF,0x14,0x14,0x14,0x00,0x00,0xFF,0xFF,0x00,0xFF,0xFF,0x10,
    0x00,0x00,0x1F,0x1F,0x10,0x17,0x17,0x14,0x00,0x00,0xFC,0xFC,0x04,0xF4,0xF4,0x14,0x14,0x14,0x17,0x17,0x10,0x17,0x17,0x14,0x14,0x14,0xF4,0xF4,0x04,0xF4,0xF4,0x14,
    0x00,0x00,0xFF,0xFF,0x00,0xF7,0xF7,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0xF7,0xF7,0x00,0xF7,0xF7,0x14,0x14,0x14,0x14,0x17,0x17,0x14,0x14,0x14,
    0x10,0x10,0x1F,0x1F,0x10,0x1F,0x1F,0x10,0x14,0x14,0x14,0xF4,0xF4,0x14,0x14,0x14,0x10,0x10,0xF0,0xF0,0x10,0xF0,0xF0,0x10,0x00,0x00,0x1F,0x1F,0x10,0x1F,0x1F,0x10,
    0x00,0x00,0x00,0x1F,0x1F,0x14,0x14,0x14,0x00,0x00,0x00,0xFC,0xFC,0x14,0x14,0x14,0x00,0x00,0xF0,0xF0,0x10,0xF0,0xF0,0x10,0x10,0x10,0xFF,0xFF,0x10,0xFF,0xFF,0x10,
    0x14,0x14,0x14,0xFF,0xFF,0x14,0x14,0x14,0x10,0x10,0x10,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x10,0x10,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
    0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
    0x38,0x7C,0x44,0x6C,0x38,0x6C,0x44,0x00,0xFC,0xFE,0x2A,0x2A,0x3E,0x14,0x00,0x00,0x7E,0x7E,0x02,0x02,0x06,0x06,0x00,0x00,0x02,0x7E,0x7E,0x02,0x7E,0x7E,0x02,0x00,
    0x63,0x77,0x5D,0x49,0x63,0x63,0x00,0x00,0x38,0x7C,0x44,0x7C,0x3C,0x04,0x04,0x00,0x80,0xFE,0x7E,0x20,0x20,0x3E,0x1E,0x00,0x04,0x06,0x02,0x7E,0x7C,0x06,0x02,0x00,
    0x99,0xBD,0xE7,0xE7,0xBD,0x99,0x00,0x00,0x1C,0x3E,0x6B,0x49,0x6B,0x3E,0x1C,0x00,0x4C,0x7E,0x73,0x01,0x73,0x7E,0x4C,0x00,0x30,0x78,0x4A,0x4F,0x7D,0x39,0x00,0x00,
    0x18,0x3C,0x24,0x3C,0x3C,0x24,0x3C,0x18,0x98,0xFC,0x64,0x3C,0x3E,0x27,0x3D,0x18,0x1C,0x3E,0x6B,0x49,0x49,0x00,0x00,0x00,0x7E,0x7F,0x01,0x01,0x7F,0x7E,0x00,0x00,
    0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x00,0x00,0x44,0x44,0x5F,0x5F,0x44,0x44,0x00,0x00,0x40,0x51,0x5B,0x4E,0x44,0x40,0x00,0x00,0x40,0x44,0x4E,0x5B,0x51,0x40,0x00,0x00,
    0x00,0x00,0x00,0xFE,0xFF,0x01,0x07,0x06,0x60,0xE0,0x80,0xFF,0x7F,0x00,0x00,0x00,0x08,0x08,0x6B,0x6B,0x08,0x08,0x00,0x00,0x24,0x36,0x12,0x36,0x24,0x36,0x12,0x00,
    0x00,0x06,0x0F,0x09,0x0F,0x06,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x10,0x30,0x70,0xC0,0xFF,0xFF,0x01,0x01,
    0x00,0x1F,0x1F,0x01,0x1F,0x1E,0x00,0x00,0x00,0x19,0x1D,0x17,0x12,0x00,0x00,0x00,0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    };

The usage is like this:

#include "font_8x8.h"
#include "LCD_SSD1306_I2C.h"
LCD_SSD1306_I2C lcd;

// init
for (int adr=1;adr<128;adr++) // find I2C device
 if (I2C_probe(adr))
    {
    lcd.init(adr,128,64); // LCD address and resolution
    break;
    }

// render
lcd.clrscr();
lcd.prntxt(0,0,"test LCD");
lcd.pixel(10,10,true);
lcd.rfsscr();

just exchange the I2C_??? stuff with what you have.

Take a close look to init and rfsscr functions and corssreference with what you do and repair/test until its working...

DO NOT FORGET TO SWITH POWER OFF/ON BETFORE ANY TESTS !!!

[edit1] I rewrited my old driver

so here is newer version of the driver with some bugs sorted out and added rendering capabilities like patterned lines, filed polygons...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM