STM8 Microcontrollers – the Final Chapters

Hardware

OLED Display – SSD1306/SSD1309

At present LED technology is quickly conquering the world with new innovations and wonders. Organic LED (OLED) displays are just one example of such wonders. In the market, there are many OLED display modules available, varying in size and resolution. Most of them are based on SSD1306/SSD1309 and have a resolution of 128×64 bits. Most of them are either fully monochrome or dual colour-based. There are other OLED displays with full RGB colour support. SSD1306 display chip supports both I2C and SPI communication methods. It is nice to integrate a tiny and stylish graphical display as such in projects.

OLED

Hardware Connection

OLED

Code Example

font.h

static const unsigned char font_regular[92][6] =
{                       
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // sp
    0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,   // !
    0x00, 0x00, 0x07, 0x00, 0x07, 0x00,   // "
    0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,   // #
    0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,   // $
    0x00, 0x62, 0x64, 0x08, 0x13, 0x23,   // %
    0x00, 0x36, 0x49, 0x55, 0x22, 0x50,   // &
    0x00, 0x00, 0x05, 0x03, 0x00, 0x00,   // '
    0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,   // (
    0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,   // )
    0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,   // *
    0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,   // +
    0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,   // ,
    0x00, 0x08, 0x08, 0x08, 0x08, 0x08,   // -
    0x00, 0x00, 0x60, 0x60, 0x00, 0x00,   // .
    0x00, 0x20, 0x10, 0x08, 0x04, 0x02,   // /
    0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,   // 0
    0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,   // 1
    0x00, 0x42, 0x61, 0x51, 0x49, 0x46,   // 2
    0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,   // 3
    0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,   // 4
    0x00, 0x27, 0x45, 0x45, 0x45, 0x39,   // 5
    0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,   // 6
    0x00, 0x01, 0x71, 0x09, 0x05, 0x03,   // 7
    0x00, 0x36, 0x49, 0x49, 0x49, 0x36,   // 8
    0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,   // 9
    0x00, 0x00, 0x36, 0x36, 0x00, 0x00,   // :
    0x00, 0x00, 0x56, 0x36, 0x00, 0x00,   // ;
    0x00, 0x08, 0x14, 0x22, 0x41, 0x00,   // <
    0x00, 0x14, 0x14, 0x14, 0x14, 0x14,   // =
    0x00, 0x00, 0x41, 0x22, 0x14, 0x08,   // >
    0x00, 0x02, 0x01, 0x51, 0x09, 0x06,   // ?
    0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,   // @
    0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,   // A
    0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,   // B
    0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,   // C
    0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,   // D
    0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,   // E
    0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,   // F
    0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,   // G
    0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,   // H
    0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,   // I
    0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,   // J
    0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,   // K
    0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,   // L
    0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,   // M
    0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,   // N
    0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,   // O
    0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,   // P
    0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,   // Q
    0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,   // R
    0x00, 0x46, 0x49, 0x49, 0x49, 0x31,   // S
    0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,   // T
    0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,   // U
    0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,   // V
    0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,   // W
    0x00, 0x63, 0x14, 0x08, 0x14, 0x63,   // X
    0x00, 0x07, 0x08, 0x70, 0x08, 0x07,   // Y
    0x00, 0x61, 0x51, 0x49, 0x45, 0x43,   // Z
    0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,   // [
    0x00, 0x02, 0x04, 0x08, 0x10, 0x20,   // \92
    0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,   // ]
    0x00, 0x04, 0x02, 0x01, 0x02, 0x04,   // ^
    0x00, 0x40, 0x40, 0x40, 0x40, 0x40,   // _
    0x00, 0x00, 0x01, 0x02, 0x04, 0x00,   // '
    0x00, 0x20, 0x54, 0x54, 0x54, 0x78,   // a
    0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,   // b
    0x00, 0x38, 0x44, 0x44, 0x44, 0x20,   // c
    0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,   // d
    0x00, 0x38, 0x54, 0x54, 0x54, 0x18,   // e
    0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,   // f
    0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,   // g
    0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,   // h
    0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,   // i
    0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,   // j
    0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,   // k
    0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,   // l
    0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,   // m
    0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,   // n
    0x00, 0x38, 0x44, 0x44, 0x44, 0x38,   // o
    0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,   // p
    0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,   // q
    0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,   // r
    0x00, 0x48, 0x54, 0x54, 0x54, 0x20,   // s
    0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,   // t
    0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,   // u
    0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,   // v
    0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,   // w
    0x00, 0x44, 0x28, 0x10, 0x28, 0x44,   // x
    0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,   // y
    0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,   // z
    0x14, 0x14, 0x14, 0x14, 0x14, 0x14    // horiz lines
};

 

SSD1306.h

#include "STM8S.h"


#define I2C_PORT                                             GPIOE

#define SCL_pin                                              GPIO_PIN_1
#define SDA_pin                                            GPIO_PIN_2

#define SSD1306_I2C_Address                                 0x78

#define DAT                                                0x60
#define CMD                                                0x00

#define Set_Lower_Column_Start_Address_CMD                 0x00
#define Set_Higher_Column_Start_Address_CMD                0x10
#define Set_Memory_Addressing_Mode_CMD                     0x20
#define Set_Column_Address_CMD                             0x21
#define Set_Page_Address_CMD                               0x22
#define Set_Display_Start_Line_CMD                         0x40
#define Set_Contrast_Control_CMD                           0x81
#define Set_Charge_Pump_CMD                                0x8D
#define Set_Segment_Remap_CMD                              0xA0
#define Set_Entire_Display_ON_CMD                          0xA4
#define Set_Normal_or_Inverse_Display_CMD                  0xA6
#define Set_Multiplex_Ratio_CMD                            0xA8
#define Set_Display_ON_or_OFF_CMD                          0xAE
#define Set_Page_Start_Address_CMD                         0xB0
#define Set_COM_Output_Scan_Direction_CMD                  0xC0
#define Set_Display_Offset_CMD                             0xD3
#define Set_Display_Clock_CMD                              0xD5
#define Set_Pre_charge_Period_CMD                          0xD9
#define Set_Common_HW_Config_CMD                           0xDA
#define Set_VCOMH_Level_CMD                                0xDB
#define Set_NOP_CMD                                        0xE3

#define Horizontal_Addressing_Mode                         0x00
#define Vertical_Addressing_Mode                           0x01
#define Page_Addressing_Mode                               0x02

#define Disable_Charge_Pump                                0x00
#define Enable_Charge_Pump                                 0x04

#define Column_Address_0_Mapped_to_SEG0                    0x00
#define Column_Address_0_Mapped_to_SEG127                  0x01

#define Normal_Display                                     0x00
#define Entire_Display_ON                                  0x01

#define Non_Inverted_Display                               0x00
#define Inverted_Display                                   0x01

#define Display_OFF                                         0x00
#define Display_ON                                          0x01

#define Scan_from_COM0_to_63                                0x00
#define Scan_from_COM63_to_0                                0x08

#define x_size                                             128
#define x_max                                              x_size
#define x_min                                              0
#define y_size                                             64
#define y_max                                              8
#define y_min                                              0

#define ON                                                 1
#define OFF                                                0

#define YES                                                1
#define NO                                                 0

#define ROUND                                              1
#define SQUARE                                             0

#define buffer_size                                        1024//(x_max * y_max)


extern unsigned char buffer[buffer_size];


void I2C_setup(void);
void OLED_HW_setup(void);
void OLED_init(void);
void OLED_write(unsigned char value, unsigned char control_byte);
void OLED_gotoxy(unsigned char x_pos, unsigned char y_pos);
void OLED_fill(unsigned char bmp_data);
void OLED_print_Image(const unsigned char *bmp, unsigned char pixel);
void OLED_clear_screen(void);
void OLED_clear_buffer(void);
void OLED_cursor(unsigned char x_pos, unsigned char y_pos);
void OLED_draw_bitmap(unsigned char xb, unsigned char yb, unsigned char xe, unsigned char ye, unsigned char *bmp_img);
void OLED_print_char(unsigned char x_pos, unsigned char y_pos, unsigned char ch);
void OLED_print_string(unsigned char x_pos, unsigned char y_pos, unsigned char *ch);
void OLED_print_chr(unsigned char x_pos, unsigned char y_pos, signed int value);
void OLED_print_int(unsigned char x_pos, unsigned char y_pos, signed long value);
void OLED_print_decimal(unsigned char x_pos, unsigned char y_pos, unsigned int value, unsigned char points);
void OLED_print_float(unsigned char x_pos, unsigned char y_pos, float value, unsigned char points);
void Draw_Pixel(unsigned char x_pos, unsigned char y_pos, unsigned char colour);
void Draw_Line(signed int x1, signed int y1, signed int x2, signed int y2, unsigned char colour);
void Draw_Rectangle(signed int x1, signed int y1, signed int x2, signed int y2, unsigned char fill, unsigned char colour, unsigned char type);
void Draw_Circle(signed int xc, signed int yc, signed int radius, unsigned char fill, unsigned char colour);

 

SSD1306.c

#include "fonts.h"
#include "SSD1306.h"


void I2C_setup(void)
{
    I2C_DeInit();

    I2C_Init(100000,
             SSD1306_I2C_Address,
             I2C_DUTYCYCLE_2,
             I2C_ACK_CURR,
             I2C_ADDMODE_7BIT,
             (CLK_GetClockFreq() / 1000000));

    I2C_Cmd(ENABLE);
}


void OLED_HW_setup(void)
{
       GPIO_Init(I2C_PORT, SCL_pin, GPIO_MODE_OUT_OD_HIZ_FAST);
       GPIO_Init(I2C_PORT, SDA_pin, GPIO_MODE_OUT_OD_HIZ_FAST);

    I2C_setup();
}


void OLED_init(void)
{
     OLED_HW_setup();
     delay_ms(100);

     OLED_write((Set_Display_ON_or_OFF_CMD | Display_OFF), CMD);
     OLED_write(Set_Multiplex_Ratio_CMD, CMD);
     OLED_write(0x3F, CMD);
     OLED_write(Set_Display_Offset_CMD, CMD);
     OLED_write(0x00, CMD);
     OLED_write(Set_Display_Start_Line_CMD, CMD);
     OLED_write((Set_Segment_Remap_CMD | Column_Address_0_Mapped_to_SEG127), CMD);
     OLED_write((Set_COM_Output_Scan_Direction_CMD | Scan_from_COM63_to_0), CMD);
     OLED_write(Set_Common_HW_Config_CMD, CMD);
     OLED_write(0x12, CMD);
     OLED_write(Set_Contrast_Control_CMD, CMD);
     OLED_write(0xFF, CMD);
     OLED_write(Set_Entire_Display_ON_CMD, CMD);
     OLED_write(Set_Normal_or_Inverse_Display_CMD, CMD);
     OLED_write(Set_Display_Clock_CMD, CMD);
     OLED_write(0x80, CMD);
     OLED_write(Set_Pre_charge_Period_CMD, CMD);
     OLED_write(0x25, CMD);
     OLED_write(Set_VCOMH_Level_CMD, CMD);
     OLED_write(0x20, CMD);
     OLED_write(Set_Page_Address_CMD, CMD);
     OLED_write(0x00, CMD);
     OLED_write(0x07, CMD);
     OLED_write(Set_Page_Start_Address_CMD , CMD);
     OLED_write(Set_Higher_Column_Start_Address_CMD, CMD);
     OLED_write(Set_Lower_Column_Start_Address_CMD, CMD);
     OLED_write(Set_Memory_Addressing_Mode_CMD, CMD);
     OLED_write(0x02, CMD);
     OLED_write(Set_Charge_Pump_CMD, CMD);
     OLED_write(0x14, CMD);
     OLED_write((Set_Display_ON_or_OFF_CMD | Display_ON), CMD);
}


void OLED_write(unsigned char value, unsigned char control_byte)
{
    while(I2C_GetFlagStatus(I2C_FLAG_BUSBUSY));

    I2C_GenerateSTART(ENABLE);
    while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

    I2C_Send7bitAddress(SSD1306_I2C_Address, I2C_DIRECTION_TX);
    while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    I2C_SendData(control_byte);
    while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));

    I2C_SendData(value);
    while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    I2C_GenerateSTOP(ENABLE); 
}


void OLED_gotoxy(unsigned char x_pos, unsigned char y_pos)
{
     OLED_write((Set_Page_Start_Address_CMD + y_pos), CMD);
     OLED_write(((x_pos & 0x0F) | Set_Lower_Column_Start_Address_CMD), CMD);
     OLED_write((((x_pos & 0xF0) >> 0x04) | Set_Higher_Column_Start_Address_CMD), CMD);
}


void OLED_fill(unsigned char bmp_data)
{
    unsigned char x_pos = 0x00;
    unsigned char page = 0x00;

    for(page = 0; page < y_max; page++)
    {
        OLED_gotoxy(x_min, page);

        I2C_GenerateSTART(ENABLE);
        while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

        I2C_Send7bitAddress(SSD1306_I2C_Address, I2C_DIRECTION_TX);
        while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

        I2C_SendData(DAT);
        while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));   

        for(x_pos = x_min; x_pos < x_max; x_pos++)
        {
           I2C_SendData(bmp_data);
                 while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED)); 
        }

        I2C_GenerateSTOP(ENABLE); 
    }
}


void OLED_print_Image(const unsigned char *bmp, unsigned char pixel)
{
    unsigned char x_pos = 0;
    unsigned char page = 0;

    if(pixel != OFF)
    {
        pixel = 0xFF;
    }
    else
    {
        pixel = 0x00;
    }

    for(page = 0; page < y_max; page++)
    {
         OLED_gotoxy(x_min, page);

         I2C_GenerateSTART(ENABLE);
         while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

         I2C_Send7bitAddress(SSD1306_I2C_Address, I2C_DIRECTION_TX);
         while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

         I2C_SendData(DAT);
         while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING));   

         for(x_pos = x_min; x_pos < x_max; x_pos++)
         {
            I2C_SendData((*bmp++ ^ pixel));
            while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
         }

               I2C_GenerateSTOP(ENABLE);
     }
}


void OLED_clear_screen(void)
{
    OLED_fill(0x00);
}


void OLED_clear_buffer(void)
{
     unsigned int s = 0x0000;

     for(s = 0; s < buffer_size; s++)
     {
          buffer[s] = 0x00;
     }
}


void OLED_cursor(unsigned char x_pos, unsigned char y_pos)
{
    unsigned char s = 0x00;

    if(y_pos != 0x00)
    {
        if(x_pos == 1)
        {
            OLED_gotoxy(0x00, (y_pos + 0x02));
        }
        else
        {
            OLED_gotoxy((0x50 + ((x_pos - 0x02) * 0x06)), (y_pos + 0x02));
        }

        for(s = 0x00; s < 0x06; s++)
        {
            OLED_write(0xFF, DAT);
        }
    }
}


void OLED_draw_bitmap(unsigned char xb, unsigned char yb, unsigned char xe, unsigned char ye, unsigned char *bmp_img)
{
    unsigned int s = 0x0000;
    unsigned char x_pos = 0x00;
    unsigned char y_pos = 0x00;

    for(y_pos = yb; y_pos <= ye; y_pos++)
    {
        OLED_gotoxy(xb, y_pos);
        for(x_pos = xb; x_pos < xe; x_pos++)
        {
            OLED_write(bmp_img[s++], DAT);
        }
    }
}


void OLED_print_char(unsigned char x_pos, unsigned char y_pos, unsigned char ch)
{
  unsigned char s = 0x00;
  unsigned char chr = 0x00;

  chr = (ch - 0x20);

  if(x_pos > (x_max - 0x06))
  {
    x_pos = 0x00;
    y_pos++;
  }
  OLED_gotoxy(x_pos, y_pos);

  for(s = 0x00; s < 0x06; s++)
  {
    OLED_write(font_regular[chr][s], DAT);
  }
}


void OLED_print_string(unsigned char x_pos, unsigned char y_pos, char *ch)
{
  do
  {
    OLED_print_char(x_pos, y_pos, *ch++);
    x_pos += 0x06;
  }while((*ch >= 0x20) && (*ch <= 0x7F) && (*ch != '\n'));
}


void OLED_print_chr(unsigned char x_pos, unsigned char y_pos, signed int value)
{
   char ch[5] = {0x20, 0x20, 0x20, 0x20, '\n'};

  if(value < 0)
  {
    ch[0] = 0x2D;
    value = -value;
  }
  else
  {
    ch[0] = 0x20;
  }

  if((value > 99) && (value <= 999))
  {
     ch[1] = ((value / 100) + 0x30);
     ch[2] = (((value % 100) / 10) + 0x30);
     ch[3] = ((value % 10) + 0x30);
  }
  else if((value > 9) && (value <= 99))
  {
     ch[1] = ((value / 10) + 0x30);
     ch[2] = ((value % 10) + 0x30);
     ch[3] = 0x20;
  }
  else if((value >= 0) && (value <= 9))
  {
     ch[1] = ((value % 10) + 0x30);
     ch[2] = 0x20;
     ch[3] = 0x20;
  }

  OLED_print_string(x_pos, y_pos, ch);
}


void OLED_print_int(unsigned char x_pos, unsigned char y_pos, signed long value)
{
   char ch[7] = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, '\n'};

  if(value < 0)
  {
    ch[0] = 0x2D;
    value = -value;
  }
  else
  {
    ch[0] = 0x20;
  }

  if(value > 9999)
  {
    ch[1] = ((value / 10000) + 0x30); 
    ch[2] = (((value % 10000) / 1000) + 0x30); 
    ch[3] = (((value % 1000) / 100) + 0x30); 
    ch[4] = (((value % 100) / 10) + 0x30); 
    ch[5] = ((value % 10) + 0x30);
  }

  else if((value > 999) && (value <= 9999))
  {
    ch[1] = ((value / 1000) + 0x30); 
    ch[2] = (((value % 1000) / 100) + 0x30); 
    ch[3] = (((value % 100) / 10) + 0x30); 
    ch[4] = ((value % 10) + 0x30);
    ch[5] = 0x20;
  }
  else if((value > 99) && (value <= 999))
  {
    ch[1] = ((value / 100) + 0x30); 
    ch[2] = (((value % 100) / 10) + 0x30); 
    ch[3] = ((value % 10) + 0x30);
    ch[4] = 0x20;
    ch[5] = 0x20;
  }
  else if((value > 9) && (value <= 99))
  {
    ch[1] = ((value / 10) + 0x30); 
    ch[2] = ((value % 10) + 0x30);
    ch[3] = 0x20;
    ch[4] = 0x20;
    ch[5] = 0x20;
  }
  else
  {
    ch[1] = ((value % 10) + 0x30);
    ch[2] = 0x20;
    ch[3] = 0x20;
    ch[4] = 0x20;
    ch[5] = 0x20;
  }

  OLED_print_string(x_pos, y_pos, ch);
}


void OLED_print_decimal(unsigned char x_pos, unsigned char y_pos, unsigned int value, unsigned char points)
{
   char ch[6] = {0x2E, 0x20, 0x20, 0x20, 0x20, '\n'};

  ch[1] = ((value / 1000) + 0x30);

  if(points > 1)
  {
    ch[2] = (((value % 1000) / 100) + 0x30);

    if(points > 2)
    {
      ch[3] = (((value % 100) / 10) + 0x30);

      if(points > 3)
      {
        ch[4] = ((value % 10) + 0x30);
      }
    }
  }

  OLED_print_string(x_pos, y_pos, ch);
}


void OLED_print_float(unsigned char x_pos, unsigned char y_pos, float value, unsigned char points)
{
  signed long tmp = 0;

  tmp = value;
  OLED_print_int(x_pos, y_pos, tmp);
  tmp = ((value - tmp) * 10000);

  if(tmp < 0)
  {
    tmp = -tmp;
  }

  if((value >= 10000) && (value < 100000))
  {
    OLED_print_decimal((x_pos + 36), y_pos, tmp, points);
  }
  else if((value >= 1000) && (value < 10000))
  {
    OLED_print_decimal((x_pos + 30), y_pos, tmp, points);
  }
  else if((value >= 100) && (value < 1000))
  {
    OLED_print_decimal((x_pos + 24), y_pos, tmp, points);
  }
  else if((value >= 10) && (value < 100))
  {
    OLED_print_decimal((x_pos + 18), y_pos, tmp, points);
  }
  else if(value < 10)
  {
    OLED_print_decimal((x_pos + 12), y_pos, tmp, points);

    if(value < 0)
    {
        OLED_print_char(x_pos, y_pos, 0x2D);
    }
    else
    {
        OLED_print_char(x_pos, y_pos, 0x20);
    }
  }
}


void Draw_Pixel(unsigned char x_pos, unsigned char y_pos, unsigned char colour)
{
    unsigned char value = 0x00;
    unsigned char page = 0x00;
    unsigned char bit_pos = 0x00;

    page = (y_pos / y_max);
    bit_pos = (y_pos - (page * y_max));
    value = buffer[((page * x_max) + x_pos)];

    if((colour & YES) != NO)
    {
        value |= (1 << bit_pos);
    }
    else
    {
        value &= (~(1 << bit_pos));
    }

    buffer[((page * x_max) + x_pos)] = value;
    OLED_gotoxy(x_pos, page);
    OLED_write(value, DAT);
}


void Draw_Line(signed int x1, signed int y1, signed int x2, signed int y2, unsigned char colour)
{
    signed int dx = 0x0000;
    signed int dy = 0x0000;
    signed int stepx = 0x0000;
    signed int stepy = 0x0000;
    signed int fraction = 0x0000;

    dy = (y2 - y1);
    dx = (x2 - x1);

    if (dy < 0)
    {
        dy = -dy;
        stepy = -1;
    }
    else
    {
        stepy = 1;
    }

    if (dx < 0)
    {
        dx = -dx;
        stepx = -1;
    }
    else
    {
        stepx = 1;
    }

    dx <<= 1;
    dy <<= 1;

    Draw_Pixel(x1, y1, colour);

    if(dx > dy)
    {
        fraction = (dy - (dx >> 1));
        while (x1 != x2)
        {
            if(fraction >= 0)
            {
                y1 += stepy;
                fraction -= dx;
            }

            x1 += stepx;
            fraction += dy;

            Draw_Pixel(x1, y1, colour);
        }
    }
    else
    {
        fraction = (dx - (dy >> 1));
        while (y1 != y2)
        {
            if (fraction >= 0)
            {
                x1 += stepx;
                fraction -= dy;
            }

            y1 += stepy;
            fraction += dx;

            Draw_Pixel(x1, y1, colour);
        }
    }
}


void Draw_Rectangle(signed int x1, signed int y1, signed int x2, signed int y2, unsigned char fill, unsigned char colour, unsigned char type)
{
     unsigned short i = 0x00;
     unsigned short xmin = 0x00;
     unsigned short xmax = 0x00;
     unsigned short ymin = 0x00;
     unsigned short ymax = 0x00;

     if(fill != NO)
     {
        if(x1 < x2)
        {
           xmin = x1;
           xmax = x2;
        }
        else
        {
           xmin = x2;
           xmax = x1;
        }

        if(y1 < y2)
        {
           ymin = y1;
           ymax = y2;
        }
        else
        {
           ymin = y2;
           ymax = y1;
        }

        for(; xmin <= xmax; ++xmin)
        {
           for(i = ymin; i <= ymax; ++i)
           {
               Draw_Pixel(xmin, i, colour);
           }
         }
     }

     else
     {
        Draw_Line(x1, y1, x2, y1, colour);
        Draw_Line(x1, y2, x2, y2, colour);
        Draw_Line(x1, y1, x1, y2, colour);
        Draw_Line(x2, y1, x2, y2, colour);
     }

     if(type != SQUARE)
     {
         Draw_Pixel(x1, y1, ~colour);
         Draw_Pixel(x1, y2, ~colour);
         Draw_Pixel(x2, y1, ~colour);
         Draw_Pixel(x2, y2, ~colour);
     }
}


void Draw_Circle(signed int xc, signed int yc, signed int radius, unsigned char fill, unsigned char colour)
{
   signed int a = 0x0000;
   signed int b = 0x0000;
   signed int P = 0x0000;

   b = radius;
   P = (1 - b);

   do
   {
        if(fill != NO)
        {
           Draw_Line((xc - a), (yc + b), (xc + a), (yc + b), colour);
           Draw_Line((xc - a), (yc - b), (xc + a), (yc - b), colour);
           Draw_Line((xc - b), (yc + a), (xc + b), (yc + a), colour);
           Draw_Line((xc - b), (yc - a), (xc + b), (yc - a), colour);
        }
        else
        {
           Draw_Pixel((xc + a), (yc + b), colour);
           Draw_Pixel((xc + b), (yc + a), colour);
           Draw_Pixel((xc - a), (yc + b), colour);
           Draw_Pixel((xc - b), (yc + a), colour);
           Draw_Pixel((xc + b), (yc - a), colour);
           Draw_Pixel((xc + a), (yc - b), colour);
           Draw_Pixel((xc - a), (yc - b), colour);
           Draw_Pixel((xc - b), (yc - a), colour);
        }

        if(P < 0)
        {
           P += (3 + (2 * a++));
        }
        else
        {
           P += (5 + (2 * ((a++) - (b--))));
        }
    }while(a <= b);
}

 

main.c

#include "STM8S.h"
#include "SSD1306.h"


unsigned char buffer[buffer_size];


void setup_clock(void);
void setup_GPIOs(void);


void main(void)
{
     unsigned char p = 0;

     signed int i = -9;

     float f = -10.0;

     setup_clock();
     setup_GPIOs();
     OLED_init();

     while(1)
     {
         i = -9;
         f = -10.0;

         OLED_fill(0x00);
         OLED_fill(0xFF);
         delay_ms(600);
         OLED_fill(0xAA);
         delay_ms(600);
         OLED_fill(0x55);
         delay_ms(600);

         OLED_clear_buffer();
         OLED_fill(0x00);
         OLED_print_string(36, 0, "MicroArena");
         OLED_print_string(16, 1, "fb.com/MicroArena");
         Draw_Line(0, 19, 127, 19, ON);
         Draw_Line(0, 60, 127, 60, ON);
         delay_ms(900);
         Draw_Line(3, 16, 3, 63, ON);
         Draw_Line(124, 16, 124, 63, ON);
         delay_ms(900);
         Draw_Rectangle(122, 58, 5, 21, OFF, ON, SQUARE);
         delay_ms(900);
         Draw_Circle(63, 40, 7, ON, ON);
         delay_ms(2000);

         OLED_fill(0x00);
         OLED_clear_buffer();
         OLED_print_string(36, 0, "SShahyriar");
         Draw_Rectangle(27, 21, 100, 58, ON, ON, ROUND);
         delay_ms(900);
         Draw_Circle(63, 40, 9, ON, OFF);
         delay_ms(2000);

         OLED_fill(0x00);
         OLED_clear_buffer();
         for(p = 0; p < 254; p++)
         {
             f += 0.1;
             i += 1;

             OLED_print_float(42, 2, f, 1);
             OLED_print_int(42, 3, i);
             OLED_print_chr(42, 4, p);

             delay_ms(99);
         }
     };
}


void setup_clock(void)
{
       CLK_DeInit();

       CLK_HSECmd(ENABLE);
       while(CLK_GetFlagStatus(CLK_FLAG_HSERDY) == FALSE);

       CLK_LSICmd(DISABLE);

       CLK_HSICmd(ENABLE);
       while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);

       CLK_ClockSwitchCmd(ENABLE);
       CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);
       CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);

       CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE,
       DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);

       CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART2, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER3, DISABLE);
       CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE);
}


void setup_GPIOs(void)
{
       GPIO_DeInit(I2C_PORT);
}

 

Explanation

Explaining the working of the OLED display is beyond the scope of this article and so I will rather explain the useful functions of the OLED display library.

To use the OLED display library, you need to include the font library and initialize the OLED display in the main function.

OLED_init();

As said earlier, SSD1306 supports both I2C and SPI communication methods. Here I2C-based method is used and so we need to initialize I2C GPIOs and I2C peripheral clock.

CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);

The following functions are for general printing:

/*
Fills the whole screen with the designated pattern.
*/
void OLED_fill(unsigned char bmp_data);

 

/*
Prints a bitmap on the whole screen. Pixel sets whether or not to invert the pixel states.
*/

 

void OLED_print_Image(const unsigned char *bmp, unsigned char pixel);

 

/*
Clears the entire screen.
*/

 

void OLED_clear_screen(void);

 

/*
Clears the data buffer that holds pixel data.
*/

 

void OLED_clear_buffer(void);

 



 

/*
Draws a bitmap in the area defined by points (xb, yb) and (xe, ye).
*/

 

void OLED_draw_bitmap(unsigned char xb, unsigned char yb, unsigned char xe, unsigned char ye, unsigned char *bmp_img);

The following functions are used printing texts and numbers:

/*
Prints a single character at position (x_pos, y_pos).
*/
 
void OLED_print_char(unsigned char x_pos, unsigned char y_pos, unsigned char ch);
 
/*
Prints a string of characters at position (x_pos, y_pos).
*/
 
void OLED_print_string(unsigned char x_pos, unsigned char y_pos, unsigned char *ch);
 
/*
Prints a character type variable at position (x_pos, y_pos).
*/
 
void OLED_print_chr(unsigned char x_pos, unsigned char y_pos, signed int value);

 

/*
Prints a integer type variable at position (x_pos, y_pos).
*/

 


void OLED_print_int(unsigned char x_pos, unsigned char y_pos, signed long value);
 
 
/*
Prints a float type variable at position (x_pos, y_pos). Argument “points” states the number of points to print after the decimal point.
*/
 
void OLED_print_float(unsigned char x_pos, unsigned char y_pos, float value, unsigned char points);

The following functions are for projecting basic graphical objects:

/*
Draws a pixel at coordinate (x_pos, y_pos).
*/
 
void Draw_Pixel(unsigned char x_pos, unsigned char y_pos, unsigned char colour);
 
/*
Draws a line from point (x1, y1) to (x2, y2).
*/
 
void Draw_Line(signed int x1, signed int y1, signed int x2, signed int y2, unsigned char colour);

 

/*
Draws a rectangle from point (x1, y1) to (x2, y2). “Fill” states whether or not the area inside the rectangle is solid filled. “Type” states the edge type – Round/Square.
*/

 

void Draw_Rectangle(signed int x1, signed int y1, signed int x2, signed int y2, unsigned char fill, unsigned char colour, unsigned char type);

 

/*
Draws a circle with centre at point (xc, yc). “Radius” states the radius of the circle in pixels. “Fill” states whether or not to solid fill the enclosed circular area.
*/

 

void Draw_Circle(signed int xc, signed int yc, signed int radius, unsigned char fill, unsigned char colour);

 

/*
In all functions, colour states whether or not to enable the pixel(s) at the point(s). It doesn’t represent actual colour since the displays are not colour displays.
*/

Don’t forget to switch to long stack memory model.

 

 

Demo

OLED (2) OLED (1)

Continue Reading ...

Related Posts

25 comments

  • Hey; thanks a lot for your prefect article, could you send me please the delay libraries I haven’t got the right version of them, I have an error about “delay_cycle()”.

    • STM8S_delay.h


      #include "stm8s.h"

      #define F_CPU 16000000UL
      #define dly_const (F_CPU / 16000000.0F)

      void delay_us(unsigned int value);
      void delay_ms(unsigned int value);

      STM8S_delay.c


      #include "stm8s_delay.h"

      void delay_us(unsigned int value)
      {
      register unsigned int loops = (dly_const * value) ;

      while(loops)
      {
      _asm ("nop");
      loops--;
      };
      }

      void delay_ms(unsigned int value)
      {
      while(value)
      {
      delay_us(1000);
      value--;
      };
      }

      I didn’t use delay cycle in my library…. Are you using some other compiler other than Cosmic + STVD?

  • Really outstanding library! Thanks for helping out. I am using the STM8AF5288 so made some changes and worked like a charm. but the issue i am facing right now is the font size. is there any available font library that could be replaced to get bigger fonts? and If possible can you explain how the font is being created on the ssd1306, I mean the way the pixels are being drawn using the hex code (in the font.h file).
    Thanks in advance.

  • Really outstanding library! Thanks for helping out. I am using the STM8AF5288 so made some changes and worked like a charm. but the issue i am facing right now is the font size. is there any available font library that could be replaced to get bigger fonts ? and If possible can you explain how the font is being created on the ssd1306, I mean the way the pixels are being drawn using the hex code (in the font.h file).
    Thanks in advance.

    • There are several OLED libraries available in the internet with big fonts but I’m happy with this font size to make maximum use of the display…. Thus I didn’t go for development of libraries with big fonts….

      • thanks for the quick reply, But the thing is that i am facing a issue with that of the draw bitmap function.
        i.e.
        void OLED_draw_bitmap(unsigned char xb, unsigned char yb, unsigned char xe, unsigned char ye, unsigned char *bmp_img)

        {

        unsigned int s = 0x0000;

        unsigned char x_pos = 0x00;

        unsigned char y_pos = 0x00;

        for(y_pos = yb; y_pos <= ye; y_pos++)

        {

        OLED_gotoxy(xb, y_pos);

        for(x_pos = xb; x_pos < xe; x_pos++)

        {

        OLED_write(bmp_img[s++], DAT);

        }

        }

        }

        and i am calling it by the following way:
        OLED_draw_bitmap(0,0,128,64,(unsigned char *)&image_data_LesInv);

        and my bitmap file goes like this:
        static const uint8_t image_data_LesInv[128][64] = {
        // 'untitled', 128x64px
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0x7f, 0x3f, 0x3f, 0x3f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
        0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
        0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
        0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x3f, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0xf8,
        0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
        0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x07,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x0f, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x80, 0xe0,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
        0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
        0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xfe, 0xfc, 0xfc, 0xfc, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
        0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
        0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
        0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfc, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
        };

        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        but the issue is that my image does gets generated but it gets back to blank screen within a 500ms or so.
        can you please help with the same.

        • void OLED_draw_bitmap(unsigned char xb, unsigned char yb, unsigned char xe, unsigned char ye, unsigned char *bmp_img)
          {
          unsigned int s = 0x0000;
          unsigned char x_pos = 0x00;
          unsigned char y_pos = 0x00;

          for(y_pos = yb; y_pos <= ye; y_pos++)
          {
          OLED_gotoxy(xb, y_pos);
          for(x_pos = xb; x_pos < xe; x_pos++)
          {
          OLED_write(bmp_img[s++], DAT);
          }
          }
          }

          This was the original code but yours seems to be modified in the for loops…. Please recheck unless it is intentional….

          • both the loops are the same. I did not make any changes in the original code but the bitmap image seems to get printed on the screen but it gets instantly blank within 20ms.
            can you help me for the same.
            Thanks in advance.

          • Could you send me the whole code? I think there is an overflow somewhere….

  • Hello,
    How can i change the font size so i can support for example [92][12] ? Saw some libraries on the net but i am not sure if they are compatible with this code… or am i doing something wrong ? I tried manipulating the current one with some cycles within ” OLED_print_char ” also chaning 0x06 to 0x0C with a font library also tried creating fonts but i did not get the expected result. Can you give me some advice please ?
    Thank you for your time!

    • The coordinates of the OLED displays are mapped as multiples of 8-bits or 8 dots in both x and y directions. So just by changing x-coordinate values won’t result in larger fonts…. You must also take care of the y-coordinate too…. Take the example of the bitmap function:

      void OLED_draw_bitmap(unsigned char xb, unsigned char yb, unsigned char xe, unsigned char ye, unsigned char *bmp_img)
      {
      unsigned int s = 0x0000;
      unsigned char x_pos = 0x00;
      unsigned char y_pos = 0x00;

      for(y_pos = yb; y_pos <= ye; y_pos++)
      {
      OLED_gotoxy(xb, y_pos);
      for(x_pos = xb; x_pos < xe; x_pos++)
      {
      OLED_write(bmp_img[s], DAT);
      s++;
      }
      }
      }

      It takes care of the y-coordinate part once the x-coordinate points are filled up….

  • Hi great tutorial!
    Can you post code for interfacing external eeprom using i2c for stm8s003f3??

  • Pingback: .NET i jiné ...

  • Pingback: STM8 Microcontrollers – gStore

  • Outstanding bro. Carry on. Wish your good luck.

Leave a Reply

Your email address will not be published. Required fields are marked *