Controlador periférico SPI3+DMA - Inicialización TFTLCD

prefacio

(1) Esta serie se basa en las notas del proyecto STM32 y cubre el uso de varios periféricos STM32, desde superficiales hasta profundos.

(2) La MCU utilizada por el editor es STM32F105RCT6. Las notas del proyecto se basan en el proyecto real del editor, pero el contenido del blog es adecuado para que los estudiantes que desarrollan varias MCU las aprendan y utilicen.

objetivo de aprendizaje

Hay cinco tareas en este capítulo:

  1. Conozca la interfaz de hardware de la pantalla LCD TFTLCD
  2. Aprenda y comprenda el controlador STM32 DMA
  3. Inicialización de la interfaz de hardware de la pantalla LCD TFTLCD
  4. Inicialización de cristal líquido LCD
  5. Prueba de visualización y transferencia de código de pantalla LCD TFTLCD

Análisis de circuito de hardware de pantalla de cristal líquido TFTLCD

Descripción de la interfaz: La pantalla LCD TFTLCD está conectada a la interfaz SPI3 del microcontrolador.

TFTDIO ---- PB5 SPI3-MOSI pin de transmisión de datos control de hardware SPI

TFTCMD---- PB4 SPI3-MISO pin de control de datos/comandos

TFTCLK ----- PB3 SPI3-SCK Envío de datos pin de reloj control de hardware SPI

CS ------ Pin de selección de chip PB6

LEDA_EN—Pin de control de retroiluminación de la pantalla LCD PC10

FTFRES: pin de reinicio del LCD PA15

Instrucciones de diseño de circuito:

● El diseño del circuito de hardware se basa en los materiales de referencia proporcionados por la pantalla LCD oficial. Básicamente, simplemente cópielo de acuerdo con los datos del chip.

● Para mejorar la eficiencia de actualización de la pantalla LCD, elegimos la interfaz SPI3. modo de un solo cable

● DIO CLK debe estar conectado de forma fija a MOSI SCK, se pueden conectar otros pines a cualquier puerto IO

Inicialización de la pantalla LCD TFTLCD

código hal_tftlcd.c

#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();
}

código hal_tftlcd.h

#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

análisis de código

hal_tftlcd.c incluye

● Inicialización de la interfaz de comunicación con pantalla de cristal líquido TFTLCD

● Función de envío TFTLCD a través de datos DMA

● Otras funciones de control de puertos de la pantalla LCD TFTLCD

Proceso de inicialización de la interfaz TFTLCD SP3

➢ Definir la interfaz de comunicación TFTLCD.

//-----------------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)

➢ Encienda el reloj correspondiente.

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的功能

➢ Inicialice los puertos GPIO relacionados con la pantalla LCD TFTLCD y 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);	

➢ Inicializar los parámetros relacionados con SPI3

/* 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);

➢ Configurar la función SPI3 DMA.

Introducción a DMA:

El acceso directo a la memoria (DMA) se utiliza para proporcionar transferencias de datos de alta velocidad entre periféricos y memoria o entre memoria y memoria. Los datos se pueden mover rápidamente a través de DMA sin intervención de la CPU, lo que libera recursos de la CPU para otras operaciones. Los dos controladores DMA tienen 12 canales (7 canales para DMA1 y 5 canales para DMA2), y cada canal está dedicado a gestionar las solicitudes de acceso a la memoria desde uno o más periféricos. También hay un árbitro para coordinar la prioridad de cada solicitud de DMA.

En resumen, cuando nuestras funciones involucran funciones de transmisión de datos, como ADC, DMA, USART, etc., para acelerar la transmisión de datos, se puede agregar la función DMA a la transmisión de datos para permitir la transmisión o recepción DMA.

Tabla de correspondencia del canal DMA1:

Tabla de correspondencia de canales DMA2:

Nuestro proyecto utiliza la función de envío de DMA2, porque solo necesitamos enviar datos a la pantalla TFTLCD.

//使能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

Función de envío de datos SPI3 DMA
// 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);
}

Otras funciones de control de pines LCD
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();
}

Función de envío de datos y comando LCD
/******************************************************************************
      函数说明: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();//写数据
}

El contenido anterior es el contenido de los archivos hal_tftlcd.c y hal_tftlcd.h, que están relacionados con la función de inicialización del periférico stm32 DMA SPI3.

El siguiente contenido será el contenido de los archivos mt_tftlcd.c y mt_tftlcd.h, que están relacionados con el contenido de inicialización de la pantalla LCD del módulo. La inicialización del módulo de pantalla LCD se escribe en función de la función de inicialización de los periféricos stm32. , Entonces todas las funciones de inicialización del módulo se componen de llamar a la función de inicialización del periférico, la capa inferior es la función de inicialización del periférico stm32, la función de inicialización y el código del módulo, relativamente hablando, es el código de la capa de aplicación . Por lo tanto, el archivo mt es el código del controlador de la capa de aplicación y el archivo hal es el código del controlador subyacente.

Inicialización de la pantalla LCD y función de llenado de LCD

Para el controlador LCD y otras funciones del controlador relacionadas con la pantalla LCD, podemos trasplantarlos directamente de las rutinas de referencia oficiales y usarlos sin una investigación en profundidad.

vacío mt_tftlcd_init(vacío);

LCD_Fill(xsta corto sin firmar,ysta corto sin firmar,xend corto sin firmar,yend corto sin firmar,color corto sin firmar);

Nota: Tanto el código del controlador subyacente como el código del controlador de la capa de aplicación son programas escritos en función de la configuración de los registros STM32. No se requiere una investigación en profundidad y se puede llamar; el controlador de la capa de aplicación se programa en función del controlador subyacente.

código mt_tftlcd.c

#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);
	}	
}

código mt_Tftlcd.h

#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

Verificación de prueba funcional

La pantalla LCD se muestra amarilla en pantalla completa, lo que indica que la unidad está completa y en buen estado.

Supongo que te gusta

Origin blog.csdn.net/weixin_62261692/article/details/132550504
Recomendado
Clasificación