Based on stm32 IoT development board (2)--LCD screen

Based on stm32 IoT development board (2)-LCD screen

  • LCD application display:

LCD screen application


insert image description here

1 Overview

  • Screen size is 1.3 inches, resolution 240*240, color format RGB565, driver IC: ST7789VW;
  • Large viewing angle: greater than 160° (a screen with the largest viewing angle in the display);
  • Wide voltage power supply (3V~5V), compatible with 3.3V and 5V level logic, no need for level conversion chips;
  • Adopt 7-wire SPI interface;
  • The working temperature range is industrial grade (-20℃~60℃);
  • Military-grade process standards, long-term stable work;

insert image description here

  • Hardware interface:
pin illustrate
LEDK PB0 Backlight
CS PA4 Chip Select
SCL PA5 clock
SDA PA7 host output
RES PB1 reset pin (level reset)
D/C PC4 data command selection pin

2. Communication protocol

  ST7789VW is a microcontroller/driver for 262K color graphic TFT-LCD. It consists of 720 source lines and 320 gate line driver circuits. The chip can be directly connected to an external microprocessor and accepts 8-bit/9-bit/16-bit/18-bit parallel interfaces. Display data can be stored in 240x320x18-bit on-chip display data RAM. It can perform display data RAM read/write operations without an external operating clock to minimize power consumption. Furthermore, since circuits necessary for driving liquid crystals with a power supply are integrated; a display system with a minimum of components can be manufactured.

2.1 SPI interface timing

  This time the LCD screen is driven by SPI timing, and the timing diagram is as follows:
insert image description here
  data is sampled on the rising edge, and data is sent on the falling edge.
  The 4-wire serial interface includes serial clock SCLK, serial data SDIN, data command selection D/C, and chip selection CS.

u8 SPI_WriteReadByte(u8 dat_tx)
{
    
    
	u8 data_rx=0;
	SPI_CLK=0;//空闲电平为低电平
	for(i=0;i<8;i++)
	{
    
    
		SPI_CLK=0;//开始发送数据(主机和从机都发送数据)
		if(dat_tx&0x80)SPI_MOSI=1;
		else SPI_MOSI=0;
		SPI_CLK=1;//数据发送完成,开始读取数据
		dat_tx<<=1;//准备发送下一位数据
		//0x23--- 0010 0011
		data_rx<<=1;//默认读取到的数据为0
		if(SPI_MISO)data_rx=data_rx|0x01;
	}
	SPI_CLK=0;//空闲电平为低电平
	return data_rx;
}

About SPI hardware configuration reference: STM32 SPI hardware configuration

2.2 Write data and write command

  When the SPI interface is used to drive, the D/C pin is used as a data command selection pin. When D/C=0, read and write commands, and when D/C=1, read and write data.

/************************************************************
函数说明:LCD写入数据
入口数据:dat 写入的数据
返回值:  无
**************************************************************/
void LCD_WR_DATA(u16 dat)
{
    
    
    OLED_CS(0);
	OLED_DC_Set();//写数据
	LCD_Writ_Bus(dat>>8);
	LCD_Writ_Bus(dat);
    OLED_CS(1);
}

/****************************************************
函数说明:LCD写入命令
入口数据:dat 写入的命令
返回值:  无
*****************************************************/
void LCD_WR_REG(u8 dat)
{
    
    
    OLED_CS(0);
	OLED_DC_Clr();//写命令
	LCD_Writ_Bus(dat);
    OLED_CS(1);
}

3. Introduction to common commands

  (1) Set the screen scanning direction 0x36
insert image description here

  • Parameter description:
    insert image description here
      (2) Set the column (Column) address 0x2A

  The 0x2A command is used to set the start address and end address of the column, XS<=XE.
insert image description here
  (3) Set row (ROW) address 0x2B

  The 0x2B command is used to set the start address and end address of the line, YS<=YE.
insert image description here
  (4) Write GRAM command 0x2C
  This command is used to transfer data from MCU to frame memory. After accepting this command, the column register and page register will be reset to the starting column/starting page location. The location of the start column/start page varies according to the MADCTL setting. Frame writing can be stopped by sending any other command.
insert image description here

4. ST7789 driver sequence

void Lcd_Init(void)
{
    
    
	OLED_RST_Clr();
	Delay_Ms(200);
	OLED_RST_Set();
	Delay_Ms(20);  
  //************* Start Initial Sequence **********// 
  LCD_WR_REG(0x36);
  if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);//横屏
  else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);//横屏
  else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);//竖屏
  else LCD_WR_DATA8(0xA0);//竖屏

  LCD_WR_REG(0x3A); 
  LCD_WR_DATA8(0x05);

  LCD_WR_REG(0xB2);
  LCD_WR_DATA8(0x0C);
  LCD_WR_DATA8(0x0C);
  LCD_WR_DATA8(0x00);
  LCD_WR_DATA8(0x33);
  LCD_WR_DATA8(0x33); 

  LCD_WR_REG(0xB7); 
  LCD_WR_DATA8(0x35);  

  LCD_WR_REG(0xBB);
  LCD_WR_DATA8(0x19);

  LCD_WR_REG(0xC0);
  LCD_WR_DATA8(0x2C);

  LCD_WR_REG(0xC2);
  LCD_WR_DATA8(0x01);

  LCD_WR_REG(0xC3);
  LCD_WR_DATA8(0x12);   

  LCD_WR_REG(0xC4);
  LCD_WR_DATA8(0x20);  

  LCD_WR_REG(0xC6); 
  LCD_WR_DATA8(0x0F);    

  LCD_WR_REG(0xD0); 
  LCD_WR_DATA8(0xA4);
  LCD_WR_DATA8(0xA1);

  LCD_WR_REG(0xE0);
  LCD_WR_DATA8(0xD0);
  LCD_WR_DATA8(0x04);
  LCD_WR_DATA8(0x0D);
  LCD_WR_DATA8(0x11);
  LCD_WR_DATA8(0x13);
  LCD_WR_DATA8(0x2B);
  LCD_WR_DATA8(0x3F);
  LCD_WR_DATA8(0x54);
  LCD_WR_DATA8(0x4C);
  LCD_WR_DATA8(0x18);
  LCD_WR_DATA8(0x0D);
  LCD_WR_DATA8(0x0B);
  LCD_WR_DATA8(0x1F);
  LCD_WR_DATA8(0x23);

  LCD_WR_REG(0xE1);
  LCD_WR_DATA8(0xD0);
  LCD_WR_DATA8(0x04);
  LCD_WR_DATA8(0x0C);
  LCD_WR_DATA8(0x11);
  LCD_WR_DATA8(0x13);
  LCD_WR_DATA8(0x2C);
  LCD_WR_DATA8(0x3F);
  LCD_WR_DATA8(0x44);
  LCD_WR_DATA8(0x51);
  LCD_WR_DATA8(0x2F);
  LCD_WR_DATA8(0x1F);
  LCD_WR_DATA8(0x1F);
  LCD_WR_DATA8(0x20);
  LCD_WR_DATA8(0x23);
  LCD_WR_REG(0x21); 
  LCD_WR_REG(0x11); 
  LCD_WR_REG(0x29);//开启显示 
  LCD_Clear(WHITE);//清屏
  OLED_BLK_Set();//开背光 
} 

5. LCD screen example

5.1 Example of horizontal and vertical screen configuration

  To realize the effect of horizontal screen and vertical screen, you can set the screen scanning direction register 0x36.

#define USE_HORIZONTAL 0  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏
/******************************************************************************
函数说明:设置起始和结束地址
入口数据:x1,x2 设置列的起始和结束地址
          y1,y2 设置行的起始和结束地址
返回值:  无
******************************************************************************/
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
{
    
    
	if(USE_HORIZONTAL==0)
	{
    
    
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1);
		LCD_WR_DATA(x2);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1);
		LCD_WR_DATA(y2);
		LCD_WR_REG(0x2c);//储存器写
	}
	else if(USE_HORIZONTAL==1)
	{
    
    
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1);
		LCD_WR_DATA(x2);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1+80);
		LCD_WR_DATA(y2+80);
		LCD_WR_REG(0x2c);//储存器写
	}
	else if(USE_HORIZONTAL==2)
	{
    
    
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1);
		LCD_WR_DATA(x2);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1);
		LCD_WR_DATA(y2);
		LCD_WR_REG(0x2c);//储存器写
	}
	else
	{
    
    
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1+80);
		LCD_WR_DATA(x2+80);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1);
		LCD_WR_DATA(y2);
		LCD_WR_REG(0x2c);//储存器写
	}
}

5.2 Picture display

/******************************************************************************
函数说明:显示图片
入口数据:x1,y1    起点坐标
          width,height --图片宽高
          bmp --要显示的图片内容
返回值:  无
******************************************************************************/
void LCD_ShowPicture(u16 x1,u16 y1,u16 width,u16 height,u8*bmp)
{
    
    
    int i;
    LCD_WR_REG(0x2a);//列地址设置
    LCD_WR_DATA(x1);
    LCD_WR_DATA(x1+width-1);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1);
    LCD_WR_DATA(y1+height-1);
		LCD_WR_REG(0x2c);//储存器写
		for(i=0;i<width*height;i++)
	  {
    
     	
			LCD_WR_DATA8(bmp[i*2]);	 
			LCD_WR_DATA8(bmp[i*2+1]);			
	  }
    LCD_WR_REG(0x2a);//列地址设置	
		LCD_WR_DATA(0);
    LCD_WR_DATA(LCD_W);
    LCD_WR_REG(0x2b);//行地址设置
    LCD_WR_DATA(0);
    LCD_WR_DATA(LCD_H);
}

Guess you like

Origin blog.csdn.net/weixin_44453694/article/details/130669454