写点什么

【STM32】1.44 寸 TFT 液晶屏显示字符、汉字和图片

用户头像
AXYZdong
关注
发布于: 2021 年 02 月 11 日
【STM32】1.44寸TFT液晶屏显示字符、汉字和图片

Author:AXYZdong

自动化专业 工科男

有一点思考,有一点想法,有一点理性

概述

MCU:某宝的 STM32F407VET6 最小系统板,点此详见

外部资源:某宝的 TFT 液晶屏(下面会附上图片)

点此下载完整工程

文末有惊喜,希望可以坚持看下去

4.1 硬件设计



这里有个小疑问:为啥引出两个 GND 和 NC?不知道制造商怎么想的?有知道的小伙伴可以私信我呢。


要注意一下,NC 这个引脚是不需要接线的。

LED:背光控制信号,如果不需要控制时,接电源+3.3V

关键词:SPI 总线驱动

4.2 软件设计

4.2.1 编程要点

1、初始化 GPIO 口来模拟 SPI,每个人设置的 GPIO 口不同,开发板与 TFT 接线也会不同。之后再设置液晶屏初始化。


2、TFT 驱动程序,这里的驱动程序可以参考别人写的,然后自己再加以修改或者补充。驱动程序包括:向 TFT 写数据,设置 TFT 显示区域、设置 TFT 某点的颜色等等,具体的在代码里注释说明。


3、取模,包括文字取模和图片取模。根据自己的需要来取模。需要取模软件的可以私信我。

(PS:其实这几个步骤和上一篇文章的 OLED 差不多的啦,只是修(fu)改(zhi)了一下)

4.2.2 代码说明

1、宏定义 Lcd_Driver.h


#define RED  	  0xf800#define GREEN	  0x07e0#define BLUE 	  0x001f#define WHITE	  0xffff#define BLACK	  0x0000#define YELLOW  0xFFE0#define GRAY0   0xEF7D   	    //灰色0 3165 00110 001011 00101#define GRAY1   0x8410      	//灰色1 00000 000000 00000#define GRAY2   0x4208      	//灰色2  1111111111011111
#define LCD_CTRL GPIOB //定义TFT数据端口#define LCD_LED GPIO_Pin_9 //MCU_PB9--->>TFT --BL#define LCD_SCL GPIO_Pin_10 //PB13--->>TFT --SCL/SCK#define LCD_SDA GPIO_Pin_12 //PB15 MOSI--->>TFT --SDA/DIN#define LCD_RS GPIO_Pin_11 //PB11--->>TFT --RS/DC#define LCD_RST GPIO_Pin_14 //PB10--->>TFT --RST#define LCD_CS GPIO_Pin_13 //MCU_PB11--->>TFT --CS/CE
//#define LCD_CS_SET(x) LCD_CTRL->ODR=(LCD_CTRL->ODR&~LCD_CS)|(x ? LCD_CS:0)//液晶控制口置1操作语句宏定义
#define LCD_CS_SET LCD_CTRL->BSRRL=LCD_CS #define LCD_RS_SET LCD_CTRL->BSRRL=LCD_RS #define LCD_SDA_SET LCD_CTRL->BSRRL=LCD_SDA #define LCD_SCL_SET LCD_CTRL->BSRRL=LCD_SCL #define LCD_RST_SET LCD_CTRL->BSRRL=LCD_RST #define LCD_LED_SET LCD_CTRL->BSRRL=LCD_LED
//液晶控制口置0操作语句宏定义#define LCD_CS_CLR LCD_CTRL->BSRRH=LCD_CS #define LCD_RS_CLR LCD_CTRL->BSRRH=LCD_RS #define LCD_SDA_CLR LCD_CTRL->BSRRH=LCD_SDA #define LCD_SCL_CLR LCD_CTRL->BSRRH=LCD_SCL #define LCD_RST_CLR LCD_CTRL->BSRRH=LCD_RST #define LCD_LED_CLR LCD_CTRL->BSRRH=LCD_LED #define LCD_DATAOUT(x) LCD_DATA->ODR=x; //数据输出#define LCD_DATAIN LCD_DATA->IDR; //数据输入#define LCD_WR_DATA(data){\
LCD_RS_SET;\LCD_CS_CLR;\LCD_DATAOUT(data);\LCD_WR_CLR;\LCD_WR_SET;\LCD_CS_SET;\}
void LCD_GPIO_Init(void);void Lcd_WriteIndex(u8 Index);void Lcd_WriteData(u8 Data);void Lcd_WriteReg(u8 Index,u8 Data);u16 Lcd_ReadReg(u8 LCD_Reg);void Lcd_Reset(void);void Lcd_Init(void);void Lcd_Clear(u16 Color);void Lcd_SetXY(u16 x,u16 y);void Gui_DrawPoint(u16 x,u16 y,u16 Data);unsigned int Lcd_ReadPoint(u16 x,u16 y);void Lcd_SetRegion(u16 x_start,u16 y_start,u16 x_end,u16 y_end);void LCD_WriteData_16Bit(u16 Data);
复制代码

2、TFT 驱动文件 Lcd_Driver.c


#include "stm32f4xx.h"#include "Lcd_Driver.h"#include "LCD_Config.h"#include "delay.h"
//本程序使用的是模拟SPI接口驱动//可自由更改接口IO配置,使用任意最少4 IO即可完成液晶驱动显示
接口定义在Lcd_Driver.h内定义,请根据接线修改并修改相应IO初始化LCD_GPIO_Init()#define LCD_CTRL GPIOB //定义TFT数据端口#define LCD_LED GPIO_Pin_9 //PB9--->>TFT --BL#define LCD_RS GPIO_Pin_10 //PB11--->>TFT --RS/DC#define LCD_CS GPIO_Pin_11 //PB11--->>TFT --CS/CE#define LCD_RST GPIO_Pin_12 //PB10--->>TFT --RST#define LCD_SCL GPIO_Pin_13 //PB13--->>TFT --SCL/SCK#define LCD_SDA GPIO_Pin_15 //PB15 MOSI--->>TFT --SDA/DIN*******************************************************************************/
//液晶IO初始化配置void LCD_GPIO_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB ,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9| GPIO_Pin_10| GPIO_Pin_11| GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14| GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_Init(GPIOB, &GPIO_InitStructure); }//向SPI总线传输一个8位数据void SPI_WriteData(u8 Data){ unsigned char i=0; for(i=8;i>0;i--) { if(Data&0x80) LCD_SDA_SET; //输出数据 else LCD_SDA_CLR; LCD_SCL_CLR; LCD_SCL_SET; Data<<=1; }}//向液晶屏写一个8位指令void Lcd_WriteIndex(u8 Index){ //SPI 写命令时序开始 LCD_CS_CLR; LCD_RS_CLR; SPI_WriteData(Index); LCD_CS_SET;}
//向液晶屏写一个8位数据void Lcd_WriteData(u8 Data){ LCD_CS_CLR; LCD_RS_SET; SPI_WriteData(Data); LCD_CS_SET; }//向液晶屏写一个16位数据void LCD_WriteData_16Bit(u16 Data){ LCD_CS_CLR; LCD_RS_SET; SPI_WriteData(Data>>8); //写入高8位数据 SPI_WriteData(Data); //写入低8位数据 LCD_CS_SET; }
void Lcd_WriteReg(u8 Index,u8 Data){ Lcd_WriteIndex(Index); Lcd_WriteData(Data);}
void Lcd_Reset(void){ LCD_RST_CLR; delay_ms(100); LCD_RST_SET; delay_ms(50);}
//LCD Init For 1.44Inch LCD Panel with ST7735R.void Lcd_Init(void){ LCD_GPIO_Init(); Lcd_Reset(); //Reset before LCD Init.
//LCD Init For 1.44Inch LCD Panel with ST7735R. Lcd_WriteIndex(0x11);//Sleep exit delay_ms (120); //ST7735R Frame Rate Lcd_WriteIndex(0xB1); Lcd_WriteData(0x01); Lcd_WriteData(0x2C); Lcd_WriteData(0x2D);
Lcd_WriteIndex(0xB2); Lcd_WriteData(0x01); Lcd_WriteData(0x2C); Lcd_WriteData(0x2D);
Lcd_WriteIndex(0xB3); Lcd_WriteData(0x01); Lcd_WriteData(0x2C); Lcd_WriteData(0x2D); Lcd_WriteData(0x01); Lcd_WriteData(0x2C); Lcd_WriteData(0x2D); Lcd_WriteIndex(0xB4); //Column inversion Lcd_WriteData(0x07); //ST7735R Power Sequence Lcd_WriteIndex(0xC0); Lcd_WriteData(0xA2); Lcd_WriteData(0x02); Lcd_WriteData(0x84); Lcd_WriteIndex(0xC1); Lcd_WriteData(0xC5);
Lcd_WriteIndex(0xC2); Lcd_WriteData(0x0A); Lcd_WriteData(0x00);
Lcd_WriteIndex(0xC3); Lcd_WriteData(0x8A); Lcd_WriteData(0x2A); Lcd_WriteIndex(0xC4); Lcd_WriteData(0x8A); Lcd_WriteData(0xEE); Lcd_WriteIndex(0xC5); //VCOM Lcd_WriteData(0x0E); Lcd_WriteIndex(0x36); //MX, MY, RGB mode Lcd_WriteData(0xC8); //ST7735R Gamma Sequence Lcd_WriteIndex(0xe0); Lcd_WriteData(0x0f); Lcd_WriteData(0x1a); Lcd_WriteData(0x0f); Lcd_WriteData(0x18); Lcd_WriteData(0x2f); Lcd_WriteData(0x28); Lcd_WriteData(0x20); Lcd_WriteData(0x22); Lcd_WriteData(0x1f); Lcd_WriteData(0x1b); Lcd_WriteData(0x23); Lcd_WriteData(0x37); Lcd_WriteData(0x00); Lcd_WriteData(0x07); Lcd_WriteData(0x02); Lcd_WriteData(0x10);
Lcd_WriteIndex(0xe1); Lcd_WriteData(0x0f); Lcd_WriteData(0x1b); Lcd_WriteData(0x0f); Lcd_WriteData(0x17); Lcd_WriteData(0x33); Lcd_WriteData(0x2c); Lcd_WriteData(0x29); Lcd_WriteData(0x2e); Lcd_WriteData(0x30); Lcd_WriteData(0x30); Lcd_WriteData(0x39); Lcd_WriteData(0x3f); Lcd_WriteData(0x00); Lcd_WriteData(0x07); Lcd_WriteData(0x03); Lcd_WriteData(0x10); Lcd_WriteIndex(0x2a); Lcd_WriteData(0x00); Lcd_WriteData(0x00); Lcd_WriteData(0x00); Lcd_WriteData(0x7f);
Lcd_WriteIndex(0x2b); Lcd_WriteData(0x00); Lcd_WriteData(0x00); Lcd_WriteData(0x00); Lcd_WriteData(0x9f); Lcd_WriteIndex(0xF0); //Enable test command Lcd_WriteData(0x01); Lcd_WriteIndex(0xF6); //Disable ram power save mode Lcd_WriteData(0x00); Lcd_WriteIndex(0x3A); //65k mode Lcd_WriteData(0x05); Lcd_WriteIndex(0x29);//Display on }

/*************************************************函数名:LCD_Set_Region功能:设置lcd显示区域,在此区域写点数据自动换行入口参数:xy起点和终点返回值:无*************************************************/void Lcd_SetRegion(u16 x_start,u16 y_start,u16 x_end,u16 y_end){ Lcd_WriteIndex(0x2a); Lcd_WriteData(0x00); Lcd_WriteData(x_start+2); Lcd_WriteData(0x00); Lcd_WriteData(x_end+2);
Lcd_WriteIndex(0x2b); Lcd_WriteData(0x00); Lcd_WriteData(y_start+3); Lcd_WriteData(0x00); Lcd_WriteData(y_end+3); Lcd_WriteIndex(0x2c);
}
/*************************************************函数名:LCD_Set_XY功能:设置lcd显示起始点入口参数:xy坐标返回值:无*************************************************/void Lcd_SetXY(u16 x,u16 y){ Lcd_SetRegion(x,y,x,y);}
/*************************************************函数名:LCD_DrawPoint功能:画一个点入口参数:无返回值:无*************************************************/void Gui_DrawPoint(u16 x,u16 y,u16 Data){ Lcd_SetRegion(x,y,x+1,y+1); LCD_WriteData_16Bit(Data);
}
/***************************************** 函数功能:读TFT某一点的颜色 出口参数:color 点颜色值 ******************************************/unsigned int Lcd_ReadPoint(u16 x,u16 y){ unsigned int Data; Lcd_SetXY(x,y);
//Lcd_ReadData();//丢掉无用字节 //Data=Lcd_ReadData(); Lcd_WriteData(Data); return Data;}/*************************************************函数名:Lcd_Clear功能:全屏清屏函数入口参数:填充颜色COLOR返回值:无*************************************************/void Lcd_Clear(u16 Color) { unsigned int i,m; Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1); Lcd_WriteIndex(0x2C); for(i=0;i<X_MAX_PIXEL;i++) for(m=0;m<Y_MAX_PIXEL;m++) { LCD_WriteData_16Bit(Color); } }
复制代码

3、延时函数文件 delay.c


#include "stm32f4xx.h"#include "delay.h" static u8  fac_us=0;//us延时倍乘数static u16 fac_ms=0;//ms延时倍乘数//初始化延迟函数//SYSTICK的时钟固定为HCLK时钟的1/8//SYSCLK:系统时钟void delay_init(u8 SYSCLK){	SysTick->CTRL&=0xfffffffb;//bit2清空,选择外部时钟  HCLK/8	fac_us=SYSCLK/8;		    	fac_ms=(u16)fac_us*1000;}								    //延时nms//注意nms的范围//SysTick->LOAD为24位寄存器,所以,最大延时为://nms<=0xffffff*8*1000/SYSCLK//SYSCLK单位为Hz,nms单位为ms//对72M条件下,nms<=1864 void delay_ms(u16 nms){	 		  	  	u32 temp;		   	SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)	SysTick->VAL =0x00;           //清空计数器	SysTick->CTRL=0x01 ;          //开始倒数  	do	{		temp=SysTick->CTRL;	}	while(temp&0x01&&!(temp&(1<<16)));//等待时间到达   	SysTick->CTRL=0x00;       //关闭计数器	SysTick->VAL =0X00;       //清空计数器	  	    }   //延时nus//nus为要延时的us数.		    								   void delay_us(u32 nus){			u32 temp;	    	 	SysTick->LOAD=nus*fac_us; //时间加载	  		 	SysTick->VAL=0x00;        //清空计数器	SysTick->CTRL=0x01 ;      //开始倒数 	 	do	{		temp=SysTick->CTRL;	}	while(temp&0x01&&!(temp&(1<<16)));//等待时间到达   	SysTick->CTRL=0x00;       //关闭计数器	SysTick->VAL =0X00;       //清空计数器	 }
复制代码

4、图像显示驱动文件 GUI.c

#include "stm32f4xx.h"#include "Lcd_Driver.h"#include "GUI.h"#include "delay.h"#include "font.h"//从ILI93xx读出的数据为GBR格式,而我们写入的时候为RGB格式。//通过该函数转换//c:GBR格式的颜色值//返回值:RGB格式的颜色值u16 LCD_BGR2RGB(u16 c){  u16  r,g,b,rgb;     b=(c>>0)&0x1f;  g=(c>>5)&0x3f;  r=(c>>11)&0x1f;	   rgb=(b<<11)+(g<<5)+(r<<0);		   return(rgb);
}void Gui_Circle(u16 X,u16 Y,u16 R,u16 fc) {//Bresenham算法 unsigned short a,b; int c; a=0; b=R; c=3-2*R; while (a<b) { Gui_DrawPoint(X+a,Y+b,fc); // 7 Gui_DrawPoint(X-a,Y+b,fc); // 6 Gui_DrawPoint(X+a,Y-b,fc); // 2 Gui_DrawPoint(X-a,Y-b,fc); // 3 Gui_DrawPoint(X+b,Y+a,fc); // 8 Gui_DrawPoint(X-b,Y+a,fc); // 5 Gui_DrawPoint(X+b,Y-a,fc); // 1 Gui_DrawPoint(X-b,Y-a,fc); // 4
if(c<0) c=c+4*a+6; else { c=c+4*(a-b)+10; b-=1; } a+=1; } if (a==b) { Gui_DrawPoint(X+a,Y+b,fc); Gui_DrawPoint(X+a,Y+b,fc); Gui_DrawPoint(X+a,Y-b,fc); Gui_DrawPoint(X-a,Y-b,fc); Gui_DrawPoint(X+b,Y+a,fc); Gui_DrawPoint(X-b,Y+a,fc); Gui_DrawPoint(X+b,Y-a,fc); Gui_DrawPoint(X-b,Y-a,fc); } } //画线函数,使用Bresenham 画线算法void Gui_DrawLine(u16 x0, u16 y0,u16 x1, u16 y1,u16 Color) {int dx, // difference in x's dy, // difference in y's dx2, // dx,dy * 2 dy2, x_inc, // amount in pixel space to move during drawing y_inc, // amount in pixel space to move during drawing error, // the discriminant i.e. error i.e. decision variable index; // used for looping

Lcd_SetXY(x0,y0); dx = x1-x0;//计算x距离 dy = y1-y0;//计算y距离
if (dx>=0) { x_inc = 1; } else { x_inc = -1; dx = -dx; } if (dy>=0) { y_inc = 1; } else { y_inc = -1; dy = -dy; }
dx2 = dx << 1; dy2 = dy << 1;
if (dx > dy)//x距离大于y距离,那么每个x轴上只有一个点,每个y轴上有若干个点 {//且线的点数等于x距离,以x轴递增画点 // initialize error term error = dy2 - dx;
// draw the line for (index=0; index <= dx; index++)//要画的点数不会超过x距离 { //画点 Gui_DrawPoint(x0,y0,Color); // test if error has overflowed if (error >= 0) //是否需要增加y坐标值 { error-=dx2;
// move to next line y0+=y_inc;//增加y坐标值 } // end if error overflowed
// adjust the error term error+=dy2;
// move to the next pixel x0+=x_inc;//x坐标值每次画点后都递增1 } // end for } // end if |slope| <= 1 else//y轴大于x轴,则每个y轴上只有一个点,x轴若干个点 {//以y轴为递增画点 // initialize error term error = dx2 - dy;
// draw the line for (index=0; index <= dy; index++) { // set the pixel Gui_DrawPoint(x0,y0,Color);
// test if error overflowed if (error >= 0) { error-=dy2;
// move to next line x0+=x_inc; } // end if error overflowed
// adjust the error term error+=dx2;
// move to the next pixel y0+=y_inc; } // end for } // end else |slope| > 1}


void Gui_box(u16 x, u16 y, u16 w, u16 h,u16 bc){ Gui_DrawLine(x,y,x+w,y,0xEF7D); Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0x2965); Gui_DrawLine(x,y+h,x+w,y+h,0x2965); Gui_DrawLine(x,y,x,y+h,0xEF7D); Gui_DrawLine(x+1,y+1,x+1+w-2,y+1+h-2,bc);}void Gui_box2(u16 x,u16 y,u16 w,u16 h, u8 mode){ if (mode==0) { Gui_DrawLine(x,y,x+w,y,0xEF7D); Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0x2965); Gui_DrawLine(x,y+h,x+w,y+h,0x2965); Gui_DrawLine(x,y,x,y+h,0xEF7D); } if (mode==1) { Gui_DrawLine(x,y,x+w,y,0x2965); Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0xEF7D); Gui_DrawLine(x,y+h,x+w,y+h,0xEF7D); Gui_DrawLine(x,y,x,y+h,0x2965); } if (mode==2) { Gui_DrawLine(x,y,x+w,y,0xffff); Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0xffff); Gui_DrawLine(x,y+h,x+w,y+h,0xffff); Gui_DrawLine(x,y,x,y+h,0xffff); }}

/**************************************************************************************功能描述: 在屏幕显示一凸起的按钮框输 入: u16 x1,y1,x2,y2 按钮框左上角和右下角坐标输 出: 无**************************************************************************************/void DisplayButtonDown(u16 x1,u16 y1,u16 x2,u16 y2){ Gui_DrawLine(x1, y1, x2,y1, GRAY2); //H Gui_DrawLine(x1+1,y1+1,x2,y1+1, GRAY1); //H Gui_DrawLine(x1, y1, x1,y2, GRAY2); //V Gui_DrawLine(x1+1,y1+1,x1+1,y2, GRAY1); //V Gui_DrawLine(x1, y2, x2,y2, WHITE); //H Gui_DrawLine(x2, y1, x2,y2, WHITE); //V}
/**************************************************************************************功能描述: 在屏幕显示一凹下的按钮框输 入: u16 x1,y1,x2,y2 按钮框左上角和右下角坐标输 出: 无**************************************************************************************/void DisplayButtonUp(u16 x1,u16 y1,u16 x2,u16 y2){ Gui_DrawLine(x1, y1, x2,y1, WHITE); //H Gui_DrawLine(x1, y1, x1,y2, WHITE); //V Gui_DrawLine(x1+1,y2-1,x2,y2-1, GRAY1); //H Gui_DrawLine(x1, y2, x2,y2, GRAY2); //H Gui_DrawLine(x2-1,y1+1,x2-1,y2, GRAY1); //V Gui_DrawLine(x2 ,y1 ,x2,y2, GRAY2); //V}

void Gui_DrawFont_GBK16(u16 x, u16 y, u16 fc, u16 bc, u8 *s){ unsigned char i,j; unsigned short k,x0; x0=x;
while(*s) { if((*s) < 128) { k=*s; if (k==13) { x=x0; y+=16; } else { if (k>32) k-=32; else k=0; for(i=0;i<16;i++) for(j=0;j<8;j++) { if(asc16[k*16+i]&(0x80>>j)) Gui_DrawPoint(x+j,y+i,fc); else { if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc); } } x+=8; } s++; } else {
for (k=0;k<hz16_num;k++) { if ((hz16[k].Index[0]==*(s))&&(hz16[k].Index[1]==*(s+1))) { for(i=0;i<16;i++) { for(j=0;j<8;j++) { if(hz16[k].Msk[i*2]&(0x80>>j)) Gui_DrawPoint(x+j,y+i,fc); else { if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc); } } for(j=0;j<8;j++) { if(hz16[k].Msk[i*2+1]&(0x80>>j)) Gui_DrawPoint(x+j+8,y+i,fc); else { if (fc!=bc) Gui_DrawPoint(x+j+8,y+i,bc); } } } } } s+=2;x+=16; } }}
void Gui_DrawFont_GBK24(u16 x, u16 y, u16 fc, u16 bc, u8 *s){ unsigned char i,j; unsigned short k;
while(*s) { if( *s < 0x80 ) { k=*s; if (k>32) k-=32; else k=0;
for(i=0;i<16;i++) for(j=0;j<8;j++) { if(asc16[k*16+i]&(0x80>>j)) Gui_DrawPoint(x+j,y+i,fc); else { if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc); } } s++;x+=8; } else {
for (k=0;k<hz24_num;k++) { if ((hz24[k].Index[0]==*(s))&&(hz24[k].Index[1]==*(s+1))) { for(i=0;i<24;i++) { for(j=0;j<8;j++) { if(hz24[k].Msk[i*3]&(0x80>>j)) Gui_DrawPoint(x+j,y+i,fc); else { if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc); } } for(j=0;j<8;j++) { if(hz24[k].Msk[i*3+1]&(0x80>>j)) Gui_DrawPoint(x+j+8,y+i,fc); else { if (fc!=bc) Gui_DrawPoint(x+j+8,y+i,bc); } } for(j=0;j<8;j++) { if(hz24[k].Msk[i*3+2]&(0x80>>j)) Gui_DrawPoint(x+j+16,y+i,fc); else { if (fc!=bc) Gui_DrawPoint(x+j+16,y+i,bc); } } } } } s+=2;x+=24; } }}void Gui_DrawFont_Num32(u16 x, u16 y, u16 fc, u16 bc, u16 num){ unsigned char i,j,k,c; //lcd_text_any(x+94+i*42,y+34,32,32,0x7E8,0x0,sz32,knum[i]);// w=w/8;
for(i=0;i<32;i++) { for(j=0;j<4;j++) { c=*(sz32+num*32*4+i*4+j); for (k=0;k<8;k++) { if(c&(0x80>>k)) Gui_DrawPoint(x+j*8+k,y+i,fc); else { if (fc!=bc) Gui_DrawPoint(x+j*8+k,y+i,bc); } } } }}
复制代码

5、TFT 显示图像文件 QDTFT_demo.c

#include "stm32f4xx.h"#include "Lcd_Driver.h"#include "GUI.h"#include "delay.h"#include "Picture.h"#include "QDTFT_demo.h"unsigned char Num[10]={0,1,2,3,4,5,6,7,8,9};void Redraw_Mainmenu(void){
Lcd_Clear(GRAY0); Gui_DrawFont_GBK16(48,0,BLUE,GRAY0,"CSDN"); // DisplayButtonUp(15,18,113,28); Gui_DrawFont_GBK16(32,20,RED,GRAY0,"AXYZdong");
DisplayButtonUp(15,38,113,58); //x1,y1,x2,y2 Gui_DrawFont_GBK16(32,40,YELLOW,GRAY0,"文字显示");
DisplayButtonUp(15,68,113,88); //x1,y1,x2,y2 Gui_DrawFont_GBK16(2,70,BLUE,GRAY0,"Tel:17855525056");
DisplayButtonUp(15,98,113,118); //x1,y1,x2,y2 Gui_DrawFont_GBK16(0,100,RED,GRAY0,"www.AXYZdong.com"); delay_ms(1500);}
void Num_Test(void){ u8 i=0; Lcd_Clear(GRAY0); Gui_DrawFont_GBK16(32,60,RED,GRAY0,"Num Test"); delay_ms(1000); Lcd_Clear(GRAY0);
for(i=0;i<10;i++) { Gui_DrawFont_Num32((i%3)*42,32*(i/3),RED,GRAY0,Num[i+1]); delay_ms(100); } }
void Font_Test(void){ Lcd_Clear(GRAY0); Gui_DrawFont_GBK16(16,60,BLUE,GRAY0,"文字显示测试");
delay_ms(1000); Lcd_Clear(GRAY0); Gui_DrawFont_GBK16(16,20,YELLOW,GRAY0,"全动电子技术"); Gui_DrawFont_GBK16(16,40,BLUE,GRAY0,"专注液晶批发"); Gui_DrawFont_GBK16(16,60,RED,GRAY0, "全程技术支持") Gui_DrawFont_GBK16(4,100,RED,GRAY0, "www.youdong.com"); delay_ms(1800); }
void Color_Test(void){ u8 i=1; Lcd_Clear(GRAY0); Gui_DrawFont_GBK16(24,60,BLUE,GRAY0,"Color Test"); delay_ms(200);
while(i--) { Lcd_Clear(WHITE); Lcd_Clear(BLACK); Lcd_Clear(RED); Lcd_Clear(GREEN); Lcd_Clear(BLUE); } }
//取模方式 水平扫描 从左到右 低位在前void showimage(const unsigned char *p) //显示40*40 QQ图片{ int i,j,k; unsigned char picH,picL; Lcd_Clear(WHITE); //清屏 for(k=0;k<3;k++) { for(j=0;j<3;j++) { Lcd_SetRegion(40*j,40*k,40*j+39,40*k+39); //坐标设置 for(i=0;i<40*40;i++) { picL=*(p+i*2); //数据低位在前 picH=*(p+i*2+1); LCD_WriteData_16Bit(picH<<8|picL); } } } }
//取模方式 水平扫描 从左到右 低位在前void showphoto(const unsigned char *p) //显示128*128图片{ int i; unsigned char picH,picL;// Lcd_Clear(WHITE); //清屏 Lcd_SetRegion(0,0,127,127); //坐标设置 for(i=0;i<128*128;i++) { picL=*(p+i*2); //数据低位在前 picH=*(p+i*2+1); LCD_WriteData_16Bit(picH<<8|picL); } }void QDTFT_Test_Demo(void){// Lcd_Init(); LCD_LED_SET;//通过IO控制背光亮 Redraw_Mainmenu();//绘制主菜单(部分内容由于分辨率超出物理值可能无法显示)// Color_Test();//简单纯色填充// Num_Test();//数码管字体// Font_Test();//中英文显示 // showphoto(gImage_Robotmaster);//图片显示示例// delay_ms(1200);// LCD_LED_CLR;//IO控制背光灭 }
复制代码

6、主函数 main.c


//  作    者   : AXYZdong//  生成日期   : 2020-02-03//  最近修改   : 2020-03-02 //  功能描述   : TFT SPI接口演示例程(stm32系列)//              GND    电源地//              VCC  接5V或3.3v电源//              LED  接PB9//              SCL  接PB10//              SDA  接PB12//              RS   接PB11//              RST  接PB14//              CS   接PB13               //              ------------------------------------------------------------ 
/*Left--Right Pin:VCC GND GND NC NC LED SCL SDA RS RST CS*/
#include "stm32f4xx.h"#include "delay.h"#include "QDTFT_demo.h"#include "Lcd_Driver.h"#include "GUI.h"

int main(void){
SystemInit(); //System init. delay_init(72); //Delay init. Lcd_Init(); while(1) { QDTFT_Test_Demo(); //See the test details in QDTFT_Demo.c }
}
复制代码

上的代码比较多,如有不懂的地方可以私信我呢。


当然,显示字符、汉字和图片是 TFT 最最基本的功能,作为一个显示的媒介,如果与其他的器件建立起通信,将其他器件产生的信息在 TFT 上显示出来,这样我们就可以直观的获取想要的信息。


那么,该如何建立相互之间的通信关系?如何直观的显示在 TFT 上?是我今后所要探索和学习的地方。博客也会不定期更新,期待不久的某一篇会更新到相关内容。(hhh,先卖个关子)


下一篇,更精彩!


码字不易,大家的支持就是我坚持下去的动力。点赞后不要忘了关注我哦!


发布于: 2021 年 02 月 11 日阅读数: 21
用户头像

AXYZdong

关注

没有伞的孩子要学会奔跑! 2020.06.01 加入

自动化专业 工科男 有一点思考,有一点想法,有一点理性。 定个小小目标,努力成为习惯。

评论

发布
暂无评论
【STM32】1.44寸TFT液晶屏显示字符、汉字和图片