之前写过关于LCD屏的学习日志,当时学得很懵逼,最后先暂时跳过,把教材的例程当成库函数来用,等后面开窍了再回过头来学习一遍。回想大学学习51单片机的时候,也是觉得LCD屏很困难,我觉得新手很容易就在这里从就入门到放弃了,因为相比前面的知识,个人认为LCD算是一个比较复杂的外设,难度有阶梯式的上升。再加上学习的教材为了兼容各种驱动芯片,程序看起来比较乱。所以这次单把NT35100这款驱动芯片拎出来分析学习。
这里使用的是ATK-4.3'TFTLCD模块,他是采用NT35510芯片驱动,分辨率为800*480,自带GRAM。
ATK-4.3’ TFTLCD模块正面图
一、引脚与GRAM
它一共有34个引脚。原理图及引脚功能如下。因为LCD可以看成是一个外部SRAM,可以用STM32大容量芯片自带的FSMC(灵活的静态存储器控制器)来访问。
引脚1:LCD的片选引脚接到FSMC的片选引脚NE4,前缀N说明信号低有效,(FSMC引脚相关信息在STM32中文参考手册329页),FSMC有4个存储块,每个存储块又分为4*64MB的区,NE1~4分别对应4个区。(参考手册326页)
引脚2:命令数据引脚接到FSMC的地址引脚10,片选4的映射地址HDDR[27:0]为0x6C000000~0x6FFFFFFF,它与地址FSMCA[25:0]有区别,当数据宽度为8或16位的时候,内部地址线连接不一样,具体可看(参考手册327页)。假如数据宽度为8位,要使FSMCA10为0,加1为1,要使FSMC的地址应该为0x3FF,加1就是0x400,可以控制引脚为命令或数据,但是这里的数据宽度为16,HADDR[25:1]与FSMCA[24;0]相连,HADDR[0]未接,所以映射地址要左移一位,为0x7FE。因为结构体变量的地址是连续的,所以把LCD这个指针指向LCD_REG时,LCD_REG这个变量的地址就为0x6C0007FE,下一个变量LCD_RAM的地址要加2,因为上一个变量是16位,所以是加2而非加1。这部分比较复杂,可以自己参考手册和程序多加理解,我水平有限,讲的可能不是很清楚。
引脚3:写使能信号,低有效,接FSMC_NWE;
引脚4:读使能信号,低有效,接FSMC_NOE;
引脚5:复位信号,低有效,与系统的复位引脚相连;
引脚6-21:16位双向数据线,与FSMC_D[15:0]相连;
引脚23:背光控制引脚,接普通IO口,高电平点亮,低电平关闭;
除电源与GND外其余引脚为触摸屏控制引脚,本次暂未使用。
NT35510自带LCD GRAM(480*864*3字节),并且最高支持24位颜色深度(1600万色),不过,一般使用16位颜色深度(65k色),RGB565模式,这样,在16位模式下,可以达到最快的速度。在16位模式下,NT35510的数据总线低16位,与MCU的16位数据线,以及24位的LCD GRAM的对应关系如下,
可以看出,是将R、G、B高位的数据搬到空白区进行填充,组成24位数据。高位R代表红色,中间G代表绿色,低位B代表蓝色,且数值越大,颜色越深。
注意:NT35510的指令是16宽,数据除了GRAM的读写是16位宽,其他都是8位宽。
1、读取ID指令:0xDA00、0xDB00、0xDC00;返回值0x8000;
根据读取的ID执行不同的初始化代码,该初始化代码厂家提供,不必深究。
2、存储访问控制指令:0x3600;
该指令可以控制连续GRAM时,指针的增长方向,由参数MY、MX、MV控制;
3、设置横坐标指令:0x2A00~0x2A03;
该指令用于设置起始横坐标SC与结束横坐标EC,若果EC没有变化,只需设置一次即可,在初始化时设置;之后如果只是在设置一个坐标时,只需设置SC,即发送0x2A00、0x2A01和参数;
4、设置纵坐标指令:0x2B00~0x2B03;
该指令用于设置起始纵坐标SP与结束纵坐标EP,若果EP没有变化,只需设置一次即可,在初始化时设置;之后如果只是在设置一个坐标时,只需设置SP,即发送0x2B00、0x2B01和参数;
5、写GRAM指令:0x2C00;
在收到指令后,数据宽度变为16位,我们可以往LCD GRAM里面连续写颜色数据了,而GRAM的地址将根据指令0x3600设置的扫描方向来进行自增。例如:设置的是从左到右,从上到下,设置好起始与结束坐标,每写入一个颜色值,SC++,直到EC,再回到SC;然后SP++,直到结束坐标,其间无需再设置坐标,从而大大提高写入速度。
6、读GRAM指令:0x2E00;
该指令用于NT35510显存的读取,该指令在NT35510数据手册上面的描述是有误的,它真实的输出情况如下表,第一次读到的是无效的数据,第二次读到的是R1与G1,第二次读到B1与R2,每次读两个,接着以RGB的顺序循环读下去。如果只读一个点的颜色,则只要读到参数3即可。
画点的流程:设置坐标——>写GRAM指令——>写入颜色数据;
读点的流程:设置坐标——>读GRAM指令——>读取颜色数据;
基于画点的流程,就可以写字符或数字了,因为他们都是由点构成的。
三、程序编写
1、设置STM32与TFTLCD模块相连的IO口;
除了背光引脚模式设置为推挽输出,其余FSMC的引脚设置为复用推挽;
初始化FSMC;
2、初始化LCD
首先要读取LCD的ID,并把它打印到串口,可以从串口调试助手判断ID是否正确。之后根据不同的ID执行不同的初始化代码。
LCD_Display_Dir(0);该程序主要是设置扫描模式,以及设置起始坐标(0,0)到终点坐标(width-1,height-1);
然后点亮背光,清屏;
3、通过函数将字符和数字显示到TFTLCD上;
画点程序就是设坐标,写GRAM指令,然后填充颜色数据,POINT_COLOR是默认颜色;
快速画点就是加了个颜色的参数,可以更改画点的颜色;
而字符与数字是有点构成的,根据字符的字模不断地调用画点,就可以显示;
字体大小12是指12*12,这是汉子的大小,数字与字符是12*06,12是高,06是宽,所以它占用的字节数为6*2=12字节,
阴码+逐列式+顺向+C51格式,可以在字模软件上模拟下,看它的画点方向是如何的;
这里是从上往下,一列点画完后,纵坐标回到第一行,横坐标+1;继续画第二列的点,直到一个字符的所有字节画完。
数字也是一样的原理,而字符串就是重复调用画字符程序。
横屏显示
竖屏显示