先从网上找个TFT显示屏,ILI9328驱动的 240*320 。ILI9328是一款由Ilitek公司开发的TFT-LCD驱动控制器,广泛应用于各类嵌入式显示系统中。
主要特点
1 高分辨率支持:ILI9328支持高达240x320像素的屏幕分辨率,适用于多种尺寸的液晶显示屏,如2.5英寸和2.8英寸的TFT显示屏。
该控制器支持16位和18位真彩色模式,能够显示262,144种颜色(即262K色),提供高质量的彩色显示效果。
2 接口灵活:ILI9328支持多种接口模式,包括并行总线接口(如8位、9位、16位和18位)和串行接口(如SPI),便于与不同类型的微控制器或处理器连接。内置视频RAM缓冲区:控制器内置视频RAM(GRAM),用于存储图像数据,减少了外部存储器的需求,简化了系统设计。
3 低功耗:ILI9328采用先进的低功耗设计,适用于便携式设备,如手持GPS、MP3播放器、智能仪表等。
开发一个PCB转接板,先要源文件可以私信我。
下面进行软件编写:
使用普通I/O口模拟SPI接口时,需要连接以下信号线:
SCK(Serial Clock):时钟信号线,由STM32G4提供,用于同步数据传输。
MOSI(Master Out Slave In):主设备输出/从设备输入引脚,用于STM32G4向TFT显示屏发送数据。
CS(Chip Select):片选信号线,用于选中TFT显示屏进行通信。
DC(Data/Command):数据/命令选择信号线,用于区分传输的是数据还是命令。
RST(Reset):复位信号线,用于复位TFT显示屏。其他信号线:如背光控制信号线等,根据实际需求进行连接。
宏定义:
#define LCD_RS RS_Pin //PE3Á¬½ÓÖÁTFT --DC RS #define LCD_CS CS_Pin //PE4Á¬½ÓÖÁTFT --CS #define LCD_RST RST_Pin //PE1Á¬½ÓÖÁTFT --RST #define LCD_SCL CLK_Pin //PE2Á¬½ÓÖÁTFT --CLK #define LCD_SDA SDA_Pin //PE6Á¬½ÓÖÁTFT - SDI #define LCD_SDO SDO_Pin //PE5Á¬½ÓÖÁTFT - SDO #define SPI_CS(a) \ if (a) \ GPIOE->BSRR=LCD_CS; \ else \ GPIOE->BRR=LCD_CS ; #define SPI_DCLK(a) \ if (a) \ GPIOE->BSRR=LCD_SCL; \ else \ GPIOE->BRR=LCD_SCL; #define SPI_SDA(a) \ if (a) \ GPIOE->BSRR=LCD_SDA; \ else \ GPIOE->BRR=LCD_SDA; #define lcd_RS(a) \ if (a) \ GPIOE->BSRR=LCD_RS;\ else \ GPIOE->BRR=LCD_RS; #define LCD_RST_SET GPIOE->BSRR=LCD_RST #define LCD_RST_CLR GPIOE->BRR=LCD_RST
功能函数编写:
void Lcd_Reset(void) { LCD_RST_CLR; HAL_Delay(100); LCD_RST_SET; HAL_Delay(50); } void LCD_delay(int time) //¼òµ¥Èí¼þ ÑÓʱº¯Êý { unsigned short i,j; for(i=0;i<time;i++) for(j=0;j<1000;j++) ; } void LCD_WriteByteSPI(unsigned char byte) //SPIÄ£Ä⺯Êý£¬Ð´Ò»¸ö8bitµÄÊý¾Ý { unsigned char buf; unsigned char i; for(i=0;i<8;i++) { buf=(byte>>(7-i))&0x1; SPI_DCLK(0); SPI_SDA(buf); SPI_DCLK(1); } } void LCD_WriteRegIndex(unsigned char Index) //дÃüÁîµÄ²ÎÊý { SPI_CS(0); LCD_WriteByteSPI(0X70); LCD_WriteByteSPI(0); LCD_WriteByteSPI(Index); SPI_CS(1); } void LCD_WriteData(unsigned short dat) //дÊý¾Ý { SPI_CS(0); LCD_WriteByteSPI(0X72); LCD_WriteByteSPI(dat>>8); // start byte RS=1,RW=0----Write a GRAM data LCD_WriteByteSPI(dat); SPI_CS(1); } void LCD_WR_REG(unsigned int Index,unsigned int CongfigTemp) { LCD_WriteRegIndex(Index); LCD_WriteData(CongfigTemp); } void Lcd_SetCursor(unsigned short x,unsigned short y) { LCD_WriteRegIndex(0x20); LCD_WriteData(x);//ˮƽ×ø±ê LCD_WriteRegIndex(0x21); LCD_WriteData(y);//´¹Ö±×ø±ê } void BlockWrite(unsigned int Xstart,unsigned int Xend,unsigned int Ystart,unsigned int Yend) { //ILI9328 LCD_WR_REG(0x0050,Xstart);//ˮƽGRAMÆðʼλÖà LCD_WR_REG(0x0051,Xend); //ˮƽGRAMÖÕֹλÖà LCD_WR_REG(0x0052,Ystart);//´¹Ö± GRAMÆðʼλÖà LCD_WR_REG(0x0053,Yend); //´¹Ö±GRAMÖÕֹλÖà Lcd_SetCursor(Xstart, Ystart); LCD_WriteRegIndex(0x022); } void Lcd_ColorBox(unsigned int xStart,unsigned int yStart,unsigned int xLong,unsigned int yLong,unsigned int Color) { unsigned int temp; BlockWrite(xStart,xStart+xLong-1,yStart,yStart+yLong-1); SPI_CS(0); LCD_WriteByteSPI(0X72); for (temp=0; temp<xLong*yLong; temp++) { LCD_WriteByteSPI(Color>>8); // start byte RS=1,RW=0----Write a GRAM data LCD_WriteByteSPI(Color); } SPI_CS(1); } void LCD_Initial(void) //LCD³õʼ»¯º¯Êý { Lcd_Reset(); //************* Start Initial Sequence **********// LCD_WR_REG(0x0001, 0x0000); // set SS and SM bit LCD_WR_REG(0x0002, 0x0700); // set 1 line inversion LCD_WR_REG(0x0003, 0x1030); // set GRAM write direction and BGR=1. 0001 0000 0011 0000 LCD_WR_REG(0x0004, 0x0000); // Resize register LCD_WR_REG(0x0008, 0x0202); // set the back porch and front porch LCD_WR_REG(0x0009, 0x0000); // set non-display area refresh cycle ISC[3:0] LCD_WR_REG(0x000A, 0x0000); // FMARK function LCD_WR_REG(0x000C, 0x0000); // RGB interface setting LCD_WR_REG(0x000D, 0x0000); // Frame marker Position LCD_WR_REG(0x000F, 0x0000); // RGB interface polarity //*************Power On sequence ****************// LCD_WR_REG(0x0010, 0x0000); // SAP, BT[3:0], AP, DSTB, SLP, STB LCD_WR_REG(0x0011, 0x0007); // DC1[2:0], DC0[2:0], VC[2:0] LCD_WR_REG(0x0012, 0x0000); // VREG1OUT voltage LCD_WR_REG(0x0013, 0x0000); // VDV[4:0] for VCOM amplitude LCD_WR_REG(0x0007, 0x0001); HAL_Delay(200); // Dis-charge capacitor power voltage LCD_WR_REG(0x0010, 0x1690); // SAP, BT[3:0], AP, DSTB, SLP, STB LCD_WR_REG(0x0011, 0x0227); // Set DC1[2:0], DC0[2:0], VC[2:0] HAL_Delay(50); // Delay 50ms LCD_WR_REG(0x0012, 0x009D); // External reference voltage= Vci; HAL_Delay(50); // Delay 50ms LCD_WR_REG(0x0013, 0x1A00); // VDV[4:0] for VCOM amplitude LCD_WR_REG(0x0029, 0x001D); // VCM[5:0] for VCOMH LCD_WR_REG(0x002B, 0x000D); // Set Frame Rate HAL_Delay(50); // Delay 50ms LCD_WR_REG(0x0020, 0x0000); // GRAM horizontal Address LCD_WR_REG(0x0021, 0x0000); // GRAM Vertical Address // ----------- Adjust the Gamma Curve ----------// LCD_WR_REG(0x0030, 0x0000); LCD_WR_REG(0x0031, 0x0607); LCD_WR_REG(0x0032, 0x0305); LCD_WR_REG(0x0035, 0x0000); LCD_WR_REG(0x0036, 0x1604); LCD_WR_REG(0x0037, 0x0204); LCD_WR_REG(0x0038, 0x0001); LCD_WR_REG(0x0039, 0x0707); LCD_WR_REG(0x003C, 0x0000); LCD_WR_REG(0x003D, 0x000F); //------------------ Set GRAM area ---------------// LCD_WR_REG(0x0050, 0x0000); // Horizontal GRAM Start Address LCD_WR_REG(0x0051, 0x00EF); // Horizontal GRAM End Address LCD_WR_REG(0x0052, 0x0000); // Vertical GRAM Start Address LCD_WR_REG(0x0053, 0x013F); // Vertical GRAM Start Address LCD_WR_REG(0x0060, 0x2700); // Gate Scan Line LCD_WR_REG(0x0061, 0x0001); // NDL,VLE, REV LCD_WR_REG(0x006A, 0x0000); // set scrolling line //-------------- Partial Display Control ---------// LCD_WR_REG(0x0080, 0x0000); LCD_WR_REG(0x0081, 0x0000); LCD_WR_REG(0x0082, 0x0000); LCD_WR_REG(0x0083, 0x0000); LCD_WR_REG(0x0084, 0x0000); LCD_WR_REG(0x0085, 0x0000); //-------------- Panel Control -------------------// LCD_WR_REG(0x0090, 0x0010); LCD_WR_REG(0x0092, 0x0600); LCD_WR_REG(0x0007, 0x0133); // 262K color and display ON HAL_Delay(10); //============´ÓÓÒµ½×ó´Óϵ½ÉÏ============// // LCD_WR_REG(0x0001, 0x0100); // LCD_WR_REG(0x03,0x1008);//MX, MY, RGB mode //============´Ó×óµ½ÓÒ´Óϵ½ÉÏ============// // LCD_WR_REG(0x0001, 0x0100); // LCD_WR_REG(0x03,0x1018);//MX, MY, RGB mode //============´ÓÓÒµ½×ó´ÓÉϵ½ÏÂ============// // LCD_WR_REG(0x0001, 0x0100); // LCD_WR_REG(0x03,0x1028);//MX, MY, RGB mode //============´Ó×óµ½ÓÒ´ÓÉϵ½ÏÂ============// // LCD_WR_REG(0x0001, 0x0100); // LCD_WR_REG(0x03,0x1038);//MX, MY, RGB mode //============´Ó×óµ½ÓÒ´ÓÉϵ½ÏÂ============// // LCD_WR_REG(0x0001, 0x0100);// set SS and SM bit // LCD_WR_REG(0x03,0x1030);//MX, MY, RGB mode set GRAM write direction and BGR=1. // Lcd_Light_ON;//´ò¿ª±³¹â // LCD_WR_REG(0x0001, 0x0100); // LCD_WR_REG(0x03,0x1008);//MX, MY, RGB mode } void LCD_Fill_Pic(unsigned int x, unsigned int y,unsigned int pic_H, unsigned int pic_V, const unsigned char* pic) { //DMA ·½Ê½ // BlockWrite(x,x+pic_H-1,y,y+pic_V-1); // TK80_DMA_Init((u32)pic,pic_H*pic_V);//DMA³õʼ»¯ // while((DMA2->ISR & 0x20)==0); // DMA2->IFCR |=1<<5; //========= ÂÖѯ·½Ê½=========// unsigned long i; unsigned long j; BlockWrite(x,x+pic_H-1,y,y+pic_V-1); j= pic_H*pic_V*2; SPI_CS(0); LCD_WriteByteSPI(0X72); for (i = 0; i <j; i++) { LCD_WriteByteSPI(pic[i]); } SPI_CS(1); } //=============== ÔÚx£¬y ×ø±êÉÏ´òÒ»¸öÑÕɫΪColorµÄµã =============== void DrawPixel(unsigned int x, unsigned int y, int Color) { BlockWrite(x,x,y,y); SPI_CS(0); LCD_WriteByteSPI(0X72); LCD_WriteByteSPI(Color>>8); LCD_WriteByteSPI(Color); SPI_CS(1); } void SPILCD_ShowChar(unsigned short x,unsigned short y,unsigned char num, unsigned int fColor, unsigned int bColor,unsigned char flag) { unsigned char temp; unsigned int pos,i,j; num=num-' ';//µÃµ½Æ«ÒƺóµÄÖµ i=num*16; for(pos=0;pos<16;pos++) { temp=nAsciiDot[i+pos]; //µ÷ͨµ÷ÓÃASCII×ÖÌå for(j=0;j<8;j++) { if(temp&0x80) DrawPixel(x+j,y,fColor); else if(flag) DrawPixel(x+j,y,bColor); //Èç¹û±³¾°É«±êÖ¾flagΪ1 temp<<=1; } y++; } } void PutGB1616(unsigned short x, unsigned short y, unsigned char c[2], unsigned int fColor,unsigned int bColor,unsigned char flag) { unsigned int i,j,k; unsigned short m; for (k=0;k<200;k++) { //64±êʾ×Ô½¨ºº×Ö¿âÖеĸöÊý£¬Ñ»·²éѯÄÚÂë if ((codeGB_16[k].Index[0]==c[0])&&(codeGB_16[k].Index[1]==c[1])) { for(i=0;i<32;i++) { m=codeGB_16[k].Msk[i]; for(j=0;j<8;j++) { if((m&0x80)==0x80) { DrawPixel(x+j,y,fColor); } else { if(flag) DrawPixel(x+j,y,bColor); } m=m<<1; } if(i%2){y++;x=x-8;} else x=x+8; } } } } void LCD_PutString(unsigned short x, unsigned short y, char *s, unsigned int fColor, unsigned int bColor,unsigned char flag) { unsigned char l=0; while(*s) { if( (unsigned char)*s < 0x80) { SPILCD_ShowChar(x+l*8,y,*s,fColor,bColor,flag); s++;l++; } else { PutGB1616(x+l*8,y,(unsigned char*)s,fColor,bColor,flag); s+=2;l+=2; } } }
main
int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); // LCD_GPIO_Config(); LCD_Initial(); Lcd_ColorBox(0,0,XSIZE_PHYS,YSIZE_PHYS,Blue);//ÓÃÀ¶É«ÇåÆÁ // HAL_Delay(500); Lcd_ColorBox(0,0,XSIZE_PHYS,YSIZE_PHYS,Red);//ÓúìÉ«ÇåÆÁ // HAL_Delay(500); Lcd_ColorBox(0,0,XSIZE_PHYS,YSIZE_PHYS,Green);//ÓÃÂÌÉ«ÇåÆÁ // HAL_Delay(500); Lcd_ColorBox(0,0,XSIZE_PHYS,YSIZE_PHYS,White);//Óð×É«ÇåÆÁ LCD_PutString(20,10,"STM32G474Test",Red,White,0); LCD_PutString(20,30,"I LOVE EEPW",Red,White,0); while(1); }
视频:
https://www.bilibili.com/video/BV1TuZJYQEX3/