cancel
Showing results for 
Search instead for 
Did you mean: 

Help with RTC on Nucleo-F401 to display time on SSD1306 LCD

adityapruthi01
Associate II

Hello all, 
I'm new to STM32, I have been given a project to display the time and date on either an 16x2 lcd or an oled display using the internal RTC of my board. 
I have the STM32 Nucleo f401re.
Can somebody help me?
Thanks and Regards

16 REPLIES 16

Hi @mÆŽALLEm
Good Day!
What do you want me to do with these 4 links? 
I have already tried to run this github code, with these 4 files included but it does not work.
Perhaps can you guide me with which pins should i connect my oled to my board?
Thanks.

Hello,


@adityapruthi01 wrote:

Hi @mÆŽALLEm
Good Day!
What do you want me to do with these 4 links? 


You need to start a new project and add these files as drivers for your new project and test only LCD as your issue seems to be related to the LCD itself.

 


@adityapruthi01 wrote:

Perhaps can you guide me with which pins should i connect my oled to my board?
Thanks.


The pins connections are described in the header of the ssd1306.c file:

SofLit_0-1730891170296.png

Don't forget to add pull-up resistors on SCL and SDA lines for I2C bus.

Otherwise as said by @Andrew Neil you need to start with very simple projects to be familiar with ST environment and its MCUs.

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.


The pins connections are described in the header of the ssd1306.c file:

SofLit_0-1730891170296.png

Don't forget to add pull-up resistors on SCL and SDA lines for I2C bus.

Otherwise as said by @Andrew Neil you need to start with very simple projects to be familiar with ST environment and its MCUs.

 


You can also confirm the pin connection for I2C in https://github.com/guiguitz/RTC-OLED-Application/blob/main/NUCLEO-F401RE-RTC-OLED-Application/Src/stm32f4xx_hal_msp.c :

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hi2c->Instance==I2C1) { /* USER CODE BEGIN I2C1_MspInit 0 */ /* USER CODE END I2C1_MspInit 0 */ __HAL_RCC_GPIOB_CLK_ENABLE(); /**I2C1 GPIO Configuration PB8 ------> I2C1_SCL PB9 ------> I2C1_SDA */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Peripheral clock enable */ __HAL_RCC_I2C1_CLK_ENABLE(); /* USER CODE BEGIN I2C1_MspInit 1 */ /* USER CODE END I2C1_MspInit 1 */ } }

->

/**I2C1 GPIO Configuration PB8 ------> I2C1_SCL PB9 ------> I2C1_SDA */

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Understand that this is *your* project, perhaps work with and seek direction from your supervisor, peers or those that assigned this too you.

There are only 4-wires, and only 2 signal wires.

Make sure there's pull-up's on the SDA/SCL pins

It shouldn't be this hard to build for your board, and I2C / Pin combo that's unique to your implementation.

>>I have already tried to run this github code, with these 4 files included but it does not work.

Try harder..

Do some debugging, get a scope or logic analyzer on the signals. Understand what IS happening and WHY its "Not Working"

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
adityapruthi01
Associate II
Hello all, (EDITED)
With some debugging i've got the code to work without any errors, everything is working fine on the OLED Display,the only problem is if I am coommenting out this line:

 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM3) { // Your 1-second interrupt handling code here Print_Date_Oled(); Print_Time_Oled(); } }​

 

which is used to display the time and date on the OLED, the Terra Term does not work and there is no feedback when pressing any keys while trying to change the date and time.

adityapruthi01_0-1730986720739.png

The above is showing like this when trying to press any key on the num pad.

But actually it has to be like this.

adityapruthi01_1-1730986817074.png

The above happens when I commenting out the Print date and time function.

So either I am able to use the RTC functionality or miss displaying it on the OLED, or I am able to Display on the OLED missing RTC functionality.
The video for the same can be found here https://www.youtube.com/watch?v=Nm-16YhCYl8&t=1438s
Github for the same original project is located here: https://github.com/PRTechTalk/STM32/tree/main/G071_LCD_RTC.

Can you please check.
Thanks and Regards

The whole code that I am dumping to my STM Nucleo Board can be found below:

 

#include "ssd1306.h" #include <math.h> #include <stdlib.h> #include <string.h> // For memcpy #if defined(SSD1306_USE_I2C) void ssd1306_Reset(void) { /* for I2C - do nothing */ } // Send a byte to the command register void ssd1306_WriteCommand(uint8_t byte) { HAL_I2C_Mem_Write(&SSD1306_I2C_PORT, SSD1306_I2C_ADDR, 0x00, 1, &byte, 1, HAL_MAX_DELAY); } // Send data void ssd1306_WriteData(uint8_t* buffer, size_t buff_size) { HAL_I2C_Mem_Write(&SSD1306_I2C_PORT, SSD1306_I2C_ADDR, 0x40, 1, buffer, buff_size, HAL_MAX_DELAY); } #elif defined(SSD1306_USE_SPI) void ssd1306_Reset(void) { // CS = High (not selected) HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_SET); // Reset the OLED HAL_GPIO_WritePin(SSD1306_Reset_Port, SSD1306_Reset_Pin, GPIO_PIN_RESET); HAL_Delay(10); HAL_GPIO_WritePin(SSD1306_Reset_Port, SSD1306_Reset_Pin, GPIO_PIN_SET); HAL_Delay(10); } // Send a byte to the command register void ssd1306_WriteCommand(uint8_t byte) { HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_RESET); // select OLED HAL_GPIO_WritePin(SSD1306_DC_Port, SSD1306_DC_Pin, GPIO_PIN_RESET); // command HAL_SPI_Transmit(&SSD1306_SPI_PORT, (uint8_t *) &byte, 1, HAL_MAX_DELAY); HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_SET); // un-select OLED } // Send data void ssd1306_WriteData(uint8_t* buffer, size_t buff_size) { HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_RESET); // select OLED HAL_GPIO_WritePin(SSD1306_DC_Port, SSD1306_DC_Pin, GPIO_PIN_SET); // data HAL_SPI_Transmit(&SSD1306_SPI_PORT, buffer, buff_size, HAL_MAX_DELAY); HAL_GPIO_WritePin(SSD1306_CS_Port, SSD1306_CS_Pin, GPIO_PIN_SET); // un-select OLED } #else #error "You should define SSD1306_USE_SPI or SSD1306_USE_I2C macro" #endif // Screenbuffer static uint8_t SSD1306_Buffer[SSD1306_BUFFER_SIZE]; // Screen object static SSD1306_t SSD1306; /* Fills the Screenbuffer with values from a given buffer of a fixed length */ SSD1306_Error_t ssd1306_FillBuffer(uint8_t* buf, uint32_t len) { SSD1306_Error_t ret = SSD1306_ERR; if (len <= SSD1306_BUFFER_SIZE) { memcpy(SSD1306_Buffer,buf,len); ret = SSD1306_OK; } return ret; } /* Initialize the oled screen */ void ssd1306_Init(void) { // Reset OLED ssd1306_Reset(); // Wait for the screen to boot HAL_Delay(100); // Init OLED ssd1306_SetDisplayOn(0); //display off ssd1306_WriteCommand(0x20); //Set Memory Addressing Mode ssd1306_WriteCommand(0x00); // 00b,Horizontal Addressing Mode; 01b,Vertical Addressing Mode; // 10b,Page Addressing Mode (RESET); 11b,Invalid ssd1306_WriteCommand(0xB0); //Set Page Start Address for Page Addressing Mode,0-7 #ifdef SSD1306_MIRROR_VERT ssd1306_WriteCommand(0xC0); // Mirror vertically #else ssd1306_WriteCommand(0xC8); //Set COM Output Scan Direction #endif ssd1306_WriteCommand(0x00); //---set low column address ssd1306_WriteCommand(0x10); //---set high column address ssd1306_WriteCommand(0x40); //--set start line address - CHECK ssd1306_SetContrast(0xFF); #ifdef SSD1306_MIRROR_HORIZ ssd1306_WriteCommand(0xA0); // Mirror horizontally #else ssd1306_WriteCommand(0xA1); //--set segment re-map 0 to 127 - CHECK #endif #ifdef SSD1306_INVERSE_COLOR ssd1306_WriteCommand(0xA7); //--set inverse color #else ssd1306_WriteCommand(0xA6); //--set normal color #endif // Set multiplex ratio. #if (SSD1306_HEIGHT == 128) // Found in the Luma Python lib for SH1106. ssd1306_WriteCommand(0xFF); #else ssd1306_WriteCommand(0xA8); //--set multiplex ratio(1 to 64) - CHECK #endif #if (SSD1306_HEIGHT == 32) ssd1306_WriteCommand(0x1F); // #elif (SSD1306_HEIGHT == 64) ssd1306_WriteCommand(0x3F); // #elif (SSD1306_HEIGHT == 128) ssd1306_WriteCommand(0x3F); // Seems to work for 128px high displays too. #else #error "Only 32, 64, or 128 lines of height are supported!" #endif ssd1306_WriteCommand(0xA4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content ssd1306_WriteCommand(0xD3); //-set display offset - CHECK ssd1306_WriteCommand(0x00); //-not offset ssd1306_WriteCommand(0xD5); //--set display clock divide ratio/oscillator frequency ssd1306_WriteCommand(0xF0); //--set divide ratio ssd1306_WriteCommand(0xD9); //--set pre-charge period ssd1306_WriteCommand(0x22); // ssd1306_WriteCommand(0xDA); //--set com pins hardware configuration - CHECK #if (SSD1306_HEIGHT == 32) ssd1306_WriteCommand(0x02); #elif (SSD1306_HEIGHT == 64) ssd1306_WriteCommand(0x12); #elif (SSD1306_HEIGHT == 128) ssd1306_WriteCommand(0x12); #else #error "Only 32, 64, or 128 lines of height are supported!" #endif ssd1306_WriteCommand(0xDB); //--set vcomh ssd1306_WriteCommand(0x20); //0x20,0.77xVcc ssd1306_WriteCommand(0x8D); //--set DC-DC enable ssd1306_WriteCommand(0x14); // ssd1306_SetDisplayOn(1); //--turn on SSD1306 panel // Clear screen ssd1306_Fill(Black); // Flush buffer to screen ssd1306_UpdateScreen(); // Set default values for screen object SSD1306.CurrentX = 0; SSD1306.CurrentY = 0; SSD1306.Initialized = 1; } /* Fill the whole screen with the given color */ void ssd1306_Fill(SSD1306_COLOR color) { memset(SSD1306_Buffer, (color == Black) ? 0x00 : 0xFF, sizeof(SSD1306_Buffer)); } /* Write the screenbuffer with changed to the screen */ void ssd1306_UpdateScreen(void) { // Write data to each page of RAM. Number of pages // depends on the screen height: // // * 32px == 4 pages // * 64px == 8 pages // * 128px == 16 pages for(uint8_t i = 0; i < SSD1306_HEIGHT/8; i++) { ssd1306_WriteCommand(0xB0 + i); // Set the current RAM page address. ssd1306_WriteCommand(0x00 + SSD1306_X_OFFSET_LOWER); ssd1306_WriteCommand(0x10 + SSD1306_X_OFFSET_UPPER); ssd1306_WriteData(&SSD1306_Buffer[SSD1306_WIDTH*i],SSD1306_WIDTH); } } /* * Draw one pixel in the screenbuffer * X => X Coordinate * Y => Y Coordinate * color => Pixel color */ void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color) { if(x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) { // Don't write outside the buffer return; } // Draw in the right color if(color == White) { SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] |= 1 << (y % 8); } else { SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] &= ~(1 << (y % 8)); } } /* * Draw 1 char to the screen buffer * ch => char om weg te schrijven * Font => Font waarmee we gaan schrijven * color => Black or White */ char ssd1306_WriteChar(char ch, SSD1306_Font_t Font, SSD1306_COLOR color) { uint32_t i, b, j; // Check if character is valid if (ch < 32 || ch > 126) return 0; // Check remaining space on current line if (SSD1306_WIDTH < (SSD1306.CurrentX + Font.width) || SSD1306_HEIGHT < (SSD1306.CurrentY + Font.height)) { // Not enough space on current line return 0; } // Use the font to write for(i = 0; i < Font.height; i++) { b = Font.data[(ch - 32) * Font.height + i]; for(j = 0; j < Font.width; j++) { if((b << j) & 0x8000) { ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR) color); } else { ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)!color); } } } // The current space is now taken SSD1306.CurrentX += Font.char_width ? Font.char_width[ch - 32] : Font.width; // Return written char for validation return ch; } /* Write full string to screenbuffer */ char ssd1306_WriteString(char* str, SSD1306_Font_t Font, SSD1306_COLOR color) { while (*str) { if (ssd1306_WriteChar(*str, Font, color) != *str) { // Char could not be written return *str; } str++; } // Everything ok return *str; } /* Position the cursor */ void ssd1306_SetCursor(uint8_t x, uint8_t y) { SSD1306.CurrentX = x; SSD1306.CurrentY = y; } /* Draw line by Bresenhem's algorithm */ void ssd1306_Line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) { int32_t deltaX = abs(x2 - x1); int32_t deltaY = abs(y2 - y1); int32_t signX = ((x1 < x2) ? 1 : -1); int32_t signY = ((y1 < y2) ? 1 : -1); int32_t error = deltaX - deltaY; int32_t error2; ssd1306_DrawPixel(x2, y2, color); while((x1 != x2) || (y1 != y2)) { ssd1306_DrawPixel(x1, y1, color); error2 = error * 2; if(error2 > -deltaY) { error -= deltaY; x1 += signX; } if(error2 < deltaX) { error += deltaX; y1 += signY; } } return; } /* Draw polyline */ void ssd1306_Polyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color) { uint16_t i; if(par_vertex == NULL) { return; } for(i = 1; i < par_size; i++) { ssd1306_Line(par_vertex[i - 1].x, par_vertex[i - 1].y, par_vertex[i].x, par_vertex[i].y, color); } return; } /* Convert Degrees to Radians */ static float ssd1306_DegToRad(float par_deg) { return par_deg * (3.14f / 180.0f); } /* Normalize degree to [0;360] */ static uint16_t ssd1306_NormalizeTo0_360(uint16_t par_deg) { uint16_t loc_angle; if(par_deg <= 360) { loc_angle = par_deg; } else { loc_angle = par_deg % 360; loc_angle = (loc_angle ? loc_angle : 360); } return loc_angle; } /* * DrawArc. Draw angle is beginning from 4 quart of trigonometric circle (3pi/2) * start_angle in degree * sweep in degree */ void ssd1306_DrawArc(uint8_t x, uint8_t y, uint8_t radius, uint16_t start_angle, uint16_t sweep, SSD1306_COLOR color) { static const uint8_t CIRCLE_APPROXIMATION_SEGMENTS = 36; float approx_degree; uint32_t approx_segments; uint8_t xp1,xp2; uint8_t yp1,yp2; uint32_t count; uint32_t loc_sweep; float rad; loc_sweep = ssd1306_NormalizeTo0_360(sweep); count = (ssd1306_NormalizeTo0_360(start_angle) * CIRCLE_APPROXIMATION_SEGMENTS) / 360; approx_segments = (loc_sweep * CIRCLE_APPROXIMATION_SEGMENTS) / 360; approx_degree = loc_sweep / (float)approx_segments; while(count < approx_segments) { rad = ssd1306_DegToRad(count*approx_degree); xp1 = x + (int8_t)(sinf(rad)*radius); yp1 = y + (int8_t)(cosf(rad)*radius); count++; if(count != approx_segments) { rad = ssd1306_DegToRad(count*approx_degree); } else { rad = ssd1306_DegToRad(loc_sweep); } xp2 = x + (int8_t)(sinf(rad)*radius); yp2 = y + (int8_t)(cosf(rad)*radius); ssd1306_Line(xp1,yp1,xp2,yp2,color); } return; } /* * Draw arc with radius line * Angle is beginning from 4 quart of trigonometric circle (3pi/2) * start_angle: start angle in degree * sweep: finish angle in degree */ void ssd1306_DrawArcWithRadiusLine(uint8_t x, uint8_t y, uint8_t radius, uint16_t start_angle, uint16_t sweep, SSD1306_COLOR color) { const uint32_t CIRCLE_APPROXIMATION_SEGMENTS = 36; float approx_degree; uint32_t approx_segments; uint8_t xp1; uint8_t xp2 = 0; uint8_t yp1; uint8_t yp2 = 0; uint32_t count; uint32_t loc_sweep; float rad; loc_sweep = ssd1306_NormalizeTo0_360(sweep); count = (ssd1306_NormalizeTo0_360(start_angle) * CIRCLE_APPROXIMATION_SEGMENTS) / 360; approx_segments = (loc_sweep * CIRCLE_APPROXIMATION_SEGMENTS) / 360; approx_degree = loc_sweep / (float)approx_segments; rad = ssd1306_DegToRad(count*approx_degree); uint8_t first_point_x = x + (int8_t)(sinf(rad)*radius); uint8_t first_point_y = y + (int8_t)(cosf(rad)*radius); while (count < approx_segments) { rad = ssd1306_DegToRad(count*approx_degree); xp1 = x + (int8_t)(sinf(rad)*radius); yp1 = y + (int8_t)(cosf(rad)*radius); count++; if (count != approx_segments) { rad = ssd1306_DegToRad(count*approx_degree); } else { rad = ssd1306_DegToRad(loc_sweep); } xp2 = x + (int8_t)(sinf(rad)*radius); yp2 = y + (int8_t)(cosf(rad)*radius); ssd1306_Line(xp1,yp1,xp2,yp2,color); } // Radius line ssd1306_Line(x,y,first_point_x,first_point_y,color); ssd1306_Line(x,y,xp2,yp2,color); return; } /* Draw circle by Bresenhem's algorithm */ void ssd1306_DrawCircle(uint8_t par_x,uint8_t par_y,uint8_t par_r,SSD1306_COLOR par_color) { int32_t x = -par_r; int32_t y = 0; int32_t err = 2 - 2 * par_r; int32_t e2; if (par_x >= SSD1306_WIDTH || par_y >= SSD1306_HEIGHT) { return; } do { ssd1306_DrawPixel(par_x - x, par_y + y, par_color); ssd1306_DrawPixel(par_x + x, par_y + y, par_color); ssd1306_DrawPixel(par_x + x, par_y - y, par_color); ssd1306_DrawPixel(par_x - x, par_y - y, par_color); e2 = err; if (e2 <= y) { y++; err = err + (y * 2 + 1); if(-x == y && e2 <= x) { e2 = 0; } } if (e2 > x) { x++; err = err + (x * 2 + 1); } } while (x <= 0); return; } /* Draw filled circle. Pixel positions calculated using Bresenham's algorithm */ void ssd1306_FillCircle(uint8_t par_x,uint8_t par_y,uint8_t par_r,SSD1306_COLOR par_color) { int32_t x = -par_r; int32_t y = 0; int32_t err = 2 - 2 * par_r; int32_t e2; if (par_x >= SSD1306_WIDTH || par_y >= SSD1306_HEIGHT) { return; } do { for (uint8_t _y = (par_y + y); _y >= (par_y - y); _y--) { for (uint8_t _x = (par_x - x); _x >= (par_x + x); _x--) { ssd1306_DrawPixel(_x, _y, par_color); } } e2 = err; if (e2 <= y) { y++; err = err + (y * 2 + 1); if (-x == y && e2 <= x) { e2 = 0; } } if (e2 > x) { x++; err = err + (x * 2 + 1); } } while (x <= 0); return; } /* Draw a rectangle */ void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) { ssd1306_Line(x1,y1,x2,y1,color); ssd1306_Line(x2,y1,x2,y2,color); ssd1306_Line(x2,y2,x1,y2,color); ssd1306_Line(x1,y2,x1,y1,color); return; } /* Draw a filled rectangle */ void ssd1306_FillRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) { uint8_t x_start = ((x1<=x2) ? x1 : x2); uint8_t x_end = ((x1<=x2) ? x2 : x1); uint8_t y_start = ((y1<=y2) ? y1 : y2); uint8_t y_end = ((y1<=y2) ? y2 : y1); for (uint8_t y= y_start; (y<= y_end)&&(y<SSD1306_HEIGHT); y++) { for (uint8_t x= x_start; (x<= x_end)&&(x<SSD1306_WIDTH); x++) { ssd1306_DrawPixel(x, y, color); } } return; } SSD1306_Error_t ssd1306_InvertRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) { if ((x2 >= SSD1306_WIDTH) || (y2 >= SSD1306_HEIGHT)) { return SSD1306_ERR; } if ((x1 > x2) || (y1 > y2)) { return SSD1306_ERR; } uint32_t i; if ((y1 / 8) != (y2 / 8)) { /* if rectangle doesn't lie on one 8px row */ for (uint32_t x = x1; x <= x2; x++) { i = x + (y1 / 8) * SSD1306_WIDTH; SSD1306_Buffer[i] ^= 0xFF << (y1 % 8); i += SSD1306_WIDTH; for (; i < x + (y2 / 8) * SSD1306_WIDTH; i += SSD1306_WIDTH) { SSD1306_Buffer[i] ^= 0xFF; } SSD1306_Buffer[i] ^= 0xFF >> (7 - (y2 % 8)); } } else { /* if rectangle lies on one 8px row */ const uint8_t mask = (0xFF << (y1 % 8)) & (0xFF >> (7 - (y2 % 8))); for (i = x1 + (y1 / 8) * SSD1306_WIDTH; i <= (uint32_t)x2 + (y2 / 8) * SSD1306_WIDTH; i++) { SSD1306_Buffer[i] ^= mask; } } return SSD1306_OK; } /* Draw a bitmap */ void ssd1306_DrawBitmap(uint8_t x, uint8_t y, const unsigned char* bitmap, uint8_t w, uint8_t h, SSD1306_COLOR color) { int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte uint8_t byte = 0; if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) { return; } for (uint8_t j = 0; j < h; j++, y++) { for (uint8_t i = 0; i < w; i++) { if (i & 7) { byte <<= 1; } else { byte = (*(const unsigned char *)(&bitmap[j * byteWidth + i / 8])); } if (byte & 0x80) { ssd1306_DrawPixel(x + i, y, color); } } } return; } void ssd1306_SetContrast(const uint8_t value) { const uint8_t kSetContrastControlRegister = 0x81; ssd1306_WriteCommand(kSetContrastControlRegister); ssd1306_WriteCommand(value); } void ssd1306_SetDisplayOn(const uint8_t on) { uint8_t value; if (on) { value = 0xAF; // Display on SSD1306.DisplayOn = 1; } else { value = 0xAE; // Display off SSD1306.DisplayOn = 0; } ssd1306_WriteCommand(value); } uint8_t ssd1306_GetDisplayOn() { return SSD1306.DisplayOn; }
View more

 

 

 

 

 

 

Please see the Posting Tips for how to properly post source code:

https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/ta-p/575228

I edited your post for you

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Thanks alot @Andrew Neil
Will take care of this in future. 
Regards