我们开发板上所使用的液晶为晶联讯生产的JLX12864G-13903型液晶显示器,可以显示128列*64行点阵单色图片,或显示8个/行*4行16*16点阵的汉字,或显示16个/行*8行8*8点阵的英文、数字、符号。 该液晶的通信方式可以通过不同的硬件设置,配置成串行和并行两种不同的通信方式。在这里,为了节约IO资源,我们将其配置成串行通信方式,具体电路如下: 由电路图可以看出,我们需要关心的其实也就只有五条线,那么接下来就让我们梳理一下这几条信号线的具体意义。 1.12864_cs:片选信号,低电平有效 2.12864_res:低电平复位信号,复位完成后,回到高电平,液晶开始工作 3.12864_rs:寄存器选择信号,H:数据寄存器L:指令寄存器 4.12864_sck:串行时钟 5.12864_sda:串行数据
信号定义明白了,可是时序呢?它又是咋样的呢?让我们一睹官方资料的时序图如下: 注:此处的A0即为我们的12864_rs信号,只是表示方式不同而已。 由时序图可以得出,只要我们的代码逻辑能符合上述时序要求,就可以顺利地发送数据,可是点亮这个屏,需要哪些步骤呢?官方的资料提供了一些例程,可惜这些例程都是C语言版本的,接下来,就让我们这些“门外汉”慢慢品读吧。
C程序如下:
对于我们学硬件的人来说,这样的C代码或许有些许挑战,但是不要紧,接下来就让我们细细分析它的main函数,定能找到关键线索。Main函数如下: 由此可以看出,main函数开始执行的时候,首先要经过一个叫做initial_lcd的函数,然后进入循环主体,每隔一段时间打印一幅图像。那么接下来,就让我们细细品读这个initial_lcd函数的构成。代码如下: 此可以看出,所谓LCD初始化就是首先拉低硬件复位信号12864_res一段时间再放开,等待复位结束以后,开始执行一条条指令: 1. 软件复位 2. 升压步骤一 3. 升压步骤二 4. 升压步骤三 5. 粗调对比度,可设置范围0x20~0x27 6. 微调对比度 7. 微调对比度的值,可设置范围0x00~0x3f 8. 1/9偏压比(bias) 9. 行扫描顺序:从上到下 10.列扫描顺序:从左到右 11.起始行位置:从第一行开始 12.开显示 现在的问题就成了指令是如何被执行的呢?接下来再让我们解析transfer_command这个函数。代码如下:
仔细分析代码,不难发现这个函数的作用就是拉低片选信号,并拉低12864_rs信号(选择指令寄存器),然后通过移位操作,将参数data1发送到12864_sda串行数据总线。 总结:分析上文可知,我们如果要用FPGA实现对12864的控制,首先需要做的就是先硬件复位12864一段时间,然后按照C例程的顺序,发送上述指令集,等12864初始化完毕就可以开始发送图像数据。
接下来,我们开始分析如何发送有效数据,例程代码如下: 这里面涉及到了另外一个函数—transfer_data,那么就让我们继续一探究竟,其代码如下: 可以看出,函数transfer_data也只是通过并串转换将数据发送到串行数据总线,在发送数据的过程中必须将12864_rs置位高电平(选择数据寄存器),返回到前一级函数disp_grap,可以看出在发送数据之前,还必须首先发送三组指令: transfer_command(0xb0+i); //set page address, transfer_command(0x10); transfer_command(0x00); 梳理上文提到的脉络,可以总结如下: 如果想要点亮液晶,必须先发送一系列的指令集,对LCD进行初始化。初始化完毕以后,可以开始发送数据,但每发一组数据一前还必须先发送三组指令,设置页面显示地址。 现在,我们设计FPGA模块如下:
1.时钟分频模块 我们发送数据的时序要求需要满足一些特定的参数,将频率降低到一定值,就可以满足这些时序参数。具体参数值请查阅官方手册。
2.指令控制模块 如前文所述,想要点亮LCD,首先需要进行LCD初始化,发送特定的指令集,等初始化结束以后,再开始发送具体的显示数据,这些过程都需要紧密配合,所以我们把这部分的控制作为一个单独的模块来实现。 端口说明: (1).cnt_shift:数据发送模块的移位计数器,用来控制LCD_control模块的状态跳转 (2).shift_en:控制数据发送模块开始进行并串转换,将数据发出 (3).data[7:0]:待发送的指令或数据
3.数据发送模块 端口在上面已经介绍过,在这里就不多做介绍了,让我们直奔主题,代码献上。
LCD_control模块代码如下:
Send_data模块代码如下:
顶层模块代码如下:
至此,我们的系统搭建完成,进行全编译,查看RTL视图如下: 现编写测试代码如下: 查看仿真波形: 查看上述仿真波形可知,各条指令按照顺序通过send_data模块被有序输出。
开发板显示效果如下:
|