SPI3+DMA peripheral driver - TFTLCD initialization

foreword

(1) This series is based on STM32 project notes, covering the use of various STM32 peripherals, from shallow to deep.

(2) The MCU used by the editor is STM32F105RCT6. The project notes are based on the actual project of the editor, but the content in the blog is suitable for the students who develop various MCUs to learn and use.

learning target

There are five tasks in this chapter:

  1. Learn about the hardware interface of the TFTLCD LCD screen
  2. Learn and understand STM32 DMA driver
  3. Hardware interface initialization of TFTLCD LCD screen
  4. LCD liquid crystal initialization
  5. TFTLCD LCD screen code porting and display test

TFTLCD liquid crystal screen hardware circuit analysis

Interface description: The TFTLCD LCD screen is connected to the SPI3 interface of the microcontroller.

TFTDIO ---- PB5 SPI3-MOSI data transmission pin SPI hardware control

TFTCMD---- PB4 SPI3-MISO data/command control pin

TFTCLK ----- PB3 SPI3-SCK Data sending clock pin SPI hardware control

CS ------ PB6 chip select pin

LEDA_EN—PC10 LCD screen backlight control pin

FTFRES — PA15 LCD reset pin

Circuit design instructions:

● The hardware circuit design is based on the reference materials provided by the official LCD screen. Basically, just copy it according to the chip data

● In order to improve the refreshing efficiency of the LCD screen, we choose the SPI3 interface. single-wire mode

● DIO CLK must be fixedly connected to MOSI SCK, other pins can be connected to any IO port

TFTLCD LCD screen initialization

hal_tftlcd.c code

#include "hal_tftlcd.h"
#include "stm32F10x.h"
//#include "lcd_font.h"

//-----------------LCD端口定义---------------- 
#define LCD_SCLK_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_3)//SCL=SCLK
#define LCD_SCLK_Set() GPIO_SetBits(GPIOB,GPIO_Pin_3)

#define LCD_MOSI_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_5)//SDA=MOSI
#define LCD_MOSI_Set() GPIO_SetBits(GPIOB,GPIO_Pin_5)

#define LCD_DC_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_4)//DC
#define LCD_DC_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_4)

#define LCD_CS_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_6)//CS
#define LCD_CS_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_6)

#define LCD_RES_Clr()  GPIO_ResetBits(GPIOA,GPIO_Pin_15)//RES
#define LCD_RES_Set()  GPIO_SetBits(GPIOA,GPIO_Pin_15)

#define LCD_BLK_Clr()  GPIO_ResetBits(GPIOC,GPIO_Pin_10)//BLK
#define LCD_BLK_Set()  GPIO_SetBits(GPIOC,GPIO_Pin_10)



void hal_tftlcdConfig(void)
{
	SPI_InitTypeDef  SPI_InitStructure;
	GPIO_InitTypeDef  GPIO_InitStructure;
	DMA_InitTypeDef  DMA_InitStructure;//DMA初始化结构体

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);  //相关IO的初始化
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	//RES-PA15
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOA, &GPIO_InitStructure);	  //初始化GPIOA
	GPIO_SetBits(GPIOA,GPIO_Pin_15);
	
	//CMD-PB4
	//CS-PB6
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_6;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOB, &GPIO_InitStructure);	  //初始化GPIOA	
	GPIO_SetBits(GPIOB,GPIO_Pin_4|GPIO_Pin_6);
	
		//BLK-PC10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOC, &GPIO_InitStructure);	  //初始化GPIOA		
	GPIO_ResetBits(GPIOC,GPIO_Pin_10);
	
	//CLK-PB3
	//MOSI-PB5
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3 |GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);	
	
	/* SPI3 configuration */ 
	SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //SPI1设置为单线
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;	                     //设置SPI1为主模式
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                  //SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;	 		                   //串行时钟在不操作时,时钟为高电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;		                   //第二个时钟沿开始采样数据
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;			                     //NSS信号由软件(使用SSI位)管理
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //定义波特率预分频的值:波特率预分频值为8
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;				         //数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;						               //CRC值计算的多项式
	SPI_Init(SPI3, &SPI_InitStructure);

	//使能DMA发送
	DMA_DeInit(DMA2_Channel2); 
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR; //数据传输目标地址
																															//数据缓存地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 	//外设作为数据传输的目的地
	DMA_InitStructure.DMA_BufferSize = 1024;            //发送Buff数据大小
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //设置外设地址是否递增
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;          //设置内存地址是否递增
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据宽度为8位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;       	//内存数据宽度为8位	

	DMA_InitStructure.DMA_Mode =   DMA_Mode_Normal;                              //普通缓存模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                        //高优先级
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                 //禁止DMA2个内存相互访问
	DMA_Init(DMA2_Channel2, &DMA_InitStructure);                                 //初始化DMA,SPI在DMA1的通道2

	SPI_I2S_DMACmd(SPI3,SPI_I2S_DMAReq_Tx,ENABLE);                               /使能SPI2 DMA发送功能*/	
	SPI_Cmd(SPI3, ENABLE);//使能SPI2
}

// SPI3 DMA发送
void DMA_SPI3_TX(unsigned char *buffer,unsigned short len)
{
	DMA2->IFCR |=(0xf<<4);    //清除通道2上面所有的标志位
	DMA2_Channel2->CNDTR=len; //设置要传输的数据长度
	DMA2_Channel2->CMAR=(u32)buffer; //设置RAM缓冲区地址
	DMA2_Channel2->CCR|=0x1;   ///启动DMA
        while(!(DMA2->ISR&(1<<5)));///等待数据数据传输完成
	DMA2_Channel2->CCR &=(uint32_t)~0x1;//关闭DMA
}

void LCD_Writ_Bus(unsigned char dat) 
{	
	LCD_CS_Clr();
	DMA_SPI3_TX(&dat,1);
}

/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA8(unsigned char dat)
{
	LCD_Writ_Bus(dat);
}


/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA(unsigned short dat)
{
	unsigned char d[2];
	d[0] = dat>>8;
	d[1] = dat;
	DMA_SPI3_TX(&d[0],2);
}


/******************************************************************************
      函数说明:LCD写入命令
      入口数据:dat 写入的命令
      返回值:  无
******************************************************************************/
void LCD_WR_REG(unsigned char dat)
{
	LCD_DC_Clr();//写命令
	LCD_Writ_Bus(dat);
	LCD_DC_Set();//写数据
}

void hal_Oled_Display_on(void)
{
	LCD_BLK_Set();
}

void hal_Oled_Display_off(void)
{
	LCD_BLK_Clr();
}
///

void hal_oled_RestH(void)
{
	LCD_RES_Set();
}
void hal_oled_RestL(void)
{
	LCD_RES_Clr();
}

hal_tftlcd.h code

#ifndef ____HAL_TFTLCD_H_
#define ____HAL_TFTLCD_H_

void hal_tftlcdConfig(void);

void LCD_WR_REG(unsigned char dat);
void LCD_WR_DATA8(unsigned char dat);
void LCD_WR_DATA(unsigned short dat);
void DMA_SPI3_TX(unsigned char *buffer,unsigned short len);

void hal_Oled_Display_on(void);
void hal_Oled_Display_off(void);
void hal_oled_RestH(void);
void hal_oled_RestL(void);
#endif

code analysis

hal_tftlcd.c includes

● TFTLCD liquid crystal screen communication interface initialization

● TFTLCD send function through DMA data

● Other port control functions of TFTLCD LCD screen

TFTLCD SP3 interface initialization process

➢ Define the interface of TFTLCD communication

//-----------------LCD端口定义---------------- 
#define LCD_SCLK_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_3)//SCL=SCLK
#define LCD_SCLK_Set() GPIO_SetBits(GPIOB,GPIO_Pin_3)

#define LCD_MOSI_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_5)//SDA=MOSI
#define LCD_MOSI_Set() GPIO_SetBits(GPIOB,GPIO_Pin_5)

#define LCD_DC_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_4)//DC
#define LCD_DC_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_4)

#define LCD_CS_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_6)//CS
#define LCD_CS_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_6)

#define LCD_RES_Clr()  GPIO_ResetBits(GPIOA,GPIO_Pin_15)//RES
#define LCD_RES_Set()  GPIO_SetBits(GPIOA,GPIO_Pin_15)

#define LCD_BLK_Clr()  GPIO_ResetBits(GPIOC,GPIO_Pin_10)//BLK
#define LCD_BLK_Set()  GPIO_SetBits(GPIOC,GPIO_Pin_10)

➢ Turn on the relevant clock

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);	
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);  //相关IO的初始化

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//打开端口重映射,PB3、PB4端口默认的功能不是SPI3,是JTAG,所以要对端口重映射,让它们具备SPI3的功能

➢ Initialize the GPIO ports related to TFTLCD LCD screen and SPI3

	//CMD-PB4
	//CS-PB6
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_6;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOB, &GPIO_InitStructure);	  //初始化GPIOA	
	GPIO_SetBits(GPIOB,GPIO_Pin_4|GPIO_Pin_6);
	
		//BLK-PC10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOC, &GPIO_InitStructure);	  //初始化GPIOA		
	GPIO_ResetBits(GPIOC,GPIO_Pin_10);
	
	//CLK-PB3
	//MOSI-PB5
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3 |GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);	

➢ Initialize SPI3 related parameters

/* SPI3 configuration */ 
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; //SPI1设置为单线
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;	                     //设置SPI1为主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                  //SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;	  //串行时钟在不操作时,时钟为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;		 //第二个时钟沿开始采样数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;	 //NSS信号由软件(使用SSI位)管理
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //定义波特率预分频的值:波特率预分频值为8
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7;			 //CRC值计算的多项式
SPI_Init(SPI3, &SPI_InitStructure);

➢ Configure SPI3 DMA function.

DMA introduction:

Direct memory access (DMA) is used to provide high-speed data transfers between peripherals and memory or between memory and memory. Data can be moved quickly through DMA without CPU intervention, which frees up CPU resources for other operations. The two DMA controllers have 12 channels (7 channels for DMA1 and 5 channels for DMA2), and each channel is dedicated to managing memory access requests from one or more peripherals. There is also an arbiter to coordinate the priority of each DMA request.

In short, when our functions involve data transmission functions, such as ADC, DMA, USART, etc., in order to make data transmission faster, DMA function can be added to data transmission to enable DMA transmission or reception.

DMA1 channel correspondence table:

DMA2 channel correspondence table:

Our project uses the sending function of DMA2, because we only need to send data to the TFTLCD display.

//使能DMA发送
DMA_DeInit(DMA2_Channel2); 
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI3->DR; //数据传输目标地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 	数据传输方向,从内存读取发送到外设
DMA_InitStructure.DMA_BufferSize = 1024;            //发送Buff数据大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //设置外设地址是否递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //设置内存地址是否递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据宽度为8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存数据宽度为8位	

DMA_InitStructure.DMA_Mode =   DMA_Mode_Normal;                         //普通缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                        //高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;            //禁止DMA2个内存相互访问
DMA_Init(DMA2_Channel2, &DMA_InitStructure);        //初始化DMA,SPI在DMA1的通道2

SPI_I2S_DMACmd(SPI3,SPI_I2S_DMAReq_Tx,ENABLE); /使能SPI2 DMA发送功能*/	
SPI_Cmd(SPI3, ENABLE);//使能SPI2

SPI3 DMA data sending function
// SPI3 DMA发送
void DMA_SPI3_TX(unsigned char *buffer,unsigned short len)
{
	DMA2->IFCR |=(0xf<<4);    //清除通道2上面所有的标志位
	DMA2_Channel2->CNDTR=len; //设置要传输的数据长度
	DMA2_Channel2->CMAR=(u32)buffer; //设置RAM缓冲区地址
	DMA2_Channel2->CCR|=0x1;   ///启动DMA
        while(!(DMA2->ISR&(1<<5))) ; ///等待数据数据传输完成
	DMA2_Channel2->CCR &=(uint32_t)~0x1;//关闭DMA
}
void LCD_Writ_Bus(unsigned char dat) 
{	
	LCD_CS_Clr();
	DMA_SPI3_TX(&dat,1);
}

Other LCD pin control functions
void hal_Oled_Display_on(void)
{
	LCD_BLK_Set();
}

void hal_Oled_Display_off(void)
{
	LCD_BLK_Clr();
}

void hal_oled_RestH(void)
{
	LCD_RES_Set();
}
void hal_oled_RestL(void)
{
	LCD_RES_Clr();
}

LCD command and data sending function
/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA8(unsigned char dat)
{
	DMA_SPI3_TX(dat);
}

/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA(unsigned short dat)
{
	unsigned char d[2];
	d[0] = dat>>8;
	d[1] = dat;
	DMA_SPI3_TX(&d[0],2);
}


/******************************************************************************
      函数说明:LCD写入命令
      入口数据:dat 写入的命令
      返回值:  无
******************************************************************************/
void LCD_WR_REG(unsigned char dat)
{
	LCD_DC_Clr();//写命令
	LCD_Writ_Bus(dat);
	LCD_DC_Set();//写数据
}

The above content is the content of hal_tftlcd.c and hal_tftlcd.h files, which are related to the initialization function of stm32 peripheral DMA SPI3.

The following content will be the contents of mt_tftlcd.c and mt_tftlcd.h files, which are related to the initialization content of the LCD screen of the module. The initialization of the LCD screen module is written based on the initialization function of the stm32 peripherals, so the initialization functions of the module are all It is composed of calling the peripheral initialization function, the bottom layer is the initialization function of the stm32 peripheral, the initialization function and code of the module, relatively speaking, it is the application layer code. Therefore, the mt file is the application layer driver code, and the hal file is the underlying driver code.

LCD screen initialization and LCD fill function

For the LCD driver and other LCD-related driver functions, we can directly transplant them from the official reference routines and use them without in-depth research.

void mt_tftlcd_init(void);

LCD_Fill(unsigned short xsta,unsigned short ysta,unsigned short xend,unsigned short yend,unsigned short color);

Note: Both the underlying driver code and the application layer driver code are programs written based on configuring the STM32 registers. In-depth research is not required, and it can be called; the application layer driver is programmed based on the underlying driver.

mt_tftlcd.c code

#include "mt_Tftlcd.h"
#include "hal_tftlcd.h"

static void hal_tftlcd_Delay(unsigned int de);
unsigned char ColorBuf[640];

void mt_tftlcd_init(void)
{
  		hal_tftlcdConfig();//初始化GPIO
		hal_tftlcd_Delay(10000);
		hal_oled_RestL();//复位
		hal_tftlcd_Delay(10000);
		hal_oled_RestH();
		hal_tftlcd_Delay(100);

	//************* Start Initial Sequence **********//
		LCD_WR_REG(0x11);
		hal_tftlcd_Delay(10000);//delay_ms(100); //Delay 120ms
		LCD_WR_REG(0X36);// Memory Access Control
		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(0X03);   //12bit
		LCD_WR_DATA8(0X05);  
		//--------------------------------ST7789S Frame rate setting-------------------------

		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);
		//---------------------------------ST7789S Power setting-----------------------------

		LCD_WR_REG(0xbb);
		LCD_WR_DATA8(0x35);

		LCD_WR_REG(0xc0);
		LCD_WR_DATA8(0x2c);

		LCD_WR_REG(0xc2);
		LCD_WR_DATA8(0x01);

		LCD_WR_REG(0xc3);
		LCD_WR_DATA8(0x13);

		LCD_WR_REG(0xc4);
		LCD_WR_DATA8(0x20);

		LCD_WR_REG(0xc6);
		LCD_WR_DATA8(0x0f);

		LCD_WR_REG(0xca);
		LCD_WR_DATA8(0x0f);

		LCD_WR_REG(0xc8);
		LCD_WR_DATA8(0x08);

		LCD_WR_REG(0x55);
		LCD_WR_DATA8(0x90);

		LCD_WR_REG(0xd0);
		LCD_WR_DATA8(0xa4);
		LCD_WR_DATA8(0xa1);
		//--------------------------------ST7789S gamma setting------------------------------
		LCD_WR_REG(0xe0);
		LCD_WR_DATA8(0xd0);
		LCD_WR_DATA8(0x00);
		LCD_WR_DATA8(0x06);
		LCD_WR_DATA8(0x09);
		LCD_WR_DATA8(0x0b);
		LCD_WR_DATA8(0x2a);
		LCD_WR_DATA8(0x3c);
		LCD_WR_DATA8(0x55);
		LCD_WR_DATA8(0x4b);
		LCD_WR_DATA8(0x08);
		LCD_WR_DATA8(0x16);
		LCD_WR_DATA8(0x14);
		LCD_WR_DATA8(0x19);
		LCD_WR_DATA8(0x20);
		LCD_WR_REG(0xe1);
		LCD_WR_DATA8(0xd0);
		LCD_WR_DATA8(0x00);
		LCD_WR_DATA8(0x06);
		LCD_WR_DATA8(0x09);
		LCD_WR_DATA8(0x0b);
		LCD_WR_DATA8(0x29);
		LCD_WR_DATA8(0x36);
		LCD_WR_DATA8(0x54);
		LCD_WR_DATA8(0x4b);
		LCD_WR_DATA8(0x0d);
		LCD_WR_DATA8(0x16);
		LCD_WR_DATA8(0x14);
		LCD_WR_DATA8(0x21);
		LCD_WR_DATA8(0x20);
		LCD_WR_REG(0x29);
		hal_Oled_Display_on();//打开背光

		LCD_Fill(0,0,LCD_W,LCD_H,RED);
} 

/******************************************************************************
      函数说明:设置起始和结束地址
      入口数据:x1,x2 设置列的起始和结束地址
                y1,y2 设置行的起始和结束地址
      返回值:  无
******************************************************************************/
void LCD_Address_Set(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2)
{
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1+2);
		LCD_WR_DATA(x2+2);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1+1);
		LCD_WR_DATA(y2+1);
		LCD_WR_REG(0x2c);//储存器写
}

static void hal_tftlcd_Delay(unsigned int de)
{
	while(de--);
}

void LCD_Fill(unsigned short xsta,unsigned short ysta,unsigned short xend,unsigned short yend,unsigned short color)
{          
	unsigned short i; 
	LCD_Address_Set(xsta,ysta,xend-1,yend-1);//设置显示范围
	for(i=0;i<xend;i++)
  {
		ColorBuf[i++] = color>>8;
		ColorBuf[i] = color;
	}
	for(i=ysta;i<yend*2;i++)
	{		
		 DMA_SPI3_TX(ColorBuf,xend);
	}	
}

mt_Tftlcd.h code

#ifndef ____MT_TFTLCD_H_
#define ____MT_TFTLCD_H_

#define USE_HORIZONTAL 3  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏

#if USE_HORIZONTAL==0||USE_HORIZONTAL==1

#define LCD_W 240
#define LCD_H 320

#else
#define LCD_W 320
#define LCD_H 240
#endif

///RGB565
#define WHITE         	 0xFFFF
#define BLACK         	 0x0000	  
#define BLUE           	 0x001F  
#define BRED                  0XF81F
#define GRED 		 0XFFE0
#define GBLUE	         0X07FF
#define RED           	         0xF800
#define MAGENTA       	 0xF81F
#define GREEN         	 0x07E0
#define CYAN          	 0x7FFF
#define YELLOW        	 0xFFE0
#define BROWN 			     0XBC40 //棕色
#define BRRED 			     0XFC07 //棕红色
#define GRAY  			     0X8430 //灰色
#define DARKBLUE      	 0X01CF	//深蓝色
#define LIGHTBLUE      	 0X7D7C	//浅蓝色  
#define GRAYBLUE       	 0X5458 //灰蓝色
#define LIGHTGREEN     	 0X841F //浅绿色
#define LGRAY 			     0XC618 //浅灰色(PANNEL),窗体背景色
#define LGRAYBLUE        0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE           0X2B12 //浅棕蓝色(选择条目的反色)

enum
{
	FORTSIZE_12 = 12,
	FORTSIZE_16 = 16,	
	FORTSIZE_24 = 24,
	FORTSIZE_32 = 32,	
	FORTSIZE_48 = 48,	
};

#define HUE_LCD_FONT     WHITE
#define HUE_LCD_BACK     BLACK//YELLOW  //BLACK//
#define HUE_FONT_BACK    GRAY

void mt_tftlcd_init(void);
void LCD_Fill(unsigned short xsta,unsigned short ysta,unsigned short xend,unsigned short yend,unsigned short color);
#endif

Functional Test Verification

The LCD screen displays yellow on the full screen, indicating that the drive is complete and OK.

おすすめ

転載: blog.csdn.net/weixin_62261692/article/details/132550504