NT35310 - LCD显示屏
芯片介绍\引脚介绍
NT35310 是一个低功耗、26 万色、单芯片的 TFT-LCD 控制器/驱动器,分辨率 480*320,它有一个 345600 字节的显示 RAM 和一整套控制功能。NT35310 支持数字接口(MDDI),MIPI 接口,RGB 接口,8 / 9 / 16 / 18 位8080 接口。可以实现指定的窗口区域可以有选择地更新,以便可以显示运动图像。同时也可以独立显示静止的图像区域。
8080时序
8080 总线又叫Intel(英特尔开发)总线。它控制线有四根,RD 写使能, WR 读使能, ALE 地址锁存, CS 片选。
详细介绍见协议使用笔记8080总线篇。
此处采用模拟8080时序作为介绍,该时序可由硬件FSMC模拟得,读写速度远优于模拟时序,关于FSMC相关介绍及使用,请参照STM32f10x开发笔记FSMC篇。
写时序
- CS:片选线,数据传输时,片选拉低
- WR:写数据/命令线,写数据时将WR拉低
- RS:数据/命令线,高为数据,低为命令
- D[0:15]:16位数据线
- RD:读数据线,写时将RD拉高
读时序
同上介绍
初始化流程
初始化GPIO -> 延时100ms -> 发送初始化序列 (手册提供)
控制指令介绍
注意!!!:指令和参数均为16位,但除0x2C后发送的颜色数据外,均只使用低八位。
读取ID指令
- 0xD3
可通过该指令可获取LCD屏的出厂ID,可用于分辨屏幕。发送该指令后,可接收自屏幕发送来的32bit数据。
存储访问控制指令
- 0x36
该指令为存储访问控制指令,可以控制 ILI9341 存储器的读写方向,简单的说,就是在连续写 GRAM 的时候,可以控制 GRAM 指针的增长方向,从而控制显示方式(读 GRAM 也是一样)[呈现效果]。
其发送的参数中 D7 D6 和 D5 位分别表示 MY MX 和 MV,通过这三个位可以控制指针增长方向。详细如下:
MY MX MV 呈现效果 0 0 0 从左到右,从上到下 1 0 0 从左到右,从下到上 0 1 0 从右到左,从上到下 1 1 0 从右到左,从下到上 0 0 1 从上到下,从左到右 0 1 1 从上到下,从右到左 1 0 1 从下到上,从左到右 1 1 1 从下到上,从右到左
列地址设置指令
-
0x2A
该指令是列地址设置指令,在从左到右,从上到下的扫描方式(默认)下,该指令用于设置横坐标(x 坐标),在其它方式下可自行推导。
通常我们不对扫描方式进行更改,使用默认扫描方式。
该指令共有四个参数,前两个参数(SC)代表坐标x的起始坐标的高、低位,后两个参数(EC)代表坐标x的结束坐标的高、低位。为了节约时间,如果使用中已对x长度做要求,可以不发送后两个参数。
注意:SC 必须小于等于 EC,且 0≤SC/EC≤239。
行地址设置指令
- 0x2B
该指令是行地址设置指令,在从左到右,从上到下的扫描方式(默认)下,该指令用于设置横坐标(y 坐标),在其它方式下可自行推导。
参数介绍类比于上。
注意:SP 必须小于等于 EP,且 0≤SP/EP≤319。
写数据指令
- 0x2C
该指令是写 GRAM 指令,在发送该指令之后,我们便可以往 LCD 的 GRAM 里面写入颜色数据了,该指令支持连续写 ,地址自动递增,直到到达该行结尾或预设的EC值时进行换行。
在收到指令 0X2C 之后,数据有效位宽变为 16 位,我们可以连续写入 LCD GRAM 值,而 GRAM 的地址将根据 MY/MX/MV 设置的扫描方向进行自增。例如:假设设置的是从左到右,从上到下的扫描方式,那么设置好起始坐标(通过 SC,SP 设置)后,每写入一个颜色值,GRAM 地址将会自动自增 1(SC++),如果碰到 EC,则回到 SC,同时 SP++,一直到坐标:EC,EP 结束,其间无需再次设置的坐标,从而大大提高写入速度。
读数据指令
- 0x2E
颜色读取指令,用于读取相应坐标颜色值,可连续读,地址自增。
其收到的数据格式如下:
其中第一次收到的数据dummy为无效数据,可直接丢弃,第二第三次收到的数据中已含有全部的RGB565信息,可仅接收前三个参数,后两个参数可以不接收。
代码示例
变量介绍
LCD_DAT_OUT(n,state) //LCD并行数据输出 n为0~15,state 为0或1
LCD_DAT_IN(n) //LCD并行数据输入 n为0~15
#define LCD_CS //片选
#define LCD_WR //写
#define LCD_BL //背光
#define LCD_RS //信号、数据线
#define LCD_RD //读
#define NT35310_WR_REG(data) //写命令
#define NT35310_WR_DAT(data) //写数据
写双字
//写双字,8080总线16位数据
//写数据和写命令仅为RS线高低不同,此处为未添加RS线的通用函数,可自行封装函数
void NT35310_Write_DoubleByte(u16 tData)
{
u8 i;
LCD_RD = 1; //写时序中将读线拉高
LCD_CS = 0; //片选选中
LCD_WR = 0; //写,低电平有效
for(i = 0;i < 16;i++) //循环写入
{
if((tData & (1 << i))?1:0) LCD_DAT_OUT(i,1);
else LCD_DAT_OUT(i,0);
}
LCD_WR = 1; //重新拉高,取消写
LCD_CS = 1; //取消片选
}
读双字
//读双字,8080总线16位数据
u16 NT35310_Read_DoubleByte(void)
{
u8 i;
u16 rData = 0;
LCD_WR = 1; //读数据时将写拉高
LCD_CS = 0; //片选选中
LCD_RD = 0; //读拉低,低电平有效
for(i = 0;i < 16;i++) //读取数据
{
if(LCD_DAT_IN(i)) rData++;
rData <<= 1;
}
LCD_RD = 1; //取消读
LCD_CS = 1; //取消片选
return rData; //返回数据
}
设置读写坐标
//仅设置开始坐标
void LCD_Set_Start_PageRow_CMD(u16 x,u16 y)
{
NT35310_WR_REG(0x2A); //设置x坐标指令
NT35310_WR_DAT(x >> 8); //x起始坐标高八位,下为低八位
NT35310_WR_DAT(x);
NT35310_WR_REG(0x2B); //设置y坐标指令
NT35310_WR_DAT(y >> 8); //y起始坐标高八位,下为低八位
NT35310_WR_DAT(y);
}
//设置开始结束坐标
void LCD_SetStartEnd_PageRow_CMD(u16 x_s,u16 y_s,u16 x_e,u16 y_e)
{
NT35310_WR_REG(0x2A);
NT35310_WR_DAT(x_s >> 8);
NT35310_WR_DAT(x_s);
NT35310_WR_DAT(x_e >> 8); //设置x结束坐标,同上
NT35310_WR_DAT(x_e);
NT35310_WR_REG(0x2B);
NT35310_WR_DAT(y_s >> 8);
NT35310_WR_DAT(y_s);
NT35310_WR_DAT(y_e >> 8); //设置y结束坐标,同上
NT35310_WR_DAT(y_e);
}
画点函数
void LCD_DrawPoint(u16 x,u16 y,u16 color)
{
LCD_NT35310_OUTPUT_Init();
if((x > LCD_WIDTH) || (y > LCD_HIGHT)) return;
LCD_Set_Start_PageRow_CMD(x,y);
NT35310_WR_REG(0x2C);
NT35310_WR_DAT(color); //颜色值,16位
}
//有该函数后便有无限可能,由读者自行发挥(●'◡'●)