Understand the principle of OLED display - Various ways to use OLED modules
The OLED module has four working modes, namely 6800 and 8080 parallel interfaces, 4-wire serial SPI interface mode, and IIC interface mode. The relationship between the BS1/BS2 settings and the module interface mode is shown in the following table:
The default setting of SAEF Technology OLED module is BS0 to GND, BS1 and BS2 to VCC (8080 mode), if you want to set it to other modes, you need to modify the BS0-BS2 settings with a soldering iron on the back of the OLED. (Hardware Change)
From the schematic, we can know that there are a total of 16 pins drawn out, and out of the 16 lines, we only used 15 pins, and one of them is dangling. Of the 15 lines, 2 are power and ground, and 13 are left. In different modes, the number of signal lines we need is different, in 8080 mode, all 13 are needed, one of which is common, that is, the reset line RST (RES), which we can directly connect to the reset of the MCU (to confirm that the reset method is the same), so that one line can be omitted. In IIC mode, only 2 lines are needed!
We just learned about it. The working mode of the IIC only needs two lines, and the working mode of the IIC is to use two wires to simulate the IIC to obtain data.
The OLED controller is SSD1306, that is to say: the bare screen is driven by SSD1306, which is also a more widely used led driver chip.
OLED module video memory
OLED itself does not have video memory, and its video memory is dependent on SSD1306 to provide. The total memory of the SSD1306 is 128 * 64 bits, and SSD1306 divide the memory into 8 pages. Each page contains 128 bytes, a total of 8 pages, which is exactly 128*64 dot matrix size.
However, because OLED cannot control one dot matrix at a time, it can only control 8 dot matrix; And it's a vertical sweep control;
Because each write is written in bytes, there is a problem, if we use the write-only mode to operate the module, then, we have to write 8 points at a time, so when we draw a point, we must figure out the current state of each bit of the byte where the point to be set is located (0/1?). Otherwise, the written data will overwrite the previous state, and the result will be that some points that do not need to be displayed are displayed, or those that should be displayed are not displayed. In the readable mode, we can read out the byte to be written first, get the current situation, and then write it into the gram after modifying the bit to be rewritten, so that it will not affect the previous situation. However, this requires the ability to read the GRAM, for 3-wire or 4-wire SPI mode, the module does not support reading, and the read->-to-> write mode is also relatively slow.
So the method we use is to create an OLED GRAM (a total of 128 bytes) inside the STM32, and at each modification, only modify the GRAM on the STM32 (actually SRAM), and after the modification, write the GRAM on the STM32 to the OLED GRAM at one time. Of course, this method also has disadvantages, that is, for those microcontrollers with very small SRAM (such as the 51 series), it is more troublesome.
Video memory of OLED
The storage format is as follows:
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127
u16 OLED_GRAM[128][8];
Update the video memory to the LCD
void OLED_Refresh_Gram(void)
{
u8 i,n;
for(i=0; i<8; i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); Set page address (0~7)
OLED_WR_Byte (0x00,OLED_CMD); Set the display position—column low address
OLED_WR_Byte (0x10,OLED_CMD); Set the display position—column height address
for(n=0; n<128; n++)OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);
}
}
SSD1306 command
1: Command 0X81: Set the contrast. Contains two bytes, the first 0X81 is the command, and the subsequent one byte is the value of the contrast to be set. The larger this value is set, the brighter the screen will be.
2: Command 0XAE/0XAF: 0XAE to turn off the display command; 0XAF to turn on the display command.
3: Command 0X8D: contains 2 bytes, the first one is the command word, the second is the set value, the second byte of BIT2 indicates the switching state of the charge pump, the bit is 1, the charge pump is turned on, and 0 is turned off. When the module is initialized, this must be enabled, otherwise you will not see the screen display.
4: Command 0XB0~B7: Used to set the page address, and the lower three digits correspond to the page address of the GRAM.
5: Command 0X00~0X0F: Used to set the lower four digits of the starting column address when displaying.
6: Command 0X10~0X1F: Used to set the start column address of the display four digits higher.
For more commands, please refer to this, it is highly recommended to see it, it is very detailed: SSD1306 (OLED driver chip) instructions in detail
After introducing the working mode and driver chip, we can start using this IIC OLED module
Code in detail
#define OLED_CMD 0 // write command
#define OLED_DATA 1 //Write data
Initialize the OLED
Initialize the SSD1306
void OLED_Init(void)
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); Enable the clock on the A port
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; Push-pull output
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; Speed 50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); Initialize the GPIO
GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7);
delay_ms(200);
OLED_WR_Byte(0xAE,OLED_CMD);//--display off
OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
OLED_WR_Byte(0x40,OLED_CMD);//--set start line address
OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
OLED_WR_Byte(0x81,OLED_CMD); // contract control
OLED_WR_Byte(0xFF,OLED_CMD);//--128
OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
OLED_WR_Byte(0x00,OLED_CMD);//
OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
OLED_WR_Byte(0x80,OLED_CMD);//
OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
OLED_WR_Byte(0x05,OLED_CMD);//
OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
OLED_WR_Byte(0xF1,OLED_CMD);//
OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
OLED_WR_Byte(0x12,OLED_CMD);//
OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
OLED_WR_Byte(0x30,OLED_CMD);//
OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
OLED_WR_Byte(0x14,OLED_CMD);//
OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel}
OLED_Clear(); Clear the screen, it is recommended to clean the screen first after each initialization is completed
Clear screen function, after clearing the screen, the whole screen is black! It's the same as not lighting up!!
void OLED_Clear(void)
{
u8 i,n;
for(i=0; i<8; i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); Set page address (0~7)
OLED_WR_Byte (0x00,OLED_CMD); Set the display position—column low address
OLED_WR_Byte (0x10,OLED_CMD); Set the display position—column height address
for(n=0; n<128; n++)OLED_WR_Byte(0,OLED_DATA);
} // Update the display
}
In the self-modulus we usually use, there are two common ways to take the modular, one is 6 * 8, and the other is 8 * 16, the first one is to take out the characters we want in a rectangular table with 8 rows and 6 columns, and the second is to take out the characters in a rectangular table with 16 rows and 8 columns. As written in the code comment below, since there are only 8 lines per page in OLED, space for the next page needs to be used. So we have the font size we usually use, of course, these are commonly used font sizes, we can also make our own favorite font size through character modulation software.
/* Displays a character at the specified location, including some characters
x:0~127
y:0~63
size: Select font 16/12*/
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{
unsigned char c=0,i=0;
c=chr-' '; The offset value can be obtained from the font pattern, the first one is ' ', and the corresponding character can be obtained by subtracting
if(x>Max_Column-1){x=0; y=y+2; } //Max_Column: Maximum column: 128; x: set the number of columns; y: Set the number of pages
if(Char_Size ==16) // In this case, the same column of two pages is required, and the dot matrix of 8*16 is required
{
OLED_Set_Pos(x,y); If x = y = 2, then set it to column 3 on page 3, note: there are only eight rows per page
for(i=0; i<8; i++)
OLED_WR_Byte(F8X16[c*16+i],OLED_DATA); By incrementing the i, the dots are drawn in a loop, and all 8 rows of the second column on page 2 are written into the data
OLED_Set_Pos(x,y+1); Since the number of dots is not enough, you need to continue the dots in column 2 on page 3
for(i=0; i<8; i++)
OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA); Continue to finish the drawing until the end of point 16
}
else
{
OLED_Set_Pos(x,y); 6x8 dot matrix, no need for other pages to continue the painting
for(i=0; i<6; i++)
OLED_WR_Byte(F6x8[c][i],OLED_DATA); In a two-dimensional array, C controls the rows and I controls the columns, so no other operations are needed to finish the drawing
}
}
The following if(x>120) is not an error, because the previous x+=8; There is an explanation in the following notes, so you can think about it.
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size) // Displays the string
{
unsigned char j=0;
while (chr[j]!='0') // Check whether the string ends
{
OLED_ShowChar(x,y,chr[j],Char_Size); Draw the characters one by one
x+=8; x is set to a column, the size of a character is 8*16, that is, the row is 16 and the column is 8, and each time it is displayed as one, you need to move 8 columns to the higher column
if(x>120){x=0; y+=2; } // The maximum is 128 columns, if it is exceeded, you need to start from the zero column again, because you need other pages to continue the painting at this time, to avoid overlapping, you need y += 2.
j++; Draw strings in a loop
}
}
2 numbers are displayed, both written in the code below, and it should be noted that the "" below represents the ASCII value of 32
m^n function
u32 oled_pow(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
Display 2 numbers
x,y: start coordinates
len: The number of digits of the number
size: the font size
mode: mode 0, fill mode; 1. Overlay mode
num: numerical value (0~4294967295);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
{
u8 t,temp;
u8 enshow=0;
for(t=0; t { temp=(num/oled_pow(10,len-t-1))%10; if(enshow==0&&t<(len-1)) { if(temp==0) { OLED_ShowChar(x+(size2/2)*t,y,' ',size2); continue; }else enshow=1; } OLED Show Char(x+(size2/2)*t,y,temp+'0',size2); } The above several are our most basic usage, some Xi want to use it to complete more different operations, the following is, before the introduction, first introduce our commonly used modeling software. PC to LCD 2002 Here's how it works! When we use it, we first open the file in the upper left corner and create a new one. Enter our width and height, 6 * 8 or 8 * 16 are based on this to take the mold, you can set the size by yourself. There's a gear-like thing in the top corner, and we need to open it once we've set the size. As shown in the figure: Once you've got everything on top, you can draw what you want. Because OLED is 128*64, our maximum size is this, we can write on 128*64, draw, etc., what comes out is a whole picture, which is also a way to fill the screen, and there is a kind of impression software in the back, which is obtained as a picture, such as some anime characters. Now that we've introduced the tooling, we're ready to move on to our operations! 1: Draw a straight line 2: Show pictures (such as some anime characters) It feels like a bit long. There are more ways to play, to update next.
Usually we use the same point as in the figure below when we want to draw a straight line, we always get a point, this is because the character size we generally use is 6 * 8 or 8 * 16, and the point size inside is not full of the whole rectangle (explained above), what we need to do is to open our character software and make the point larger!
Contact Person: Mrs. Christina
Tel: +8618922869670
Fax: 86-755-2370-9419