通过看LCD1602A中文手册,其实也是一知半解的。
有关于自定义显示字符的想法,来源于用51、PIC测温度的时候,想显示°C发现并没有对应ASCII码,那么对于LCD1602A自然是显示不了的。但是通过看手册,我了解到‘a'-~'Z','0'~'9'等字符之所以可以这么方便被LCD显示,是因为内部有字符发生器ROM,只读存储寄存器,存储了必要的字符码。
看自定义产生字符的CGRAM (Character Generate )的相关内容,又看的似懂非懂,好在有热心老哥的一篇博客,让我茅塞顿开。链接如下:https://blog.csdn.net/ppptalk/article/details/79190426
遗憾的是没有相关的代码,故在他的基础上我实现了相应的代码。
这里他的一句话很重要,引用下:
先解释下8、,也就是通常用到的指令为
LCD1602cmd(0x80)显示在2*16的第一行最左边,
LCD1602cmd(0xC0)显示在2*16的第二行最左边。
那么关于LCD1602的自定义字符其实只有八个,7、里的000-111选择八个空间里某一个进行填充自定义字符码位置。而则对应于要显示的字符0-7行号。比如第一行,那么就要送一个字节(8位)过去,第二行也送一个字节,直至第七行就可以形成自定义的字符。
DB5-DB0即以下表格CG RAM中的b5-b0。
字符字模数据0-4位有用,那么b7-b5赋0,对应的取模软件新建的图像 因为宽必须是8的倍数,高可以任意,所以不能生成5*7直接对应于LCD的,因为一个字节8位,所以取模就按上面博客链接里的8*8图像大小。取模图如下:
可以看出我的取模是靠右上的,这样程序编写出来显示才正常。
直接上代码:
来个最终效果图:
以上是关于自定义生成字符部分。
/***************************************/
有关移位指令,手册里有两种方法,
第一种,一定要写入要显示的数据,然后整体才移位。
写一个才移一位,要想整体左移或右移两位的话又不要写入其他不想关的字符数据,就写入’ ‘空格,反正也看不出来。
实现起来大概也就是这样子,先设置移位的模式下,至于AC光标移动来移动去,具体再考究。
第二种方法:
只需要 LCD1602Cmd(0x1c);即可。
顺便凑凑字数,加入LCD具体初始化,写数据,写命令,以及自定义显示字符串和自定义显示数字的函数吧。
//定义个全局数组,用以自定义显示数字用。
有关后续的从LCD1602比如读取我写入的字符数据或者ROM里的数据
然后通过串口发送给电脑。
更新:
发现刚开始自己想当然了,首先字符发生器里的ROM看手册是读不出里面的数据的,这样其实这些函数没什么必要应用,感觉用途并不大。毕竟只是对程序里写的数据重新读出来。
另外EN使能信号的上升沿可以读取或者写入数据进DDRAM或者CGRAM ,给下实现的代码:
1.
之前对DDRAM不太理解,
现在的理解大概是显示数据缓存寄存器,直观上来说相当于一个容器,容量为80个字节.写数据LCD1602Data();的时候ROM里面的各种字形码不知道什么原理可以显示到LCD屏上.....有点难以组织,还是不太明白里面的讲究,存疑,可能看看自定义的CGRAM会理解。
记录下我对RAM的抽象理解:
RAM相当于一幢大厦,里面住着不同的用户,那么为了管理利用大厦的空间,每个用户被分配到相应的楼层,房间,房间门牌号即为RAM的地址。
那么之前的CG RAM地址里的b5 - b3代表某一字形码,b2-b0代表这一字形码的行号,所以地址的里的这些位有复用的感觉,而不只是地址,能解读出东西的。类似于2105门牌号,意味着21楼层第五个住户。
楼层代表要显示出什么字符,比如’a',第几个住户代表这个字符,比如‘a'的第一行。
CGRAM能理解,那关于DDRAM与ROM里的关联,还是存疑。
2.同时读取数据的时候,数据端口DATAPORT 还得赋予0XFF,有点不理解,百度上说
“那么问题来了,你P0端如果全是低电平他怎么发送数据,单片机接收的都是全被拉低的数据吧,也就是还是低电平”
为什么P0端全是低电平不能发送数据呢?存疑。
当前的猜测是内部LCDP0端口要想某个位输出1,不能由0变为1,
而是赋值1若想输出1就保持1这个状态,要输出0就拉低这个位。