一、TFT是什么?

TFT(Thin Film Transistor)彩屏是一种基于薄膜晶体管技术的液晶显示屏,它使用了薄膜晶体管作为每个像素点的开关,能够实现快速响应和高质量的图像显示。

这次用到的是1.44寸彩屏,该款LCD模块采用4线制SPI通信方式,驱动IC为ST7735S,分辨率为128*128,该模块包含有LCD显示屏,背光控制电路。

废话不多说,下面直接进入正文。

二、TFT使用步骤

1.硬件

1.1 引脚说明

在这里插入图片描述

引脚标号说明
GND接地
VCC5V/3.3V电源输入
SCLSPI总线时钟信号
SDASPI总线写数据信号
RES液晶屏复位信号,低电平复位
DC液晶屏寄存器/数据选择信号,高电平:寄存器,低电平:数据
CS液晶屏片选信号,低电平使能
BLKLED 背光控制,高电平点亮,如无需控制则接3.3V常亮

1.2 硬件电路

这里我是采用面包板和STM32F103核心板以及TFT彩屏自己搭建的一个硬件连接。
在这里插入图片描述
引脚定义如下:

#define LCD_CTRL   	  	GPIOB		//定义TFT数据端口
#define LCD_LED        	GPIO_Pin_8  //PB9 连接至TFT--BLK
#define LCD_CS        	GPIO_Pin_7  //PB7连接至TFT--CS
#define LCD_RS         	GPIO_Pin_6	//PB6连接至TFT--DC
#define LCD_RST     	GPIO_Pin_5	//PB5连接至TFT--RES
#define LCD_SCL        	GPIO_Pin_11	//PB11连接至TFT--SCL
#define LCD_SDA        	GPIO_Pin_10	//PB10连接至TFT--SDA

2.软件

由于TFT彩屏用到的函数过多,我这里仅仅展示我用到的一些,感兴趣的可以下载附件查看完整工程。

2.1 初始化(示例):

TFT初始化流程是固定发这些指令的,无需深究,想了解的可以看下ST7735S驱动手册。

LCD_GPIOInit函数是将引脚配置为推挽输出模式。

/*******************************************************************************
 * 函数名:LCD_Init
 * 描述  :TFT初始化
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
 *******************************************************************************/
void LCD_Init(void)
{  	
	LCD_GPIOInit();//使用模拟SPI										 

 	LCD_RESET(); //液晶屏复位

	//************* Start Initial Sequence **********//		
	//开始初始化液晶屏
	LCD_WR_REG(0x11);//Sleep exit 
	delay_syms (120);		
	//ST7735R Frame Rate
	LCD_WR_REG(0xB1); 
	LCD_WR_DATA(0x01); 
	LCD_WR_DATA(0x2C); 
	LCD_WR_DATA(0x2D); 

	LCD_WR_REG(0xB2); 
	LCD_WR_DATA(0x01); 
	LCD_WR_DATA(0x2C); 
	LCD_WR_DATA(0x2D); 

	LCD_WR_REG(0xB3); 
	LCD_WR_DATA(0x01); 
	LCD_WR_DATA(0x2C); 
	LCD_WR_DATA(0x2D); 
	LCD_WR_DATA(0x01); 
	LCD_WR_DATA(0x2C); 
	LCD_WR_DATA(0x2D); 
	
	LCD_WR_REG(0xB4); //Column inversion 
	LCD_WR_DATA(0x07); 
	
	//ST7735R Power Sequence
	LCD_WR_REG(0xC0); 
	LCD_WR_DATA(0xA2); 
	LCD_WR_DATA(0x02); 
	LCD_WR_DATA(0x84); 
	LCD_WR_REG(0xC1); 
	LCD_WR_DATA(0xC5); 

	LCD_WR_REG(0xC2); 
	LCD_WR_DATA(0x0A); 
	LCD_WR_DATA(0x00); 

	LCD_WR_REG(0xC3); 
	LCD_WR_DATA(0x8A); 
	LCD_WR_DATA(0x2A); 
	LCD_WR_REG(0xC4); 
	LCD_WR_DATA(0x8A); 
	LCD_WR_DATA(0xEE); 
	
	LCD_WR_REG(0xC5); //VCOM 
	LCD_WR_DATA(0x0E); 
	
	LCD_WR_REG(0x36); //MX, MY, RGB mode 				 
	LCD_WR_DATA(0xC8); 
	
	//ST7735R Gamma Sequence
	LCD_WR_REG(0xe0); 
	LCD_WR_DATA(0x0f); 
	LCD_WR_DATA(0x1a); 
	LCD_WR_DATA(0x0f); 
	LCD_WR_DATA(0x18); 
	LCD_WR_DATA(0x2f); 
	LCD_WR_DATA(0x28); 
	LCD_WR_DATA(0x20); 
	LCD_WR_DATA(0x22); 
	LCD_WR_DATA(0x1f); 
	LCD_WR_DATA(0x1b); 
	LCD_WR_DATA(0x23); 
	LCD_WR_DATA(0x37); 
	LCD_WR_DATA(0x00); 	
	LCD_WR_DATA(0x07); 
	LCD_WR_DATA(0x02); 
	LCD_WR_DATA(0x10); 

	LCD_WR_REG(0xe1); 
	LCD_WR_DATA(0x0f); 
	LCD_WR_DATA(0x1b); 
	LCD_WR_DATA(0x0f); 
	LCD_WR_DATA(0x17); 
	LCD_WR_DATA(0x33); 
	LCD_WR_DATA(0x2c); 
	LCD_WR_DATA(0x29); 
	LCD_WR_DATA(0x2e); 
	LCD_WR_DATA(0x30); 
	LCD_WR_DATA(0x30); 
	LCD_WR_DATA(0x39); 
	LCD_WR_DATA(0x3f); 
	LCD_WR_DATA(0x00); 
	LCD_WR_DATA(0x07); 
	LCD_WR_DATA(0x03); 
	LCD_WR_DATA(0x10);  
	
	LCD_WR_REG(0x2a);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x7f);

	LCD_WR_REG(0x2b);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x00);
	LCD_WR_DATA(0x9f);
	
	LCD_WR_REG(0xF0); //Enable test command  
	LCD_WR_DATA(0x01); 
	LCD_WR_REG(0xF6); //Disable ram power save mode 
	LCD_WR_DATA(0x00); 
	
	LCD_WR_REG(0x3A); //65k mode 
	LCD_WR_DATA(0x05); 	
	LCD_WR_REG(0x29);//Display on	

	LCD_SetParam();//设置LCD参数	 
	LCD_LED_SET;//点亮背光	 
}

2.2 LCD复位(示例):

注意:液晶初始化前要调用此函数

/*******************************************************************************
 * 函数名:LCD_Init
 * 描述  :LCD复位函数
 * 输入  :void
 * 输出  :void
 * 调用  :初始化
 * 备注  :
 *******************************************************************************/
void LCD_RESET(void)
{
	LCD_RST_CLR;
	delay_syms(100);	
	LCD_RST_SET;
	delay_syms(50);
}

2.3 LCD写指令(示例):

#if USE_HARDWARE_SPI 在这里表示是硬件SPI还是软件模拟SPI,我这里用的是软件模拟SPI。

/*******************************************************************************
 * 函数名:LCD_WR_REG
 * 描述  :向液晶屏总线写入写16位指令
 * 输入  :Reg:待写入的指令值
 * 输出  :void
 * 调用  :
 * 备注  :
 *******************************************************************************/
void LCD_WR_REG(u16 data)
{ 
   LCD_CS_CLR;
   LCD_RS_CLR;
#if USE_HARDWARE_SPI   
   SPI_WriteByte(SPI2,data);
#else
   SPIv_WriteData(data);
#endif 
   LCD_CS_SET;
}

2.4 LCD写数据(示例):

#if USE_HARDWARE_SPI 在这里表示是硬件SPI还是软件模拟SPI,我这里用的是软件模拟SPI。

/*******************************************************************************
 * 函数名:LCD_WR_DATA
 * 描述  :向液晶屏总线写入写8位数据
 * 输入  :Data:待写入的数据
 * 输出  :void
 * 调用  :
 * 备注  :
 *******************************************************************************/
void LCD_WR_DATA(u8 data)
{	
   LCD_CS_CLR;
   LCD_RS_SET;
#if USE_HARDWARE_SPI   
   SPI_WriteByte(SPI2,data);
#else
   SPIv_WriteData(data);
#endif 
   LCD_CS_SET;
}

2.5 设置LCD参数(示例):

/*******************************************************************************
 * 函数名:LCD_SetParam
 * 描述  :设置LCD参数
 * 输入  :void
 * 输出  :void
 * 调用  :
 * 备注  :方便进行横竖屏模式切换
 *******************************************************************************/
void LCD_SetParam(void)
{ 	
	lcddev.wramcmd=0x2C;
#if USE_HORIZONTAL==1	//使用横屏	  
	lcddev.dir=1;//横屏
	lcddev.width=128;
	lcddev.height=128;
	lcddev.setxcmd=0x2A;
	lcddev.setycmd=0x2B;			
	LCD_WriteReg(0x36,0xA8);

#else//竖屏
	lcddev.dir=0;//竖屏				 	 		
	lcddev.width=128;
	lcddev.height=128;
	lcddev.setxcmd=0x2A;
	lcddev.setycmd=0x2B;	
	LCD_WriteReg(0x36,0xC8);
#endif
}	

这里说一下横屏和竖屏的定义,横屏宽度320高度240,竖屏反之宽度240高度320.

//支持横竖屏快速定义切换,支持8/16位模式切换
#define USE_HORIZONTAL  	0	//定义是否使用横屏 		0,不使用.1,使用.

//定义LCD的尺寸
#if USE_HORIZONTAL==1	//使用横屏
#define LCD_W 320
#define LCD_H 240
#else
#define LCD_W 240
#define LCD_H 320
#endif

2.6 LCD清屏(示例):

/*******************************************************************************
 * 函数名:LCD_Clear
 * 描述  :LCD全屏填充清屏函数
 * 输入  :Color:要清屏的填充色
 * 输出  :void
 * 调用  :
 * 备注  :
 *******************************************************************************/ 
void LCD_Clear(u16 Color)
{
	u16 i,j;      
	LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);	  
	for(i=0;i<lcddev.width;i++)
	{
		for(j=0;j<lcddev.height;j++)
		LCD_WR_DATA_16Bit(Color);	//写入数据 	 
	}
}  

2.7 显示一个字符串(示例):

/*******************************************************************************
 * 函数名:LCD_SetWindows
 * 描述  :显示一个字符串,包含中英文显示
 * 输入  : x,y :起点坐标
 			fc:前置画笔颜色
			bc:背景颜色
			str :字符串	 
			size:字体大小
			mode:模式	0,填充模式;1,叠加模式
 * 输出  :void
 * 调用  :
 * 备注  :
 *******************************************************************************/ 	   		   
void LCD_Show_Str(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *str,uint8_t size,uint8_t mode)
{					
	uint16_t x0=x;							  	  
  	uint18_t bHz=0;//字符或者中文 
    while(*str!=0)//数据未结束
    { 
        if(!bHz)
        {
			if(x>(lcddev.width-size/2)||y>(lcddev.height-size)) 
			return; 
	        if(*str>0x80)bHz=1;//中文 
	        else              //字符
	        {          
		        if(*str==0x0D)//换行符号
		        {         
		            y+=size;
					x=x0;
		            str++; 
		        }  
		        else
				{
					if(size==12||size==16)
					{  
					LCD_ShowChar(x,y,fc,bc,*str,size,mode);
					x+=size/2; //字符,为全字的一半 
					}
					else//字库中没有集成16X32的英文字体,用8X16代替
					{
					 	LCD_ShowChar(x,y,fc,bc,*str,16,mode);
						x+=8; //字符,为全字的一半 
					}
				} 
				str++; 
		        
	        }
        }else//中文 
        {   
			if(x>(lcddev.width-size)||y>(lcddev.height-size)) 
			return;  
            bHz=0;//有汉字库    
			if(size==32)
			GUI_DrawFont32(x,y,fc,bc,str,mode);	 	
			else if(size==24)
			GUI_DrawFont24(x,y,fc,bc,str,mode);	
			else
			GUI_DrawFont16(x,y,fc,bc,str,mode);
				
	        str+=2; 
	        x+=size;//下一个汉字偏移	    
        }						 
    }   
}

2.8 设置LCD显示窗口(示例):

/*******************************************************************************
 * 函数名:LCD_SetWindows
 * 描述  :设置lcd显示窗口,在此区域写点数据自动换行
 * 输入  :xy起点和终点
 * 输出  :void
 * 调用  :
 * 备注  :
 *******************************************************************************/
void LCD_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd)
{
#if USE_HORIZONTAL==1	//使用横屏
	LCD_WR_REG(lcddev.setxcmd);	
	LCD_WR_DATA(xStar>>8);
	LCD_WR_DATA(0x00FF&xStar+3);		
	LCD_WR_DATA(xEnd>>8);
	LCD_WR_DATA(0x00FF&xEnd+3);

	LCD_WR_REG(lcddev.setycmd);	
	LCD_WR_DATA(yStar>>8);
	LCD_WR_DATA(0x00FF&yStar+2);		
	LCD_WR_DATA(yEnd>>8);
	LCD_WR_DATA(0x00FF&yEnd+2);	

#else
	
	LCD_WR_REG(lcddev.setxcmd);	
	LCD_WR_DATA(xStar>>8);
	LCD_WR_DATA(0x00FF&xStar+2);		
	LCD_WR_DATA(xEnd>>8);
	LCD_WR_DATA(0x00FF&xEnd+2);

	LCD_WR_REG(lcddev.setycmd);	
	LCD_WR_DATA(yStar>>8);
	LCD_WR_DATA(0x00FF&yStar+3);		
	LCD_WR_DATA(yEnd>>8);
	LCD_WR_DATA(0x00FF&yEnd+3);	
#endif

	LCD_WriteRAM_Prepare();	//开始写入GRAM				
} 

2.9 TFT显示图片(示例):

/*******************************************************************************
 * 函数名:TFT_Show_Image
 * 描述  :TFT显示图片
 * 输入  :x,y :起点坐标
           x1,y1 :图片宽度,高度
           *image 图片数组
 * 输出  :void
 * 调用  :
 * 备注  :
 *******************************************************************************/
void TFT_Show_Image(uint16_t  x,uint16_t  y,uint16_t  x1,uint16_t  y1,const uint8_t  *image) 
{
    uint16_t i; 
	uint8_t picH,picL;
	
	LCD_SetWindows(x,y,x+x1-1,y+y1-1);//窗口设置
    for(i=0;i<x1*y1;i++)
	{	
	 	picL=*(image+i*2);//数据低位在前
		picH=*(image+i*2+1);				
		LCD_WR_DATA_16Bit(picH<<8|picL);  						
	}	
	LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复显示窗口为全屏	
}

2.10 TFT_Test(测试)(示例):

/*******************************************************************************
 * 函数名:TFT_Test
 * 描述  :测试TFT
 * 输入  :void
 * 输出  :void
 * 调用  :
 * 备注  :
 *******************************************************************************/
void TFT_Test(void)
{		
	/*TFT_Show_Image显示*/	
	TFT_Show_Image(0,0,128,63,xiaobuding);	
	LCD_Show_Str(10,80,BRED,WHITE,"2023-12-6",20,1);				
	LCD_Show_Str(10,100,RED,WHITE,"xiaobuding_QAQ",25,1);	
}

2.11 测试结果:

在这里插入图片描述

3.取模软件Img2Lcd的使用

在我的另外一篇文章0.96寸OLED(IIC接口)显示屏的图像显示应用用到了PCtoLCD软件,今天我们用下Img2Lcd软件,有需要可以下载免激活码使用,

3.1 打开Img2Lcd软件

在这里插入图片描述

3.2 打开图片,进行相应配置

这里注意下右下角输出图像的大小,要显示图片的时候,用到函数TFT_Show_Image对图片宽度,高度进行设置要一致

在这里插入图片描述

3.3 保存数组数据

在这里插入图片描述

3.4 最后将数组数据复制到程序里面就可以了


四、 总结

本次的TFT彩屏的驱动主要来源于多种显示模块驱动,感兴趣的可以进去看下,里面有树莓派显示模块/SPI显示模块/Arduino显示模块/IPS彩屏等等相关资料,今天的内容就到这里了,感谢你的观看,谢谢!

在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐