1) i80-system MPU 接口(8-/9-/16-/18-bit bus width)
2) serial data transfer 接口(SPI)
3) RGB 6-/16-/18-bit 接口(DOTCLK, VSYNC, HSYNC, ENABLE, DB[17:0]).
此屏的ILI9341的18位RGB赋值与 LCD GRAM的对应关系如图所示: 
从图中可以看出,ILI9341 在16 位模式下面,GRAM Data有用的是:D17~D13 和 D11~D1, D12和 D0 没有用到,实际上在我们 LCD 模块里面, ILI9341 的 D12 和 D0没有引出,ILI9341 的 D17~D13 和 D11~D1对应 MCU 的 D15~D0。MCU 的 16 位数据,最低 5 位代表蓝色,中间 6 位为绿色,最高 5 位为红色;数值越大,表示该颜色越深。
8080接口是由英特尔设计,是一种并行、异步、半双工通信协议,作用是用于外扩RAM、ROM,后面也用于LCD接口。
RD:写使能(将信息写入寄存器) WR:读使能(从寄存器读出信息) DC(RS):数据/命令(1为数据读写,0为命令读写) CS:片选
| 引脚号 | 标识 | 描述 | 功能 |
| 1 | 5V | 5V电源 | 当5V供电时(1,2脚接5V电源),3.3V端(33,34脚输出3.3V电压) |
| 2 | GND | 接地 | GND |
| 3 | D0 | 数据线 | D0-D15 |
| 4 | D1 | ||
| 5 | D2 | ||
| 6 | D3 | ||
| 7 | D4 | ||
| 8 | D5 | ||
| 9 | D6 | ||
| 10 | D7 | ||
| 11 | D8 | ||
| 12 | D9 | ||
| 13 | D10 | ||
| 14 | D11 | ||
| 15 | D12 | ||
| 16 | D13 | ||
| 17 | D14 | ||
| 18 | D15 | ||
| 19 | CS | LCD片选信号 | 低电平选择LCD |
| 20 | RS | 指令/数据 寄存器选择 | RS = 0:指令寄存器 RS = 1:数据寄存器 |
| 21 | WR | 写动作 | WR = 0,RD = 1 |
| 22 | RD | 读动作 | WR = 1,RD = 0 |
| 23 | RESET | 芯片重启 | 低电平重启芯片 |
| 24 | NC | ||
| 25 | BLVCC | 5V或3.3V | 背光灯VCC |
| 26 | BLGND | 接地 | 背光灯GND |
| 27 | BLCNT | 背光灯亮度调节 | 可以使用PWM来控制背光灯亮度 |
| 28 | TP_IRQ | 触摸面板中断 | 检测到触摸面板有按下则为低电平 |
| 29 | TP_CS | 触摸面板片选信号 | 低电平选择触摸面板 |
| 30 | TP_SCK | 触摸面板SPI时钟信号 | 连接到SPI的SCK |
| 31 | TP_SI | 触摸面板SPI数据输入 | 连接到SPI的MOSI |
| 32 | TP_SO | 触摸面板SPI数据输出 | 连接到SPI的MISO |
| 33 | 3.3V | +3.3电源 | 当3.3V供电时(33,34脚输入3.3V) 1,2脚悬空 |
| 34 | GND | 接地 |
本手册使用主控芯片STM32F103RCT6的开发板说明本款LCD的基本使用方法。用户也可以采用其他类似的开发板进行开发。
3.2inch 320x240 Touch LCD (D)和STM32F103RCT6连接接口图:
程序流程:
源代码解析:
/*下面宏定义的是图像的旋转角度跟设置控制线*/<br />
//#define DISP_ORIENTATION 0
//#define DISP_ORIENTATION 90
//#define DISP_ORIENTATION 180
#define DISP_ORIENTATION 270
#define Set_Cs GPIOC->BSRR = GPIO_Pin_6 //CS=1
#define Clr_Cs GPIOC->BRR = GPIO_Pin_6 //CS=0
#define Set_Rs GPIOC->BSRR = GPIO_Pin_7 //RS=1
#define Clr_Rs GPIOC->BRR = GPIO_Pin_7 //RS=0
#define Set_nWr GPIOC->BSRR = GPIO_Pin_1 //WR=1
#define Clr_nWr GPIOC->BRR = GPIO_Pin_1 //WR=0
#define Set_nRd GPIOC->BSRR = GPIO_Pin_2 //RD=1
#define Clr_nRd GPIOC->BRR = GPIO_Pin_2 //RD=0
/* 写命令函数 */
__inline void LCD_WriteIndex(uint16_t index)
{
Clr_Rs; //RS=0
Set_nRd; //RD=0
LCD_Delay(0); //延时
GPIOB->ODR = index; /*写命令 */
LCD_Delay(0); //延时
Clr_nWr; //WR=0
Set_nWr; //WR=1
}
/* 写数据函数 */
__inline void ILI9341_LCD_WriteData(uint16_t data)
{
Clr_Cs; //CS=1
Set_Rs; //RS=1
LCD_Delay(0); //delay
GPIOB->ODR = data; /* GPIO_Write(GPIOB,data); */
LCD_Delay(0); //delay
Clr_nWr; //WR=0
Set_nWr; //WR=1
Set_Cs; //CS=1
}
/* 读数据函数 */
__inline uint16_t LCD_ReadData(void)
{
uint16_t value;
Set_Rs;
Set_nWr;
Clr_nRd;
GPIOB->CRH = 0x44444444; //设置PB0-PB15为输入
GPIOB->CRL = 0x44444444;
value = GPIOB->IDR; //读取数据
GPIOB->CRH = 0x33333333; //设置PB0-PB15为输出
GPIOB->CRL = 0x33333333;
Set_nRd;
return value;
}
/******************************************************************************
指定的地址写入数据,LCD_Reg是地址,LCD_RegValue是写入的值。
******************************************************************************/
__inline void LCD_WriteReg(uint16_t LCD_Reg,uint16_t LCD_RegValue)
{
Clr_Cs;
LCD_WriteIndex(LCD_Reg); //写指令;即要写入数据的地址;
LCD_WriteData(LCD_RegValue); //数据写入;
Set_Cs;
}
/******************************************************************************
从指定的地址读取数据,LCD_Reg是地址,函数返回读取出来的值。
<pre>
******************************************************************************/
__inline uint16_t LCD_ReadReg(uint16_t LCD_Reg)
{
uint16_t LCD_RAM;
Clr_Cs;
LCD_WriteIndex(LCD_Reg); //写指令;即要读出数据的地址;
LCD_RAM = LCD_ReadData(); //数据读出;
Set_Cs;
return LCD_RAM;
}
//以上是最基本的读写函数;IO模拟操作,如果想STM32的FSMC来控制的,参考另外一个例程LCD + TouchPanel(8080 FSMC)
/******************************************************************************
LCD寄存器的初始化,以下寄存器的初始化值由LCD原厂家提供,按照如下配置就可以正常显示,寄存器请参考芯片手册。
******************************************************************************/
void LCD_Initializtion(void)
{
uint16_t DeviceCode;
LCD_Configuration(); //管脚初始化
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);//改变指定管脚的映射
GPIO_ResetBits(GPIOC, GPIO_Pin_0); /* LCD复位*/
delay_ms(100);
GPIO_SetBits(GPIOC, GPIO_Pin_0);
GPIO_SetBits(GPIOA, GPIO_Pin_3); /*使能背光 */
DeviceCode = LCD_ReadReg(0x0000); /* 读取ID */
if(DeviceCode == 0 || DeviceCode == 0xffff)
{
ILI9341_LCD_WriteReg(0XD3);
Clr_Cs;
DeviceCode = LCD_ReadData();
DeviceCode = LCD_ReadData();
DeviceCode = LCD_ReadData();
DeviceCode <<= 8;
DeviceCode |= LCD_ReadData();
Set_Cs;
}
if(DeviceCode == 0x9341)
{
LCD_Code = ILI9341;
ILI9341_LCD_WriteReg(0x3A);
ILI9341_LCD_WriteData(0x55);
ILI9341_LCD_WriteReg(0xB5);
ILI9341_LCD_WriteData(0X04);
ILI9341_LCD_WriteData(0X04);
ILI9341_LCD_WriteData(0X0A);
ILI9341_LCD_WriteData(0x14);
ILI9341_LCD_WriteReg(0x35);
ILI9341_LCD_WriteData(0x00);
ILI9341_LCD_WriteReg(0xCF);
ILI9341_LCD_WriteData(0x00);
ILI9341_LCD_WriteData(0xEA);
ILI9341_LCD_WriteData(0XF0);
ILI9341_LCD_WriteReg(0xED);
ILI9341_LCD_WriteData(0x64);
ILI9341_LCD_WriteData(0x03);
ILI9341_LCD_WriteData(0X12);
ILI9341_LCD_WriteData(0X81);
ILI9341_LCD_WriteReg(0xE8);
ILI9341_LCD_WriteData(0x85);
ILI9341_LCD_WriteData(0x10);
ILI9341_LCD_WriteData(0x78);
ILI9341_LCD_WriteReg(0xCB);
ILI9341_LCD_WriteData(0x39);
ILI9341_LCD_WriteData(0x2C);
ILI9341_LCD_WriteData(0x00);
ILI9341_LCD_WriteData(0x33);
ILI9341_LCD_WriteData(0x06);
ILI9341_LCD_WriteReg(0xF7);
ILI9341_LCD_WriteData(0x20);
ILI9341_LCD_WriteReg(0xEA);
ILI9341_LCD_WriteData(0x00);
ILI9341_LCD_WriteData(0x00);
ILI9341_LCD_WriteReg(0xC0); //Power control
ILI9341_LCD_WriteData(0x21); //VRH[5:0]
ILI9341_LCD_WriteReg(0xC1); //Power control
ILI9341_LCD_WriteData(0x10); //SAP[2:0];BT[3:0]
ILI9341_LCD_WriteReg(0xC5); //VCM control
ILI9341_LCD_WriteData(0x4F); //3F
ILI9341_LCD_WriteData(0x38); //3C
ILI9341_LCD_WriteReg(0xC7); //VCM control2
ILI9341_LCD_WriteData(0XB7);
ILI9341_LCD_WriteReg(0x36); // Memory Access Control
if (DISP_ORIENTATION == 0)
ILI9341_LCD_WriteData(0x08 | 0x00);
else if (DISP_ORIENTATION == 90)
ILI9341_LCD_WriteData(0x08 | 0xa0);
else if(DISP_ORIENTATION == 180)
ILI9341_LCD_WriteData(0x08 | 0xc0);
else
ILI9341_LCD_WriteData(0x08 | 0x60);
ILI9341_LCD_WriteReg(0xB1);
ILI9341_LCD_WriteData(0x00);
ILI9341_LCD_WriteData(0x13);
ILI9341_LCD_WriteReg(0xB6); // Display Function Control
ILI9341_LCD_WriteData(0x0A);
ILI9341_LCD_WriteData(0xA2);
ILI9341_LCD_WriteReg(0xF2); // 3Gamma Function Disable
ILI9341_LCD_WriteData(0x02);
ILI9341_LCD_WriteReg(0x26); //Gamma curve selected
ILI9341_LCD_WriteData(0x01);
ILI9341_LCD_WriteReg(0xE0); //Set Gamma
ILI9341_LCD_WriteData(0x0F);
ILI9341_LCD_WriteData(0x27);
ILI9341_LCD_WriteData(0x24);
ILI9341_LCD_WriteData(0x0C);
ILI9341_LCD_WriteData(0x10);
ILI9341_LCD_WriteData(0x08);
ILI9341_LCD_WriteData(0x55);
ILI9341_LCD_WriteData(0X87);
ILI9341_LCD_WriteData(0x45);
ILI9341_LCD_WriteData(0x08);
ILI9341_LCD_WriteData(0x14);
ILI9341_LCD_WriteData(0x07);
ILI9341_LCD_WriteData(0x13);
ILI9341_LCD_WriteData(0x08);
ILI9341_LCD_WriteData(0x00);
ILI9341_LCD_WriteReg(0XE1); //Set Gamma
ILI9341_LCD_WriteData(0x00);
ILI9341_LCD_WriteData(0x0F);
ILI9341_LCD_WriteData(0x12);
ILI9341_LCD_WriteData(0x05);
ILI9341_LCD_WriteData(0x11);
ILI9341_LCD_WriteData(0x06);
ILI9341_LCD_WriteData(0x25);
ILI9341_LCD_WriteData(0x34);
ILI9341_LCD_WriteData(0x37);
ILI9341_LCD_WriteData(0x01);
ILI9341_LCD_WriteData(0x08);
ILI9341_LCD_WriteData(0x07);
ILI9341_LCD_WriteData(0x2B);
ILI9341_LCD_WriteData(0x34);
ILI9341_LCD_WriteData(0x0F);
ILI9341_LCD_WriteReg(0x11); //Exit Sleep
delay_ms(120);
ILI9341_LCD_WriteReg(0x29); //display on
}
delay_ms(50);
}
/******************************************************************************
设置显示窗口的位置X、Y;
*****************************************************************************/
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
{
ILI9341_LCD_WriteReg(0x2a);//Column address setting 列地址设置
ILI9341_LCD_WriteData(x1>>8);
ILI9341_LCD_WriteData(x1&0xff);
ILI9341_LCD_WriteData(x2>>8);
ILI9341_LCD_WriteData(x2&0xff);
ILI9341_LCD_WriteReg(0x2b);//Line address Setting 行地址设置
ILI9341_LCD_WriteData(y1>>8);
ILI9341_LCD_WriteData(y1&0xff);
ILI9341_LCD_WriteData(y2>>8);
ILI9341_LCD_WriteData(y2&0xff);
ILI9341_LCD_WriteReg(0x2c);//Write in memory 写入内存
}
static void LCD_SetCursor( uint16_t Xpos, uint16_t Ypos )
{
uint16_t temp;
#if (DISP_ORIENTATION == 0)
#elif (DISP_ORIENTATION == 90)
temp = Xpos;
Xpos =Ypos;
Ypos = MAX_X - 1 - temp;
#elif (DISP_ORIENTATION == 180)
Xpos = MAX_X - 1 - Xpos;
Ypos = MAX_Y - 1 - Ypos;
#elif (DISP_ORIENTATION == 270)
temp = Ypos;
Ypos = Xpos;
Xpos = MAX_Y - 1 - temp;
#endif
ILI9341_LCD_WriteReg(0x2a); //Column address setting 列地址设置
ILI9341_LCD_WriteData(Xpos>>8);
ILI9341_LCD_WriteData(Xpos&0xff);
ILI9341_LCD_WriteReg(0x2b); //Line address Setting 行地址设置
ILI9341_LCD_WriteData(Ypos>>8);
ILI9341_LCD_WriteData(Ypos&0xff);
}
/******************************************************************************
清屏函数,作用是让整个屏显示某一种颜色,
*****************************************************************************/
void LCD_Clear(uint16_t Color)
{
uint32_t index=0;
LCD_Address_Set(0,0,MAX_X-1,MAX_Y-1);//Set Display range Set the display range 设置显示范围
for( index = 0; index < MAX_X * MAX_Y; index++ )
{
ILI9341_LCD_WriteData(Color);
}
}
int main(void)
{
//延时和初始化系统
LCD_Initializtion(); //LCD初始化
//LCD触摸板初始化
LCD_Clear(Red); //清屏为红色
//您可以编写函数来校准屏幕。
/* Infinite loop */
while (1)
{
//您可以编写函数,把触摸点坐标显示在 LCD 上
}
}