yahboom
HomeLearn
Solution
Blog
Online Store
About Us
EN/中文
ROS Robot Expansion Board📖
1.Expansion board STM32 driver
  • 0. Precautions
  • 1.1 Expansion Board Introduction_V3.0
  • 1.1 Expansion Board Introduction_V1.0
  • 1.2 STM32 Development environment
  • 1.3 Button to control the buzzer to whistle
  • 1.4 FreeRTOS application
  • 1.5 Serial communication
  • 1.6 SBUS model aircraft remote control
  • 1.7 CAN bus communication
  • 1.8 RGB colorful light bar
  • 1.9 Timer interrupt to control PWM servo
  • 1.10 Control serial port servos
  • 1.11 Nine-axis attitude sensor to obtain data
  • 1.12 Control the forward and reverse rotation of the motor
  • 1.13 The timer captures the encoder data
  • 1.14.1 Robot kinematics analysis theory
  • 1.14.2 Mecanum wheel kinematics analysis
  • 1.15 PID control robot movement
  • 1.16 OLED character display
2.Python basic control
  • 2.0 Bind PCB port devices
  • 2.1 Update the firmware of the expansion board
  • 2.2 Turn off the self-starting large program at startup
  • 2.3 Install the Rosmaster driver library
  • 2.4 Buzzer whistle
  • 2.5 Control PWM servo
  • 2.6 RGB colorful light bar special effects display
  • 2.7 Control the forward and reverse rotation of the motor
  • 2.8 Control the movement of the robot
  • 2.9 Control Serial Servo
3.ROS1 Basic Course
  • 1.ROS introduction
  • 2.ROS installation
  • 3.ROS common command tools
  • 4.ROS workspace
  • 5.ROS function package
  • 6.ROS node
  • 7.ROS topic publisher
  • 8.ROS topic subscribers
  • 9.ROS service client
  • 10.ROS service server
  • 11.ROS action client
  • 12.ROS action server
  • 13.ROS custom message reception
  • 14.ROS-launch file
  • 15.ROS-TF transformation
  • 16.ROS parameter service
  • 17.ROS-rviz use
  • 18.ROS-rqt tool usage
  • 19.Topic message recording and playback
  • 20.urdf model introduction
  • 21.gazebo introduction
  • 22.ROS distributed communication
4.ROS1 robot control
  • 0. Bind PCB port devices
  • 1. Package Use the tutorial
  • 2. Package Description
  • 3. Robot keyboard control
  • 4. Robot state estimation
  • 5. Robot imu calibration
  • 6. Robot URDF Model
5.ROS2 Basic Course
  • 1.Introduction to ROS2
  • 2.ROS2 install Humble
  • 3.ROS2 development environment
  • 4.ROS2 workspace
  • 5.ROS2 function package
  • 6.ROS2 node
  • 7.ROS2 topic communication
  • 8.ROS2 service communication
  • 9.ROS2 action communication
  • 10.ROS2 custom interface message
  • 11.ROS2 parameter service case
  • 12.ROS2 meta-function package
  • 13.ROS2 distributed communication
  • 14.ROS2 DDS
  • 15.ROS2 time related API
  • 16.ROS2 common command tools
  • 17.ROS2 rviz2 use
  • 18.ROS2 rqt toolbox
  • 19.ROS2 Launch startup file configuration
  • 20.ROS2 recording and playback tool
  • 21.ROS2 URDF model
  • 22.ROS2 Gazebo simulation platform
  • 23.ROS2 TF2 coordinate transformation
6.ROS2 robot control
  • 0. Bind PCB port devices
  • 1. Package Use the tutorial
  • 2. Robot information release
  • 3. Robot keyboard control
  • 4. Robot state estimation
  • 5. Robot calibration
  • 6. URDF model
7.RDK X3 course
  • 1. Update the firmware of the expansion board
  • 2. Turn off the self-starting large program at startup
  • 3. Install the Rosmaster driver library
  • 4. Buzzer whistle
  • 5. Control PWM servo
  • 6. RGB colorful light bar special effects
  • 7. Control motor forward reverse
  • 8. Control robot movement
  • 9. Control Serial Servo
Download
  • Rules_File
  • Hardware Info
  • Code
  • 3D Model File
  • RDK Code
  • ROS2_Basic_VM
Download ZIP

Welcome to ROS Robot Expansion Board repository

1.16 OLED character display

16. OLED character display

16. OLED character display 16.1 the purpose of the experiment 16.2 configuration, pin information 16.3 the experimental flow chart parsing 16.4 the core code explanation 16.5 hardware connection 16.6 the experimental effect

16.1 the purpose of the experiment

Through I2C communication, learning to drive SSD1306 chip, thereby driving the OLED display character.

16.2 configuration, pin information

Because each new project requires configuration information, too much trouble, good STM32CubeIDE provides the import. ioc file, you can help us save time.

1.From the OLED project import ioc file, and the name of the OLED.

image-20220309122850686

2.According to the principles of the figure shows: reserved OLED with I2C interface control PIN is connected to the STM32 chip PB10 and PB11 pin. Due to our present times the use of software IO analog I2C communication, so you need to PB10 and PB11 set to GPIO_Output mode, and modify the label for SCL and SDA, the other configuration is shown below.

image-20221014142035762image-20221014141947295

image-20221014142830723

Save and generate code.

16.3 the experimental flow chart parsing

image-20221014165343771

16.4 the core code explanation

1.New bsp_io_i2c. h and bsp_io_i2c. c, and in bsp_io_i2c. h add the following content:

image-20221014143540990

2.In bsp_io_i2c. c file in the new the following:

According to the IIC Protocol content, IIC_Start()to generate the IIC start signal, IIC_Stop()to generate the IIC stop signal.

image-20221014143840089

3.IIC response correlation function.

image-20221014143955130

image-20221014144009937image-20221014144009937

4.IIC send and read the data of the relevant function.

image-20221014144229883image-20221014144257858

image-20221014144353280

image-20221014144427442

5.New bsp_ssd1306. h and bsp_ssd1306. c, and in bsp_ssd1306. h add the following content:

xxxxxxxxxx
#ifndef __BSP_SSD1306_H__ 
#define __BSP_SSD1306_H__ 

#include "oled_fonts. h" 
#include "stdint. h" 

#define SSD1306_I2C_ADDR 0x3C 
#define SSD1306_WIDTH 128 
#define SSD1306_HEIGHT 32 


typedef enum { 
    SSD1306_COLOR_BLACK = 0x00, /*!< Black color, no pixel */ 
    SSD1306_COLOR_WHITE = 0x01  /*!< Pixel is set. Color depends on LCD */ 
} SSD1306_COLOR_t; 


uint8_t SSD1306_Init(void); 
void SSD1306_UpdateScreen(void); 
void SSD1306_ToggleInvert(void); 
void SSD1306_Fill(SSD1306_COLOR_t Color); 
void SSD1306_DrawPixel(uint16_t x, uint16_t y, SSD1306_COLOR_t color); 
void SSD1306_GotoXY(uint16_t x, uint16_t y); 
char SSD1306_Putc(char ch, FontDef_t* Font, SSD1306_COLOR_t color); 
char SSD1306_Puts(char* str, FontDef_t* Font, SSD1306_COLOR_t color); 
void SSD1306_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, SSD1306_COLOR_t c); 
void SSD1306_DrawRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, SSD1306_COLOR_t c); 
void SSD1306_DrawFilledRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, SSD1306_COLOR_t c); 
void SSD1306_DrawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, SSD1306_COLOR_t color); 
void SSD1306_DrawCircle(int16_t x0, int16_t y0, int16_t r, SSD1306_COLOR_t c); 
void SSD1306_DrawFilledCircle(int16_t x0, int16_t y0, int16_t r, SSD1306_COLOR_t c); 


void ssd1306_I2C_Init(void); 
void ssd1306_I2C_Write(uint8_t address, uint8_t reg, uint8_t data); 
void ssd1306_I2C_WriteMulti(uint8_t address, uint8_t reg, uint8_t *data, uint16_t count); 

#endif /* __BSP_SSD1306_H__ */  

6.在bsp_ssd1306.c增加以下相关函数。

xxxxxxxxxx

#include "bsp_ssd1306.h" 
#include "bsp_io_i2c.h" 

/* Write command */ 
#define SSD1306_WRITECOMMAND(command) ssd1306_I2C_Write(SSD1306_I2C_ADDR, 0x00, (command)) 
/* Write data */ 
#define SSD1306_WRITEDATA(data) ssd1306_I2C_Write(SSD1306_I2C_ADDR, 0x40, (data)) 
/* Absolute value */ 


/* SSD1306 data buffer */ 
static uint8_t SSD1306_Buffer[SSD1306_WIDTH * SSD1306_HEIGHT / 8]; 

typedef struct 
{ 
    uint16_t CurrentX; 
    uint16_t CurrentY; 
    uint8_t Inverted; 
    uint8_t Initialized; 
} SSD1306_t; 

static SSD1306_t SSD1306; 

static uint16_t ABS(int a) 
{ 
    int temp = a; 
    if (a < 0) temp = -a; 
    return temp; 
} 

/* 初始化SSD1306芯片 Initialize the SSD1306 chip*/ 
uint8_t SSD1306_Init(void) 
{ 
    /* A little delay */ 
    uint32_t p = 2500; 
    while (p > 0) 
        p--; 

    /* Init LCD */ 
    SSD1306_WRITECOMMAND(0xae);            // display off 
    SSD1306_WRITECOMMAND(0xa6);          // Set Normal Display (default) 
    SSD1306_WRITECOMMAND(0xAE);          // DISPLAYOFF 
    SSD1306_WRITECOMMAND(0xD5);          // SETDISPLAYCLOCKDIV 
    SSD1306_WRITECOMMAND(0x80);          // the suggested ratio 0x80 
    SSD1306_WRITECOMMAND(0xA8);          // SSD1306_SETMULTIPLEX 
    SSD1306_WRITECOMMAND(0x1F); 
    SSD1306_WRITECOMMAND(0xD3);          // SETDISPLAYOFFSET 
    SSD1306_WRITECOMMAND(0x00);              // no offset 
    SSD1306_WRITECOMMAND(0x40 | 0x0);    // SETSTARTLINE 
    SSD1306_WRITECOMMAND(0x8D);          // CHARGEPUMP 
    SSD1306_WRITECOMMAND(0x14);          // 0x014 enable, 0x010 disable 
    SSD1306_WRITECOMMAND(0x20);          // com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5), 
    SSD1306_WRITECOMMAND(0x02);          // 0x12 //128x32 OLED: 0x002,  128x32 OLED 0x012 
    SSD1306_WRITECOMMAND(0xa1);          // segment remap a0/a1 
    SSD1306_WRITECOMMAND(0xc8);          // c0: scan dir normal, c8: reverse 
    SSD1306_WRITECOMMAND(0xda); 
    SSD1306_WRITECOMMAND(0x02);          // com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) 
    SSD1306_WRITECOMMAND(0x81); 
    SSD1306_WRITECOMMAND(0xcf);          // [2] set contrast control 
    SSD1306_WRITECOMMAND(0xd9); 
    SSD1306_WRITECOMMAND(0xf1);          // [2] pre-charge period 0x022/f1 
    SSD1306_WRITECOMMAND(0xdb); 
    SSD1306_WRITECOMMAND(0x40);          // vcomh deselect level 
    SSD1306_WRITECOMMAND(0x2e);          // Disable scroll 
    SSD1306_WRITECOMMAND(0xa4);          // output ram to display 
    SSD1306_WRITECOMMAND(0xa6);          // none inverted normal display mode 
    SSD1306_WRITECOMMAND(0xaf);          // display on 
    
    /* Clear screen */ 
    SSD1306_Fill(SSD1306_COLOR_BLACK); 

    /* Update screen */ 
    SSD1306_UpdateScreen(); 

    /* Set default values */ 
    SSD1306.CurrentX = 0; 
    SSD1306.CurrentY = 0; 

    /* Initialized OK */ 
    SSD1306.Initialized = 1; 

    /* Return OK */ 
    return 1; 
} 

/* 刷新数据 Update Screen */ 
void SSD1306_UpdateScreen(void) 
{ 
    uint8_t m; 

    for (m = 0; m < 8; m++) 
    { 
        SSD1306_WRITECOMMAND(0xB0 + m); 
        SSD1306_WRITECOMMAND(0x00); 
        SSD1306_WRITECOMMAND(0x10); 

        /* Write multi data */ 
        ssd1306_I2C_WriteMulti(SSD1306_I2C_ADDR, 0x40, &SSD1306_Buffer[SSD1306_WIDTH * m], SSD1306_WIDTH); 
    } 
} 

/* 像素反转 Pixel Invert */ 
void SSD1306_ToggleInvert(void) 
{ 
    uint16_t i; 

    /* Toggle invert */ 
    SSD1306.Inverted = !SSD1306.Inverted; 

    /* Do memory toggle */ 
    for (i = 0; i < sizeof(SSD1306_Buffer); i++) 
    { 
        SSD1306_Buffer[i] = ~SSD1306_Buffer[i]; 
    } 
} 

/* 填充颜色 Fill color*/ 
void SSD1306_Fill(SSD1306_COLOR_t color) 
{ 
 /* Set memory */ 
 memset(SSD1306_Buffer, (color == SSD1306_COLOR_BLACK) ? 0x00 : 0xFF, sizeof(SSD1306_Buffer)); 
} 

/* Draw a Pixel draw a pixel*/ 
void SSD1306_DrawPixel(uint16_t x, uint16_t y, SSD1306_COLOR_t color) 
{ 
 if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) 
    { 
 return; // error, out of range Error, out of scope 
    } 

 /* Check whether the Pixel is inverted Check if the pixel is Inverted*/ 
    if (SSD1306.Inverted) 
    { 
        color = (SSD1306_COLOR_t)!color; 
    } 

    /* 设置颜色 set colors */ 
    if (color == SSD1306_COLOR_WHITE) 
    { 
        SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] |= 1 << (y % 8); 
    } 
    else 
    { 
        SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] &= ~(1 << (y % 8)); 
    } 
} 

/* 设置当前点X Y值 Set the current point(X , Y) value */ 
void SSD1306_GotoXY(uint16_t x, uint16_t y) 
{ 
 SSD1306. CurrentX = x; 
 SSD1306. CurrentY = y; 
} 

/* A character is converted to a pixel point Convert a character into pixels */ 
char SSD1306_Putc(char ch, FontDef_t *Font, SSD1306_COLOR_t color) 
{ 
 a uint32_t that i, b, j; 

 if ( 
 SSD1306_WIDTH <= (SSD1306. CurrentX + Font->FontWidth) || 
 SSD1306_HEIGHT <= (SSD1306. CurrentY + Font->FontHeight)) 
    { 
 return 0; // error, out of range Error, out of scope 
    } 

    for (i = 0; i < Font->FontHeight; i++) 
    { 
        b = Font->data[(ch - 32) * Font->FontHeight + i]; 
        for (j = 0; j < Font->FontWidth; j++) 
        { 
            if ((b << j) & 0x8000) 
            { 
                SSD1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR_t)color); 
            } 
            else 
            { 
                SSD1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR_t)!color); 
            } 
        } 
    } 
    /* Increase pointer */ 
    SSD1306.CurrentX += Font->FontWidth; 
    /* Return character written */ 
    return ch; 
} 

/* 将字符串转化成像素 Converts a string to pixels */ 
char SSD1306_Puts(char *str, FontDef_t *Font, SSD1306_COLOR_t color) 
{ 
    /* Write characters */ 
    while (*str) 
    { 
        /* Write character by character */ 
        if (SSD1306_Putc(*str, Font, color) != *str) 
        { 
            /* Return error */ 
            return *str; 
        } 
        /* Increase string pointer */ 
        str++; 
    } 
    /* Everything OK, zero should be returned */ 
    return *str; 
} 

/* 画一条线 Draw a Line*/ 
void SSD1306_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, SSD1306_COLOR_t c) 
{ 
    int16_t dx, dy, sx, sy, err, e2, i, tmp; 

    /* Check for overflow */ 
    if (x0 >= SSD1306_WIDTH) 
    { 
        x0 = SSD1306_WIDTH - 1; 
    } 
    if (x1 >= SSD1306_WIDTH) 
    { 
        x1 = SSD1306_WIDTH - 1; 
    } 
    if (y0 >= SSD1306_HEIGHT) 
    { 
        y0 = SSD1306_HEIGHT - 1; 
    } 
    if (y1 >= SSD1306_HEIGHT) 
    { 
        y1 = SSD1306_HEIGHT - 1; 
    } 

    dx = (x0 < x1) ? (x1 - x0) : (x0 - x1); 
 dy = (y0 < y1) ? (y1 - y0) : (y0 - y1); 
 sx = (x0 < x1) ? 1 : -1; 
 sy = (y0 < y1) ? 1 : -1; 
 err = ((dx > dy) ? dx : -dy) / 2; 

 if (dx == 0) 
    { 
 if (y1 < y0) 
        { 
 tmp = y1; 
 y1 = y0; 
 y0 = tmp; 
        } 

 if (x1 < x0) 
        { 
 tmp = x1; 
            x1 = x0; 
            x0 = tmp; 
        } 

        /* Vertical line */ 
        for (i = y0; i <= y1; i++) 
        { 
            SSD1306_DrawPixel(x0, i, c); 
        } 

        /* Return from function */ 
        return; 
    } 

    if (dy == 0) 
    { 
 if (y1 < y0) 
        { 
 tmp = y1; 
 y1 = y0; 
 y0 = tmp; 
        } 

 if (x1 < x0) 
        { 
 tmp = x1; 
            x1 = x0; 
            x0 = tmp; 
        } 

        /* Horizontal line */ 
        for (i = x0; i <= x1; i++) 
        { 
            SSD1306_DrawPixel(i, y0, c); 
        } 

        /* Return from function */ 
        return; 
    } 

 while (1) 
    { 
 SSD1306_DrawPixel(x0, y0, c); 
 if (x0 == x1 && y0 == y1) 
        { 
 break; 
        } 
 e2 = err; 
 if (e2 > -dx) 
        { 
 err -= dy; 
 x0 += sx; 
        } 
 if (e2 < dy) 
        { 
 err += dx; 
 y0 += sy; 
        } 
    } 
} 

/* 画一个矩形 Draw a Rectangle */ 
void SSD1306_DrawRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, SSD1306_COLOR_t c) 
{ 
    /* Check input parameters */ 
 if ( 
        x >= SSD1306_WIDTH || 
        y >= SSD1306_HEIGHT) 
    { 
        /* Return error */ 
        return; 
    } 

    /* Check width and height */ 
    if ((x + w) >= SSD1306_WIDTH) 
    { 
        w = SSD1306_WIDTH - x; 
    } 
    if ((y + h) >= SSD1306_HEIGHT) 
    { 
        h = SSD1306_HEIGHT - y; 
    } 

    /* Draw 4 lines */ 
 SSD1306_DrawLine(x, y, x + w, y, c); /* Top line */ 
 SSD1306_DrawLine(x, y + h, x + w, y + h, c); /* Bottom line */ 
 SSD1306_DrawLine(x, y, x, y + h, c); /* Left line */ 
 SSD1306_DrawLine(x + w, y, x + w, y + h, c); /* Right line */ 
} 

/* 画一个实心的矩形 Draw a Filled Rectangle*/ 
void SSD1306_DrawFilledRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, SSD1306_COLOR_t c) 
{ 
    uint8_t i; 

    /* Check input parameters */ 
 if ( 
        x >= SSD1306_WIDTH || 
        y >= SSD1306_HEIGHT) 
    { 
        /* Return error */ 
        return; 
    } 

    /* Check width and height */ 
    if ((x + w) >= SSD1306_WIDTH) 
    { 
        w = SSD1306_WIDTH - x; 
    } 
    if ((y + h) >= SSD1306_HEIGHT) 
    { 
        h = SSD1306_HEIGHT - y; 
    } 

    /* Draw lines */ 
    for (i = 0; i <= h; i++) 
    { 
        /* Draw lines */ 
        SSD1306_DrawLine(x, y + i, x + w, y + i, c); 
    } 
} 

/* 画一个三角形 Draw a Triangle */ 
void SSD1306_DrawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, SSD1306_COLOR_t color) 
{ 
    /* Draw lines */ 
    SSD1306_DrawLine(x1, y1, x2, y2, color); 
    SSD1306_DrawLine(x2, y2, x3, y3, color); 
    SSD1306_DrawLine(x3, y3, x1, y1, color); 
} 

/* 画一个实心的三角形  Draw a Filled Triangle*/ 
void SSD1306_DrawFilledTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, SSD1306_COLOR_t color) 
{ 
    int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 
            yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, 
            curpixel = 0; 

    deltax = ABS(x2 - x1); 
    deltay = ABS(y2 - y1); 
 x = x1; 
 y = y1; 

 if (x2 >= x1) 
    { 
 xinc1 = 1; 
 xinc2 = 1; 
    } 
    else 
    { 
 xinc1 = -1; 
 xinc2 = -1; 
    } 

 if (y2 >= y1) 
    { 
 yinc1 = 1; 
 yinc2 = 1; 
    } 
    else 
    { 
 yinc1 = -1; 
 yinc2 = -1; 
    } 

 if (deltax >= delta) 
    { 
 xinc1 = 0; 
 yinc2 = 0; 
        den = deltax; 
        num = deltax / 2; 
        numadd = deltay; 
        numpixels = deltax; 
    } 
    else 
    { 
        xinc2 = 0; 
        yinc1 = 0; 
        den = deltay; 
        num = deltay / 2; 
        numadd = deltax; 
        numpixels = deltay; 
    } 

    for (curpixel = 0; curpixel <= numpixels; curpixel++) 
    { 
        SSD1306_DrawLine(x, y, x3, y3, color); 

        num += numadd; 
        if (num >= den) 
        { 
            num -= den; 
            x += xinc1; 
            y += yinc1; 
        } 
        x += xinc2; 
        y += yinc2; 
    } 
} 

/* 画一个圆 Draw a Circle */ 
void SSD1306_DrawCircle(int16_t x0, int16_t y0, int16_t r, SSD1306_COLOR_t c) 
{ 
    int16_t f = 1 - r; 
    int16_t ddF_x = 1; 
    int16_t ddF_y = -2 * r; 
    int16_t x = 0; 
    int16_t y = r; 

    SSD1306_DrawPixel(x0, y0 + r, c); 
    SSD1306_DrawPixel(x0, y0 - r, c); 
    SSD1306_DrawPixel(x0 + r, y0, c); 
    SSD1306_DrawPixel(x0 - r, y0, c); 

    while (x < y) 
    { 
        if (f >= 0) 
        { 
            y--; 
            ddF_y += 2; 
            f += ddF_y; 
        } 
        x++; 
        ddF_x += 2; 
        f += ddF_x; 

        SSD1306_DrawPixel(x0 + x, y0 + y, c); 
        SSD1306_DrawPixel(x0 - x, y0 + y, c); 
        SSD1306_DrawPixel(x0 + x, y0 - y, c); 
        SSD1306_DrawPixel(x0 - x, y0 - y, c); 

        SSD1306_DrawPixel(x0 + y, y0 + x, c); 
        SSD1306_DrawPixel(x0 - y, y0 + x, c); 
        SSD1306_DrawPixel(x0 + y, y0 - x, c); 
        SSD1306_DrawPixel(x0 - y, y0 - x, c); 
    } 
} 

/* 画一个实心圆 Draw a Filled Circle */ 
void SSD1306_DrawFilledCircle(int16_t x0, int16_t y0, int16_t r, SSD1306_COLOR_t c) 
{ 
    int16_t f = 1 - r; 
    int16_t ddF_x = 1; 
    int16_t ddF_y = -2 * r; 
    int16_t x = 0; 
    int16_t y = r; 

    SSD1306_DrawPixel(x0, y0 + r, c); 
    SSD1306_DrawPixel(x0, y0 - r, c); 
    SSD1306_DrawPixel(x0 + r, y0, c); 
    SSD1306_DrawPixel(x0 - r, y0, c); 
 SSD1306_DrawLine(x0 - r, y0, x0 + r, y0, c); 

    while (x < y) 
    { 
        if (f >= 0) 
        { 
            y--; 
            ddF_y += 2; 
            f += ddF_y; 
        } 
        x++; 
        ddF_x += 2; 
        f += ddF_x; 

 SSD1306_DrawLine(x0 - x, y0 + y, x0 + x, y0 + y, c); 
 SSD1306_DrawLine(x0 + x, y0 - y, x0 - x, y0 - y, c); 

 SSD1306_DrawLine(x0 + y, y0 + x, x0 - y, y0 + x, c); 
 SSD1306_DrawLine(x0 + y, y0 - x, x0 - y, y0 - x, c); 
    } 
} 

/* 打开SSD1306 */ 
void SSD1306_ON(void) 
{ 
    SSD1306_WRITECOMMAND(0x8D); 
    SSD1306_WRITECOMMAND(0x14); 
    SSD1306_WRITECOMMAND(0xAF); 
} 

/* 关闭SSD1306 */ 
void SSD1306_OFF(void) 
{ 
    SSD1306_WRITECOMMAND(0x8D); 
    SSD1306_WRITECOMMAND(0x10); 
    SSD1306_WRITECOMMAND(0xAE); 
} 

//////////////////////////////////////////////////////////////////////////////// 
//////////////////////////////////////////////////////////////////////////////// 
//////////////////////////////////////////////////////////////////////////////// 
//////////////////////////////////////////////////////////////////////////////// 
/* IIC一次写多个数据 Write Multi Data */ 
void ssd1306_I2C_WriteMulti(uint8_t address, uint8_t reg, uint8_t *data, uint16_t count) 
{ 
 IIC_Write_Len(address, reg, count, data); 
} 

/* IIC write data Write Data*/ 
void ssd1306_I2C_Write(uint8_t address, uint8_t reg, uint8_t data) 
{ 
 IIC_Write_Byte(address, reg, data); 
} 

7.New oled_fonts. h and oled_fonts. c, is mainly responsible for the character encoding conversion pixel of the features.

8.New bsp_oled. h and bsp_oled. c, and in bsp_oled. h add the following content:

xxxxxxxxxx
/* 
 * bsp_oled. h 
 * 
 * Created on: Oct 14, 2022 
 * Author: Administrator 
 */ 

#ifndef BSP_OLED_H_ 
#define BSP_OLED_H_ 
#include "stdint. h" 

/* OLED Clear clear the screen */ 
void OLED_Clear(void); 
/* OLED Refresh to refresh the screen */ 
void OLED_Refresh(void); 
/* Draw String to write into the character */ 
void OLED_Draw_String(char *data, uint8_t x, uint8_t y, uint8_t clear, uint8_t refresh); 
/* Draw Line, write a line of characters */ 
void OLED_Draw_Line(char *data, uint8_t line, uint8_t clear, uint8_t refresh); 


#endif /* BSP_OLED_H_ */ 

9.In bsp_oled. c add the following correlation function.

xxxxxxxxxx
#include "bsp_oled.h" 
#include "bsp_ssd1306.h" 

/* OLED Clear clear the screen */ 
void OLED_Clear(void) 
{ 
    SSD1306_Fill(SSD1306_COLOR_BLACK); 
} 

/* OLED Refresh to refresh the screen */ 
void OLED_Refresh(void) 
{ 
    SSD1306_UpdateScreen(); 
} 

/* Draw String to write into the character */ 
void OLED_Draw_String(char *data, uint8_t x, uint8_t y, uint8_t clear, uint8_t refresh) 
{ 
    if (clear) OLED_Clear(); 
    SSD1306_GotoXY(x, y); 
    SSD1306_Puts(data, &Font_7x10, SSD1306_COLOR_WHITE); 
    if (refresh) OLED_Refresh(); 
} 

/* Draw Line, write a line of characters */ 
void OLED_Draw_Line(char *data, uint8_t line, uint8_t clear, uint8_t refresh) 
{ 
    if (line > 0 && line <= 3) 
    { 
        OLED_Draw_String(data, 0, 10 * (line - 1), clear, refresh); 
    } 
} 

10.In Bsp_Init()function to add the initialization SSD1306 content, and display Hello Yahboom character in the OLED on.

image-20221014152259422

11.In Bsp_Loop()function to add the button to refresh the OLED screen display function.

image-20221014152511203

16.5 hardware connection

External I2C interface is a two-pin socket, two rows of pins in parallel, the OLED screen as long as the alignment in which a row of pins can be inserted.

image-20221014154656632

image-20221014154144628

16.6 the experimental effect

Flashcard program, LED lights every 200 MS Flash once. In this case the OLED screen is on the display Hello Yahboom, when we press the keys KEY1, OLED screen data will be refreshed each time you press the KEY1 number plus 1.

image-20221014155531817

PID control robot movement
Bind PCB port devices

COMPANY

  • About us
  • Team Style
  • Blog

LEARNING & EXPLORATION

  • Tutorials
  • Edge AI hardware
  • Educational robots
  • Embedded intelligent hardware

WHERE TO BUY

  • Yahboom Online Store
  • Amazon
  • Alibaba
  • AliExpress
  • Mercado

TECHNOLOGY SUPPORT

  • Email: support@yahboom.com

BE A DISTRIBUTOR

  • Email: sales@yahboom.com
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文