[embedded] STM32 OLED screen display based on SPI communication protocol

1, SPI protocol and OLED introduction

1. Introduction to SPI protocol

SPI(Serial peripheral interface), that is, serial peripheral interface, is a communication protocol based on high-speed full duplex bus, which was first defined by Motorola on its MC68HCxx Series MCU. (high speed, full duplex, really powerful) is widely used between ADC, LCD and MCU.

Like the previous study of I2C and USART, learning a protocol is still analyzed from two levels: the physical layer and the protocol layer.

physical layer

SPI communication requires 4 lines: 3 buses and 1 chip selection

  SPI still follows the master-slave mode. The three buses are SCK, MOSI and MISO respectively. The chip selection line is NSS (active at low level). SPI protocol is applicable to the working scenario of one master and multiple slaves:

(1) nSS(Slave Select): chip select signal line, used to select SPI slave equipment. Each slave device independently owns this nSS signal line and occupies one pin of the host. Other buses of the equipment are connected in parallel to the SPI host, that is, no matter how many slave devices, these three buses are used together. When the nSS pin on the slave is set low, it indicates that the slave is selected by the host.
(2) SCK(Serial Clock): clock signal line, used for communication data synchronization. The clock signal is generated by the communication host, which determines the communication rate of SPI.
(3) MOSI(Master Ouput Slave Input): Master (data) output / slave (data) input pin, that is, this signal line transmits data from master to slave.
(4) MISO(Master Input Slave Ouput): host (data) input / slave (data) output pin, that is, this signal line transmits data from slave to host. The master and slave transmit data through two signal lines, so it is naturally full duplex communication. In the previous I2C communication, data was only transmitted on one SDA line, and the master-slave data interaction can only use half duplex.

protocol layer


The above is the SPI communication sequence diagram. nSS, SCK and MOSI signals are generated by the host, and MISO signals are generated by the slave. On the premise that the nSS is low, the MOSI and MISO signals are valid, and the MOSI and MISO transmit one bit of data in each clock cycle.
Similar to I2C communication, SPI communication also requires communication start / end signal, valid data and synchronization clock.

Start / end signal of communication

The change of nSS signal from high level to low level in the figure is the start signal of SPI communication. Conversely, the change of nSS signal from low level to high level is the end signal of SPI communication. This is much simpler than I2C. When the slave detects that its nSS pin is pulled low, it knows that it has been selected by the host and is ready to communicate with the host.

Collection of valid data

The data acquisition of SPI communication is a relatively complex link, not to mention others. The above figure is an example:
The red box in the figure is the time point when the effective data is collected. The pulse signal where "CPOL = 0" represents the SCK used for data synchronization. The data on MOSI and MISO lines transmits one bit of data in each SCK clock cycle. Note that the data input / output can be carried out at the same time.
   as can be seen from the figure, when the SCK is an odd (correction: it should be an even number here) edge (here the edge is a falling edge), the data is effectively sampled, that is, at this time, the data of MISO and MOSI are valid, the high level represents data 1, the low level represents data 0, and the data is not valid at other times, It can be understood as preparing for the next MISO and MOSI data transmission.
   the SPI protocol does not specify whether the high bit comes first or the low bit comes first in data transmission, but the data should be correctly transmitted in the master-slave machine. Naturally, both parties should agree first, and the high bit first (MSB) mode is generally adopted.

The complete sequence diagram is as follows:

2. Introduction to OLED display

OLED is organic light emitting diode, also known as organic electroluminescence display (OELD). OLED is considered as the emerging application technology of the next generation of flat panel display because of its excellent characteristics such as self luminescence, no backlight, high contrast, thin thickness, wide viewing angle, fast reaction speed, flexible panel, wide temperature range, simple structure and manufacturing process.

LCD needs backlight, but OLED does not because it is self luminous. This same display, OLED effect is better. With the current technology, the size of OLED is still difficult to be large-scale, but the resolution can be very high.

We use ALINETEK's OLED display module, which has the following characteristics:
1) The module is available in monochrome and two colors. The monochrome is pure blue, while the two colors are yellow and blue.
2) The size is small, the display size is 0.96 inches, while the size of the module is only 27mmx26mm.
3) High resolution, the resolution of the module is 128x64.
4) Multiple interface modes. The module provides a total of 5 interfaces, including 6800 and 8080 parallel interface modes, 3-wire or 4-wire through SPI interface mode and IIC interface mode (OLED can be controlled by only 2 wires).
5) Without high voltage, it can work directly connected to 3.3V.
For the introduction of 0.96 inch OLED display, please refer to the link:

http://www.lcdwiki.com/zh/0.96inch_SPI_OLED_Module
OLED pin connection

2, Experiment of displaying individual student number and name

1. Subject requirements

Understand the principle of OLED screen display and Chinese character dot matrix coding, and use the SPI or IIC interface of STM32F103 to realize the following functions:
Display your student number and name;

2. Code part

1. Complete code

Link: https://pan.baidu.com/s/1vawtPaudZmzuWdMjImrF3Q
Extraction code: qwer

2. Text mold

Font software download
Extraction code: qwer
1. Open the software, select options and configure font options

2. Enter the data to be displayed and click generate font

3. Modification procedure
Content display TEST_MainPage function - > test. C file

void TEST_MainPage(void)
{	
//	GUI_ShowString(28,0,"yao",16,1);// English name
	GUI_ShowCHinese(28,20,16,"Yao Sitong",1);//Chinese name
	GUI_ShowString(4,48,"631907030429",16,1);//Digital detail
	delay_ms(1500);		
	delay_ms(1500);
}

Add font to oledfont.h

Main function modification

int main(void)
{	
	delay_init();	    	       //Delay function initialization	  
	OLED_Init();			         //Initialize OLED  
	OLED_Clear(0);             //Clear screen (all black)
	while(1) 
	{	
		TEST_MainPage();         //Interface display
	}
}

4. Compile and burn
Compilation results

Burn

3. Operation results

3, Displays the temperature and humidity collected by AHT20

1. Complete code

https://pan.baidu.com/s/1fwpkkrHpujE57SGZBOXlmQ
Extraction code: qwer

2. Code modification

main.c

#include "delay.h"
#include "usart.h"
#include "bsp_i2c.h"
#include "sys.h"
 
#include "oled.h"
#include "gui.h"
#include "test.h"
 
int main(void)
{	
	delay_init();	    	       //Delay function initialization    	  
	uart_init(115200);	 
	IIC_Init();
		  
	NVIC_Configuration(); 	   //Set NVIC interrupt packet 2: 2-bit preemption priority and 2-bit response priority 	
	OLED_Init();			         //Initialize OLED  
	OLED_Clear(0); 
	while(1)
	{
		//printf("temperature and humidity display");
		read_AHT20_once();
		OLED_Clear(0); 
		delay_ms(1500);
  }
}

Temperature and humidity display read_AHT20 function - > BSP_ I2C. C file

void read_AHT20(void)
{
	uint8_t   i;
	for(i=0; i<6; i++)
	{
		readByte[i]=0;
	}

	//-------------
	I2C_Start();

	I2C_WriteByte(0x71);
	ack_status = Receive_ACK();
	readByte[0]= I2C_ReadByte();
	Send_ACK();

	readByte[1]= I2C_ReadByte();
	Send_ACK();

	readByte[2]= I2C_ReadByte();
	Send_ACK();

	readByte[3]= I2C_ReadByte();
	Send_ACK();

	readByte[4]= I2C_ReadByte();
	Send_ACK();

	readByte[5]= I2C_ReadByte();
	SendNot_Ack();
	//Send_ACK();

	I2C_Stop();

	//--------------
	if( (readByte[0] & 0x68) == 0x08 )
	{
		H1 = readByte[1];
		H1 = (H1<<8) | readByte[2];
		H1 = (H1<<8) | readByte[3];
		H1 = H1>>4;

		H1 = (H1*1000)/1024/1024;

		T1 = readByte[3];
		T1 = T1 & 0x0000000F;
		T1 = (T1<<8) | readByte[4];
		T1 = (T1<<8) | readByte[5];

		T1 = (T1*2000)/1024/1024 - 500;

		AHT20_OutData[0] = (H1>>8) & 0x000000FF;
		AHT20_OutData[1] = H1 & 0x000000FF;

		AHT20_OutData[2] = (T1>>8) & 0x000000FF;
		AHT20_OutData[3] = T1 & 0x000000FF;
	}
	else
	{
		AHT20_OutData[0] = 0xFF;
		AHT20_OutData[1] = 0xFF;

		AHT20_OutData[2] = 0xFF;
		AHT20_OutData[3] = 0xFF;
		printf("lyy");

	}
	/*Display the collected temperature and humidity through the serial port
	printf("\r\n");
	printf("Temperature:% d%d.%d",T1/100,(T1/10)%10,T1%10);
	printf("Humidity:% d%d.%d",H1/100,(H1/10)%10,H1%10);
	printf("\r\n");*/
	t=T1/10;
	t1=T1%10;
	a=(float)(t+t1*0.1);
	h=H1/10;
	h1=H1%10;
	b=(float)(h+h1*0.1);
	sprintf(strTemp,"%.1f",a);   //Call the Sprintf function to format the temperature data of DHT11 into the string array variable strTemp  
    sprintf(strHumi,"%.1f",b);    //Call the Sprintf function to format the humidity data of DHT11 into the string array variable strHumi  
	GUI_ShowCHinese(16,00,16,"Temperature and humidity display",1);
	GUI_ShowCHinese(16,20,16,"temperature",1);
	GUI_ShowString(53,20,strTemp,16,1);
	GUI_ShowCHinese(16,38,16,"humidity",1);
	GUI_ShowString(53,38,strHumi,16,1);
	delay_ms(1500);		
	delay_ms(1500);
}


3. Result display

Because he is too poor to buy a temperature sensor, he can only display the air

4, Slide up and down or left and right to display long characters

1. Complete code

https://pan.baidu.com/s/1KhdrhXcBWLVsky-pVAXH_A
Extraction code: qwer

2. Main code

main.c

#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "gui.h"
#include "test.h"
int main(void)
{	
	delay_init();	    	       //Delay function initialization	  
	NVIC_Configuration(); 	   //Set NVIC interrupt packet 2: 2-bit preemption priority and 2-bit response priority 	
	OLED_Init();			         //Initialize OLED  
	OLED_Clear(0);             //Clear screen (all black)
	OLED_WR_Byte(0x2E,OLED_CMD);        //Turn off scrolling
  OLED_WR_Byte(0x27,OLED_CMD);        //Scroll horizontally left or right 26 / 27
  OLED_WR_Byte(0x00,OLED_CMD);        //virtual byte
	OLED_WR_Byte(0x00,OLED_CMD);        //Start page 0
	OLED_WR_Byte(0x07,OLED_CMD);        //Rolling interval
	OLED_WR_Byte(0x07,OLED_CMD);        //Termination page 7
	OLED_WR_Byte(0x00,OLED_CMD);        //virtual byte
	OLED_WR_Byte(0xFF,OLED_CMD);        //virtual byte
	TEST_MainPage();
	OLED_WR_Byte(0x2F,OLED_CMD);        //Turn on scrolling
	while(1) 
	{	
		
		
	}
}

Modify test in text.c_ Mainpage function

Add font data

3. Operation results

5, Summary

After these three experiments, I have a deeper understanding of embedded applications. In the future, I can display more things through OLED screen, which can be displayed to others. In the experiment, carefully wiring and reading the code can be completed. Be careful when taking the font. Different methods will be different, otherwise the correct words will not be displayed.

Reference blog

[embedded 16] STM32+OLED screen display application example

OLED display based on SPI protocol

https://blog.csdn.net/qq_43279579/article/details/111414037

Tags: stm32 ARM

Posted on Fri, 26 Nov 2021 23:12:59 -0500 by osram