Connecting ssd1306 0.96 Inch 128×64 4Pin I2C OLED Display to STM32F401RE STMicroelectronics board in STM32CubeIDE
First we as usually create an empty STM32 Project for the STM32F401RE board. Then we activate I2C1 in the Connectivity section, and change the I2C Speed mode from Standard Mode to Fast Mode. After this we can generate the code.
Next we connect the ssd1306 display to the board. For this we download from the STMicroelectronics's website, st.com, the file User Manual STM32 Nucleo-64 board UM1724 (en.DM00105823.pdf) and look up the hardware pins configuration for the F401RE on the page #32. We need four pins: PB6, PB7, GND (ground), and +3V3. Here is the print-screen of the page #32:
So we connect the SCL of the display to the PB6 (I2C1_SCL) pin of the board, the SDA to PB7 (I2C1_SDA), VCC to the +3V3, and GND to GND. But the display will not work yet. It is necessary to add the six additional files of the ssd1306 library. They are in this ZIP archive. Three of this files sdd1306.h, fonts.h, and test.h go to the folder /Core/Inc/, and the other three files ssd1306.c, fonts.c, test.c, go to the folder /Core/Src/.
#include "ssd1306.h"
#include "test.h"
#include "fonts.h"
SSD1306_Init(); // initialize the OLED display
while (1) {
SSD1306_Clear();
SSD1306_GotoXY(5, 0); // coordinates x, y
SSD1306_Puts("Hello", &Font_11x18, 1); // print Hello
SSD1306_GotoXY(0, 24); // coordinates x, y
SSD1306_Puts("ssd1306 OLED", &Font_7x10, 1);
SSD1306_GotoXY(0, 40); // coordinates x, y
SSD1306_Puts("display!", &Font_11x18, 1);
SSD1306_UpdateScreen(); // update screen
HAL_Delay(10000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ssd1306.h"
#include "test.h"
#include "fonts.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void) {
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
SSD1306_Init(); // initialize the OLED display
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
SSD1306_Clear();
SSD1306_GotoXY(5, 0); // coordinates x, y
SSD1306_Puts("Hello", &Font_11x18, 1); // print Hello
SSD1306_GotoXY(0, 24); // coordinates x, y
SSD1306_Puts("ssd1306 OLED", &Font_7x10, 1);
SSD1306_GotoXY(0, 40); // coordinates x, y
SSD1306_Puts("display!", &Font_11x18, 1);
SSD1306_UpdateScreen(); // update screen
HAL_Delay(10000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
And the OLED display works fine with the Nucleo-F401Re board:
Now we will draw a line and display a dynamic text on our OLED screen.
/* USER CODE BEGIN 2 */
SSD1306_Init(); // initialize the diaply
uint32_t mC = 0;
char smC[5];
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
SSD1306_Clear();
SSD1306_GotoXY(5, 0); // coordinates x, y
SSD1306_Puts("Counting:", &Font_11x18, 1); // SSD1306_Puts(char* str, FontDef_t* Font, SSD1306_COLOR_t color);
SSD1306_DrawLine(0, 20, 128, 20, 1); // void SSD1306_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, SSD1306_COLOR_t c);
SSD1306_GotoXY(50, 35); // coordinates x, y
itoa(mC, smC, 10); // char * itoa ( int value, char * str, int base ); Convert integer to string
SSD1306_Puts(smC, &Font_16x26, 1);
SSD1306_UpdateScreen(); // update screen
mC++;
SSD1306_UpdateScreen(); // update screen
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
We increment the mC integer variable then convert it to the string with the itoa(); C function and print it on the display.