STM8 Microcontrollers – the Final Chapters

Hardware

This post is the sequel of the posts on STM8 microcontrollers here and here.

Hardware

Software I2C – DS1307

Software-based I2C is not a big requirement in case of STM8s because STM8 chips have hardware I2C blocks. However, for some reason if we are unable to use hardware I2C blocks, we can implement software-based I2C by bit-banging ordinary GPIOs. I2C protocol is itself slow compared to SPI and other protocols and so implementing software-based I2C will not significantly affect communication speed and overall throughput in most applications. However, extra coding is required and this in turn adds some coding and resource overheads.

Hardware Connection

sw_i2c

Code Example

SW_I2C.h

#include "STM8S.h"


#define SW_I2C_port              GPIOD

#define SDA_pin                  GPIO_PIN_6
#define SCL_pin                  GPIO_PIN_7

#define SW_I2C_OUT()             do{GPIO_DeInit(SW_I2C_port); GPIO_Init(SW_I2C_port, SDA_pin, GPIO_MODE_OUT_PP_LOW_FAST); GPIO_Init(SW_I2C_port, SCL_pin, GPIO_MODE_OUT_PP_LOW_FAST);}while(0)

#define SW_I2C_IN()              do{GPIO_DeInit(SW_I2C_port); GPIO_Init(SW_I2C_port, SDA_pin, GPIO_MODE_IN_FL_NO_IT); GPIO_Init(SW_I2C_port, SCL_pin, GPIO_MODE_OUT_PP_LOW_FAST);}while(0)

#define SDA_HIGH()               GPIO_WriteHigh(SW_I2C_port, SDA_pin)
#define SDA_LOW()                GPIO_WriteLow(SW_I2C_port, SDA_pin)
#define SCL_HIGH()               GPIO_WriteHigh(SW_I2C_port, SCL_pin)
#define SCL_LOW()                GPIO_WriteLow(SW_I2C_port, SCL_pin)

#define SDA_IN()                 GPIO_ReadInputPin(SW_I2C_port, SDA_pin)

#define I2C_ACK                  0xFF
#define I2C_NACK                 0x00

#define I2C_timeout              1000


void SW_I2C_init(void);
void SW_I2C_start(void);
void SW_I2C_stop(void);
unsigned char SW_I2C_read(unsigned char ack);
void SW_I2C_write(unsigned char value);
void SW_I2C_ACK_NACK(unsigned char mode);
unsigned char SW_I2C_wait_ACK(void);

 

SW_I2C.c

#include "SW_I2C.h"


void SW_I2C_init(void)
{
    SW_I2C_OUT();
    delay_ms(10);
    SDA_HIGH();
    SCL_HIGH();
}


void SW_I2C_start(void)
{
    SW_I2C_OUT();
    SDA_HIGH();
    SCL_HIGH();
    delay_us(40);
    SDA_LOW();
    delay_us(40);
    SCL_LOW();
}


void SW_I2C_stop(void)
{
    SW_I2C_OUT();
    SDA_LOW();
    SCL_LOW();
    delay_us(40);
    SDA_HIGH();
    SCL_HIGH();
    delay_us(40);
}


unsigned char SW_I2C_read(unsigned char ack)
{
    unsigned char i = 0x08;
    unsigned char j = 0x00;

    SW_I2C_IN();

    while(i > 0x00)
    {
        SCL_LOW();
        delay_us(20);
        SCL_HIGH();
        delay_us(20);
        j <<= 1;

        if(SDA_IN() != 0x00)
        {
            j++;
        }

        delay_us(10);
        i--;
    };

    switch(ack)
    {
        case I2C_ACK:
        {
            SW_I2C_ACK_NACK(I2C_ACK);;
            break;
        }
        default:
        {
            SW_I2C_ACK_NACK(I2C_NACK);;
            break;
        }
    }

    return j;
}


void SW_I2C_write(unsigned char value)
{
    unsigned char i = 0x08;

    SW_I2C_OUT();
    SCL_LOW();

    while(i > 0x00)
    {

        if(((value & 0x80) >> 0x07) != 0x00)
        {
            SDA_HIGH();
        }
        else
        {
            SDA_LOW();
        }


        value <<= 1;
        delay_us(20);
        SCL_HIGH();
        delay_us(20);
        SCL_LOW();
        delay_us(20);
        i--;
    };
}


void SW_I2C_ACK_NACK(unsigned char mode)
{
    SCL_LOW();
    SW_I2C_OUT();

    switch(mode)
    {
        case I2C_ACK:
        {
            SDA_LOW();
            break;
        }
        default:
        {
            SDA_HIGH();
            break;
        }
    }

    delay_us(20);
    SCL_HIGH();
    delay_us(20);
    SCL_LOW();
}


unsigned char SW_I2C_wait_ACK(void)
{
    signed int timeout = 0x0000;

    SW_I2C_IN();

    SDA_HIGH();
    delay_us(10);
    SCL_HIGH();
    delay_us(10);

    while(SDA_IN() != 0x00)
    {
        timeout++;

        if(timeout > I2C_timeout)
        {
            SW_I2C_stop();
            return 1;
        }
    };

    SCL_LOW();

    return 0x00;
}

 

DS1307.h

#include "SW_I2C.h"


#define sec_reg                0x00
#define min_reg                0x01
#define hr_reg                 0x02
#define day_reg                0x03
#define date_reg               0x04
#define month_reg              0x05
#define year_reg               0x06
#define control_reg            0x07

#define DS1307_addr            0xD0
#define DS1307_WR              DS1307_addr
#define DS1307_RD              0xD1


void DS1307_init(void);
unsigned char DS1307_read(unsigned char address);
void DS1307_write(unsigned char address, unsigned char value);
unsigned char bcd_to_decimal(unsigned char value);
unsigned char decimal_to_bcd(unsigned char value);
void get_time(void);
void set_time(void);

 

DS1307.c

#include "DS1307.h"


extern struct
{
   unsigned char s;
   unsigned char m;
   unsigned char h;
   unsigned char dy;
   unsigned char dt;
   unsigned char mt;
   unsigned char yr;
}time;


void DS1307_init(void)
{
    SW_I2C_init();
    DS1307_write(control_reg, 0x00);
}


unsigned char DS1307_read(unsigned char address)
{
    unsigned char value = 0x00;

    SW_I2C_start();
    SW_I2C_write(DS1307_WR);
    SW_I2C_write(address);

    SW_I2C_start();
    SW_I2C_write(DS1307_RD);
    value = SW_I2C_read(I2C_NACK);
    SW_I2C_stop();

    return value;
}


void DS1307_write(unsigned char address, unsigned char value)
{
    SW_I2C_start();
    SW_I2C_write(DS1307_WR);
    SW_I2C_write(address);
    SW_I2C_write(value);
    SW_I2C_stop();
}


unsigned char bcd_to_decimal(unsigned char value)
{
    return ((value & 0x0F) + (((value & 0xF0) >> 0x04) * 0x0A));
}


unsigned char decimal_to_bcd(unsigned char value)
{
    return (((value / 0x0A) << 0x04) & 0xF0) | ((value % 0x0A) & 0x0F);
}


void get_time(void)
{
       time.s = DS1307_read(sec_reg);
       time.s = bcd_to_decimal(time.s);

       time.m = DS1307_read(min_reg);
       time.m = bcd_to_decimal(time.m);

       time.h = DS1307_read(hr_reg);
       time.h = bcd_to_decimal(time.h);

       time.dy = DS1307_read(day_reg);
       time.dy = bcd_to_decimal(time.dy);

       time.dt = DS1307_read(date_reg);
       time.dt = bcd_to_decimal(time.dt);

       time.mt = DS1307_read(month_reg);
       time.mt = bcd_to_decimal(time.mt);

       time.yr = DS1307_read(year_reg);
       time.yr = bcd_to_decimal(time.yr);
}


void set_time(void)
{
       time.s = decimal_to_bcd(time.s);
       DS1307_write(sec_reg, time.s);

       time.m = decimal_to_bcd(time.m);
       DS1307_write(min_reg, time.m);

       time.h = decimal_to_bcd(time.h);
       DS1307_write(hr_reg, time.h);

       time.dy = decimal_to_bcd(time.dy);
       DS1307_write(day_reg, time.dy);

       time.dt = decimal_to_bcd(time.dt);
       DS1307_write(date_reg, time.dt);

       time.mt = decimal_to_bcd(time.mt);
       DS1307_write(month_reg, time.mt);

       time.yr = decimal_to_bcd(time.yr);
       DS1307_write(year_reg, time.yr);
}

 

main.c

#include "STM8S.h"
#include "lcd.h"
#include "SW_I2C.h"
#include "DS1307.h"


#define Button_port      GPIOB
#define Button_pin         GPIO_PIN_7


struct
{
   unsigned char s;
   unsigned char m;
   unsigned char h;
   unsigned char dy;
   unsigned char dt;
   unsigned char mt;
   unsigned char yr;
}time;

bool set = FALSE;

unsigned char menu = 0;
unsigned char data_value;


void clock_setup(void);
void GPIO_setup(void);
void show_value(unsigned char x_pos, unsigned char y_pos, unsigned char value);
void display_time(void);
void setup_time(void);
unsigned char adjust(unsigned char x_pos, unsigned char y_pos, signed char value_max, signed char value_min, signed char value);


void main(void)
{
       clock_setup();
       GPIO_setup();

       DS1307_init();

       LCD_init();
       LCD_clear_home();

       LCD_goto(0, 0);
       LCD_putstr("STM8 SW-I2C Test");

    while(1)
    {
       if((GPIO_ReadInputPin(Button_port, Button_pin) == FALSE) && (set == FALSE))
       {
              delay_ms(1000);
              if(GPIO_ReadInputPin(Button_port, Button_pin) == FALSE)
              {
                     while(GPIO_ReadInputPin(Button_port, Button_pin) == FALSE);
                     delay_ms(1000);

                     menu = 0;
                     set = TRUE;
              }
       }

       if(set)
       {
              setup_time();
       }
       else
       {
              get_time();
              display_time();
       }
    };
}


void clock_setup(void)
{
       CLK_DeInit();

       CLK_HSECmd(DISABLE);
       CLK_LSICmd(DISABLE);
       CLK_HSICmd(ENABLE);
       while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE);

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

       CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI,
       DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);

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


void GPIO_setup(void)
{
       GPIO_DeInit(GPIOB);
       GPIO_Init(Button_port, Button_pin, GPIO_MODE_IN_PU_NO_IT);
}


void show_value(unsigned char x_pos, unsigned char y_pos, unsigned char value)
{
   char ch[0x03] = {0x20, 0x20, '\0'};

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

   LCD_goto(x_pos, y_pos);
   LCD_putstr(ch);
}


void display_time(void)
{     
       show_value(4, 1, time.h);
       show_value(7, 1, time.m);
       show_value(10, 1, time.s);

       LCD_goto(6, 1);
       LCD_putchar(':');
       LCD_goto(9, 1);
       LCD_putchar(':');  
       delay_ms(100);
}


void setup_time(void)
{
       switch(menu)
       {
              case 0:
              {
                     time.h = adjust(4, 1, 23, 0, time.h);
                     break;
              }            
              case 1:
              {
                     time.m = adjust(7, 1, 59, 0, time.m);
                     break;
              }
              case 2:
              {
                     time.s = adjust(10, 1, 59, 0, time.s);
                     break;
              }
       }
}


unsigned char adjust(unsigned char x_pos, unsigned char y_pos, signed char value_max, signed char value_min, signed char value)
{
       if(GPIO_ReadInputPin(Button_port, Button_pin) == FALSE)
       {
              delay_ms(900);

              if(GPIO_ReadInputPin(Button_port, Button_pin) == FALSE)
              {
                     while(GPIO_ReadInputPin(Button_port, Button_pin) == FALSE);
                     menu++;

                     if(menu >= 3)
                     {
                           LCD_goto(3, 1);
                           LCD_putchar(' ');
                           LCD_goto(12, 1);
                           LCD_putchar(' ');  
                           set_time();
                           set = FALSE;

                           return;
                     }
              }
       }

       else
       {
              value++;

              if(value > value_max)
              {
                  value = value_min;
              }
       }

       LCD_goto(3, 1);
       LCD_putchar('<');
       LCD_goto(12, 1);
       LCD_putchar('>');  

       LCD_goto(x_pos, y_pos);
       LCD_putstr("  ");
       delay_ms(90);

       show_value(x_pos, y_pos, value);
       delay_ms(90);

       return value;
}

 

Explanation

SW_I2C.h and SW_I2C.c files translate the entire I2C communication operations with the manipulation of ordinary GPIOs. Any GPIO pin pair can be used for software I2C. Just define the software I2C port, and the serial data (SDA) and serial clock (SDA) pins:

#define SW_I2C_port              GPIOD

 

#define SDA_pin                  GPIO_PIN_6
#define SCL_pin                  GPIO_PIN_7

The functions in these files are self-explanatory and so I’m not going to explain them here.

The rest of the code is about using the software I2C library with DS1307 real time clock (RTC) chip to make a real time clock.

 

Demo

SW-I2C

Continue Reading ...

Related Posts

38 comments

  • I am trying to use i2c LCD but I am stuck in one place.

    The code is stuck in an endless loop in below function
    ////////////////
    void PCF8574_write(unsigned char data_byte)
    {
    I2C_GenerateSTART(ENABLE);
    while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

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

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

    I2C_GenerateSTOP(ENABLE);
    }
    ////////////////

    the code is stuck in below line
    while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    PCF8574_address is 0x4E

  • Hi sir, I use stm8s003f3p6, I want to run oled display, but I have an issue about stack memory. I’ve switched it to long stack memory but it doesn’t change.what should I do? I think this type of stm8s has’nt got as amount as stack memory I need.

    • Switch to chips of higher memory capacities…. This chip can’t be used to drive an OLED screen….

      • Hi shawon; I want to run OLED display but I have an error as follow: “bass size overflow(768)” I try with all type of stm8s microes but it’s not changed… I switched memory model to long stack memory. What should I do?

    • Your comment is awaiting moderation.

      I am trying to use i2c LCD but I am stuck in one place.

      The code is stuck in an endless loop in below function
      ////////////////
      void PCF8574_write(unsigned char data_byte)
      {
      I2C_GenerateSTART(ENABLE);
      while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

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

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

      I2C_GenerateSTOP(ENABLE);
      }
      ////////////////

      the code is stuck in below line
      while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

      PCF8574_address is 0x4E

      • What about pull-ups on SCL and SDA lines? Are you sure that your PCF8574’s I2C address is 0x4E?

        • I am trying without I2C module but still, nothing is showing on display.

        • I have only followed example code
          In tutorial it is not showing for pull up SDA and sck.
          .
          The address of is 0x27 I have tried with this also.

          I have also tried without i2c but that’s code is also not working .

          • Hmm first thing I guess is either the LCD is broken or you are trying with wrong I2C address… Be sure of the chip embedded in the I2C-LCD module…. Some come shipped with PCF8574 while some are shipped with PCF8574A…. These have different I2C addresses…. Secondly, in the tutorial pull-up is shown in the I2C-LCD module’s schematic and by the nature of I2C communication pull-ups are must…. It should be there no matter if specified or not….

  • 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?

      • Look up at “one_wire.c” you used “delay_cycle(1)” three times. When I compile it I get this error: “missing prototype” .I use cosmic + stvd such as you.

      • Shawon I’m sorry to bother you, but I can’t run ds18b20 with this code. Lcd shows meaningless character with this clock cpu you were configured, I configured CPUDIV4 and it worked but it only showed “4095.9” I’m sure about hardware … can u help me? What more I can do to fix it??

        • Have you use pulled up the data pin? Did you try with my code? With my code does it work or not?

          • I’ve just coppied your code , at first complier didn’t find delay_cycle funcion then I replaced it with a while loop such as you said, after that I had to reduce the cpu clock cause LCD didn’t working properly(according to you most LCDs have a maximum working frequency of 250 khz.) at last I gave the wrong temprature from DS. I’ve pulled up the data line with 10 k res.

          • I didn’t mean that you copy my code and retry…. I meant that you check with my hardware connections and my finizalied debugger file “ow_ds18b20.s19” from the debug folder…. If there is still any issue then it is likely a hardware issue or else you are doing something wrong….

  • 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 *