简介
ILI9341是一款分辨率为240x320 分辨率的a- tft液晶显示单片SOC驱动,由720通道源驱动、320通道门驱动、172800字节GRAM (240RGBx320点位图形显示数据)和电源电路组成。
ILI9341支持并行8-/9-/16-/18位数据总线MCU接口,6-/16-/18位数据总线RGB接口和3 /4线串行外围接口SPI通讯。通过窗口地址函数可以在内部GRAM中指定运动图像的区域。指定的窗口区域可以有选择地更新,使移动的图片
系统框图
显示接口
ILI9341提供了四种单片机系统接口, 其中8080- /8080Ⅰ-Ⅱ系列并行接口和3 - 4线串行接口。 给定接口的选择由外部IM[3:0]引脚完成,如下所示:
IM3 | IM2 | IM1 | IM0 | MCU-Interface Mode | Register/Content | GRAM |
---|
0 | 0 | 0 | 0 | 8080-8bit–I | D[7:0] | D[7:0],WRX,RDX,CSX,D/CX | 0 | 0 | 0 | 1 | 8080-16bit–I | D[7:0] | D[15:0],WRX,RDX,CSX,D/CX | 0 | 0 | 1 | 0 | 8080-9bit–I | D[7:0] | D[8:0],WRX,RDX,CSX,D/CX | 0 | 0 | 1 | 1 | 8080-18bit–I | D[7:0] | D[17:0],WRX,RDX,CSX,D/CX |
IM3 | IM2 | IM1 | IM0 | MCU-Interface Mode | Pins in use |
---|
0 | 1 | 0 | 1 | 3-write 9bit serial interface I | SCL,SDA,CSX | 0 | 1 | 1 | 0 | 4-write 8bit serial interface I | SCL,SDA,CSX,D/C |
IM3 | IM2 | IM1 | IM0 | MCU-Interface Mode | Register/Content | GRAM |
---|
1 | 0 | 0 | 0 | 8080-16bit–II | D[8:1] | D[17:10],D[8:1],WRX,RDX,CSX,D/CX | 1 | 0 | 0 | 1 | 8080-8bit–II | D[17:10] | D[17:10],WRX,RDX,CSX,D/CX | 1 | 0 | 1 | 0 | 8080-18bit–II | D[8:1] | D[17:0],WRX,RDX,CSX,D/CX | 1 | 0 | 1 | 1 | 8080-9bit–II | D[17:10] | D[17:9],WRX,RDX,CSX,D/CX |
IM3 | IM2 | IM1 | IM0 | MCU-Interface Mode | Pins in use |
---|
1 | 1 | 0 | 1 | 3-write 9bit serial interface I | SCL,SDI,SDO,CSX | 1 | 1 | 1 | 0 | 4-write 8bit serial interface I | SCL,SDI,SDO,CSX,D/C |
注意: 在8080-Ⅰ/8080-Ⅱ串并联接口中,寄存器由D[17:0]数据引脚访问。 本次驱动ILI9341显示器使用的是 SPI通讯协议 ILI9341提供3线/ 9位和4线/8位双向串行接口,用于主机与ILI9341通信。
3线串行模式由芯片使能输入(CSX),串行时钟输入(SCL)和串行数据输入/输出(SDA或SDI/SDO)组成。
4线串行模式包括数据/命令选择输入(D/CX),芯片使能输入(CSX),串行时钟输入(SCL)和串行数据输入/输出(SDA或SDI/SDO)进行数据传输。
未使用的数据总线(D[17:0])必须连接到GND。串行时钟(SCL)仅用于与MCU的接口
写入数据/命令
接口的写模式是指主机向ILI9341写入命令或数据。3线/3 PIN 串行数据包包含一个数据/命令选择位(D/CX)和一个传输字节。如果D/CX位为“low”,则传输字节被解释为命令字节。如果D/CX位为“高”,则传输字节存储为显示数据RAM(内存写命令),或命令寄存器作为参数。
3线串行通讯
缩写 | 含义 |
---|
SCL | 时钟线 | SDA | 数据线 | CSX | 芯片输入使能 |
4线串行通讯
缩写 | 含义 |
---|
SCL | 时钟线 | SDA | 数据线 | D/C | 数据命令选择 | CSX | 芯片输入使能 |
时序分析: 三线SPI通讯协议时序 四线SPI通讯协议时序
Rgb 接口
ILI9341有两种RGB接口,这两种接口可以通过RCM[1:0]位进行选择。当RCM[1:0]位设置为“10”时,DE模式被选择,使用VSYNC, HSYNC, DOTCLK, DE, D[17:0]引脚;当RCM[1:0]位设置为“11”,选择同步模式,使用垂直同步,高度同步,DOTCLK, D [17:0] pin。使用RGB接口时必须选择串行接口。 Rgb位数与编码表之间的关系 像素时钟(DOTCLK)一直不停地运行,用于输入垂直同步、HSYNC、DE和D[17:0]说明DOTCLK何时有上升边缘,垂直同步(VSYNC)用于告知何时收到了显示的新帧。这是低使能,它的状态是通过DOTCLK信号的上升边缘读取到显示模块。
水平同步(HSYNC)用于告知何时接收到帧的新行。这是低使能,它的状态是通过DOTCLK信号的上升边缘读取到显示模块。
在DE模式下,数据启用(DE)用来告诉何时有接收到的RGB信息应该在显示器上传输。这是一个高使能,它的状态通过DOTCLK信号的上升边缘读取到显示模块。D[17:0]是用来告诉在显示器上传输的图像的信息是什么(当DE= ’ 0 ‘(低),DOTCLK有上升边)。D[17:0]可以是’ 0 ‘(低)或’ 1 '(高)。这些行由DOTCLK信号的上升边读取。
在SYNC模式下,根据HSYNC信号的HFP/HBP设置和VSYNC的VFP/VBP设置,通过D[17:0]以像素单位输入的有效显示数据。在两种RGB接口模式下,输入显示数据先写入GRAM,然后根据GRAM的灰色数据输出相应的源电压。
指令表内容
1.一级指令说明:
Description of Level 1 Command
1. 空指令(00h)
此命令为空命令;对显示模块没有任何影响。但是它可以用来终止帧内存写或读在RAMWR(内存写)和RAMRD(内存读)命令中描述。
2. 软件复位(01h)
当软件复位命令被写入时,它会导致软件复位。它将命令和参数重置为它们的 S/W重置默认值。(参见每个命令描述中的默认表。) 注意:帧内存内容不受此命令影响;X =不在乎。
3.读取显示标识信息(04h)
这个读字节返回24位显示标识信息。 第1个参数是虚拟数据。 第2个参数(ID1 [7:0]): LCD模块的制造商ID。 第3个参数(ID2 [7:0]): LCD模块/驱动版本ID。 第4个参数(ID3 [7:0]): LCD模块/驱动ID。
4.读取显示状态(09h)
5. 读取显示功率模式(0Ah)
6.读取显示的内存寻址模式(0Bh)
7.读取显示像素格式(0Ch)
8. 读取显示图像格式(0Dh)
9.读取显示信号模式(0Eh)
10.读取显示自诊断结果(0Fh)
2.配置一些LCD的配置和模式:
1.进入睡眠模式(10h)
2.退出睡眠模式(11h)
3.部分模式开启(12h)
4. 正常显示模式ON(13h)
5.显示反转关闭(20h)
6.显示反转ON (21h)
7.Gamma 设定(26h)
8.显示 关闭(28 h)
9.显示开启(29h)
10. 列地址设定(2Ah)
11.页地址集设定
12. 内存写 (2Ch)
13.颜色设置(2dh)
14. 内存读(2Eh)
其他
…其余的值列表参照芯片手册。
代码部分
- 配置GPIO引脚模式
- 初始化控制引脚
- 创建SPI模拟时序
- 发送SPI数据
- 关联LCD 写数据、写命令
- 拓展16bit数据发送
- 初始化LCD
- 设置点
- 设置GUI
具体代码如下:
#include "ili9341.h"
#include "delay.h"
void Lcd_Init(void)
{
LCD_SPI_GPIO_Init();
Lcd_Reset();
Lcd_WriteIndex(0x11);
LCD_WriteData(0x00);
Lcd_WriteIndex(0xCF);
LCD_WriteData(0X00);
LCD_WriteData(0XC1);
LCD_WriteData(0X30);
Lcd_WriteIndex(0xED);
LCD_WriteData(0X54);
LCD_WriteData(0X03);
LCD_WriteData(0X12);
LCD_WriteData(0X81);
Lcd_WriteIndex(0xE8);
LCD_WriteData(0X85);
LCD_WriteData(0X11);
LCD_WriteData(0X78);
Lcd_WriteIndex(0xF6);
LCD_WriteData(0X01);
LCD_WriteData(0X30);
LCD_WriteData(0X00);
Lcd_WriteIndex(0xCB);
LCD_WriteData(0X39);
LCD_WriteData(0X2C);
LCD_WriteData(0X00);
LCD_WriteData(0X34);
LCD_WriteData(0X05);
Lcd_WriteIndex(0xF7);
LCD_WriteData(0X20);
Lcd_WriteIndex(0xEA);
LCD_WriteData(0X00);
LCD_WriteData(0X00);
Lcd_WriteIndex(0xC0);
LCD_WriteData(0X20);
Lcd_WriteIndex(0xC1);
LCD_WriteData(0X11);
Lcd_WriteIndex(0xC5);
LCD_WriteData(0X31);
LCD_WriteData(0X3C);
Lcd_WriteIndex(0xC7);
LCD_WriteData(0XA9);
Lcd_WriteIndex(0x3A);
LCD_WriteData(0X55);
Lcd_WriteIndex(0x36);
#if USE_HORIZONTAL
LCD_WriteData(0xE8);
#else
LCD_WriteData(0x48);
#endif
Lcd_WriteIndex(0xB1);
LCD_WriteData(0X00);
LCD_WriteData(0X18);
Lcd_WriteIndex(0xB4);
LCD_WriteData(0X00);
LCD_WriteData(0X00);
Lcd_WriteIndex(0xF2);
LCD_WriteData(0X02);
Lcd_WriteIndex(0x26);
LCD_WriteData(0X01);
Lcd_WriteIndex(0xE0);
LCD_WriteData(0X0F);
LCD_WriteData(0X17);
LCD_WriteData(0X14);
LCD_WriteData(0X09);
LCD_WriteData(0X0C);
LCD_WriteData(0X06);
LCD_WriteData(0X43);
LCD_WriteData(0X75);
LCD_WriteData(0X36);
LCD_WriteData(0X08);
LCD_WriteData(0X13);
LCD_WriteData(0X05);
LCD_WriteData(0X10);
LCD_WriteData(0X0B);
LCD_WriteData(0X08);
Lcd_WriteIndex(0xE1);
LCD_WriteData(0X00);
LCD_WriteData(0X1F);
LCD_WriteData(0X23);
LCD_WriteData(0X03);
LCD_WriteData(0X0E);
LCD_WriteData(0X04);
LCD_WriteData(0X39);
LCD_WriteData(0X25);
LCD_WriteData(0X4D);
LCD_WriteData(0X06);
LCD_WriteData(0X0D);
LCD_WriteData(0X0B);
LCD_WriteData(0X33);
LCD_WriteData(0X37);
LCD_WriteData(0X0F);
Lcd_WriteIndex(0x29);
}
void Lcd_SetXY(u16 Xpos, u16 Ypos)
{
Lcd_WriteIndex(0x2A);
LCD_WriteData_16Bit(Xpos);
Lcd_WriteIndex(0x2B);
LCD_WriteData_16Bit(Ypos);
Lcd_WriteIndex(0x2c);
}
void Lcd_SetRegion(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd)
{
Lcd_WriteIndex(0x2A);
LCD_WriteData_16Bit(xStar);
LCD_WriteData_16Bit(xEnd);
Lcd_WriteIndex(0x2B);
LCD_WriteData_16Bit(yStar);
LCD_WriteData_16Bit(yEnd);
Lcd_WriteIndex(0x2c);
}
void LCD_Color_Fill(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd,u16 color)
{
int i,j;
Lcd_SetRegion(xStar,yStar,xEnd,yEnd);
for(i = 0; i<=(xEnd-xStar); i ++)
{
for(j =0 ;j<=(yEnd-yStar);j ++)
{
LCD_WriteData_16Bit(color);
}
}
}
void Gui_DrawPoint(u16 x,u16 y,u16 Data)
{
Lcd_SetXY(x,y);
LCD_WriteData_16Bit(Data);
}
void Lcd_Clear(u16 Color)
{
unsigned int i;
Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
LCD_CS_CLR;
LCD_RST_SET;
for(i=0;i<X_MAX_PIXEL*Y_MAX_PIXEL;i++)
{
LCD_WriteData_16Bit(Color);
}
LCD_CS_SET;
}
显示效果如下:
|