其实本人接触FPGA也就1个月时间(板子才买了两星期不到),所以也没有什么高深的见解。所以希望大家能够指出我的错误,让我们一起进步。目前为止这个模块已经达到了预期的目标,想要再深入设计就必须编写软件了,这对于本人来说并不熟悉。所以就不在往后研究而是进一步学习FPGA了,想要继续的可以和我要编写的程序(第一次写不会上传啊,而且.v的文件似乎也不能上传)。我的邮箱是446771976@qq.com。
我建立的模块包含了一下几个文件:
12864.v
ram.v
speed_seclect.v
uart_rx.v
首先的编写的是一个串口模块,特权同学的教程里面也有。我是参考他的时序编写的,而且也遇到了有些人所说的只能发送单个字符的错误,经过分析我才知道是由于时序不匹配导致。测试的串口发送助手发送的是1个起始位,8个数据位和1个停止位的数据,而接收的模块却定义的是多带1个校验位的数据,所以只要删除一个位的检测即可。这个模块的建立在uart_rx.v文件中。
而speed_seclect.v包含的是波特率时钟发生器的设计。这里名字我都和特权同学的一样,本人实在是不会起名字,模块内部的名字确实有写混乱。在写嵌入式的c语言程序的时候本人已能很好的遵循规范来写,再学习一门新语言就有点心急的,所以就有点混乱了。毕竟本人即将面临激烈的就业问题了,不多学一点知识不行呐。在这里我并没有利用串口的发送模块,感觉没啥用。
然后是一个ram模块,这里我用的是altera内部的M4K模块来构建的一个一端可读一端可写的双端ram,大小是1024X8bit。写一个模块的仿真可是费了不少劲。由于本人使用的是modelsim se版,关于altera器件的内核仿真不怎么方便。我找遍了资料,说是什么编译altera的器件库啦,然后再你编的工程中加入这个库。本人头都大了。不过最后本人还是成功的编译好了库,而且也能在quartus中之间调用modelsim se版。但最简单的办法是只要在编译的文件中加入两个文件即可,一个是altera_mf.v,另一个是cycloneii_atoms.v(这个就得看你用的是什么型号的器件了)。然后自己编了个testbench测试了一个,成功!!不知道图片上传成功了木有......
接下来介绍的是12864.v,它就是这个模块的顶层了,而OLED是本人设计的12864显示模块的顶层,我也不知道这样合理不合理。那么设计好的RTL视图就是这样:
OLED.v才是显示的核心,在这里包含有:
bus8080.v
contrl (2).v
draw.v
init.v
keyscan.v
MXU2X1.v
OLED.v
read.v
write.v
bus8080.v是本人构建的8080通信协议,OLED的控制芯片是SSD1306,在它的文档中有各种可以用来驱动OLED的通信协议,有8080,6800和spi。这里我用的8080,毕竟快么。这里和文档中有些出入,我用的FPGA用的是50M的晶振,一个时钟周期也就是20ns,本来我也是在wr拉低的写个周期写入数据的,但发现这时数据会不稳定。于是乎我就在拉低wr的同时输入数据了。时序图和仿真图如下(实际还有很多内部信号位显示):
init.v则是初始化OLED的步骤,它通过控制bus8080.v模块像OLED发送一系列的初始化命令,而draw.v是像OLED发送数据的模块(其中还夹杂着一些命令),它也是通过控制bus8080.v来发送数据的。既然他们都控制bus8080.v,那就会发生冲突。MUX2X1.v则是一个多路选择器,在init.v工作的时候输出它的数据,否则输出draw.v的数据。
有人说一个模块就像一个门,当你进出这扇门的时候一定要打开和关闭。一般打开是不会忘记的,但关闭就常常会被忘记。有时候这回造成混乱,所以请记得关门。在draw.v中有时发送的是数据,有时是命令,如果在打开bus8080.v的时候不关闭,在数据和命令切换的时候就会发生混乱。这也是本人在设计中遇到的问题。所以要养成关门的好习惯,尽管在init.v中并没有关门(它发送的都是命令),不过有好习惯是好的。
本人遇到的另一个问题就是如何让数据准确的读出来,即读数据的时序要和数据输出的数据相匹配。FPGA最大的优势就是并行执行,但我发现很难让读数据的时序和数据输出的时序相匹配,这不仅仅是因为读数据的速度和数据输出速度不一致,而且间隔也可能不一致(draw.v发送的是读的数据和某些命令)。可以确定的是,的确的能另作一个数据输出模块来满足读数据的时序,但这回消耗大量的逻辑资源。在这里本人采用了在读数据之前产生一个控制信号来使数据输出,而控制信号距离数据稳定输出还有一定的时间间隔,所以这里在发送了控制信号后还需要延时几个周期才能读数据。这样逻辑资源的利用减少了,但也没发挥FPGA的优势。
read.v就是把draw.v输出的控制读数据的信号转换成地址的变化,每收到一个数据地址加一,这样就能源源不断的读出正确的数据了。
write.v则是根据ram的写时序把输入的数据写入对应的地址。这里参考altera的器件手册里面双端口ram的读写时序就可以了。
最后的是控制信号,keyscan.v是按键消抖的模块。在这里本人直接利用了做第一个实验时建立的模块,当时3个按键一个控制流水灯循环左移,一个控制循环右移,而最后一个控制左移后再右移的功能。这里只用了一个按键,所以也不更改了。contrl.v则定义了按键的功能。在按下按键后首先执行init.v模块,然后每20ms执行一次draw.v模块,机实现了每秒50次的刷屏。
在设计完成后我明白其实还有很多改进的地方,但由于时间有限也就没在修改了。等我在连好电路准备操作的时候才发现一个严重的问题。我利用取点阵的软件生成的是txt格式的,而它内部信息都是用ASCII码存储的,所以我发送的文件无法显示出想要的结果。本来我想在内部增加一个ASCII转HEX的模块,但两个ASCII码才能生成一个8位数据,这就大大降低了数据传输率。所以利用c编写的软件进行转换最好不过了,但本人对于这方面一知半解,所以我就千辛万苦把生成的txt文件复制粘贴发送进去,结果还不错。下面是效果图
而省劲点我只能发送0103070f1f3f7fffff7f3f1f0f070301这一串数据画一个个三角形了,不过目的总是达到了。
电子匠人 2013-11-4 21:53
电子匠人 2013-11-3 21:27
用户1407078 2013-11-3 19:41
用户377235 2013-11-3 17:47
电子匠人 2013-10-17 18:44
用户403664 2013-10-17 15:32
用户444552 2013-8-30 11:39
谢谢提醒,上传成功,目前我更改了一下功能,实现的是一个动态屏的功能,就像led的广告牌一样,知识目前只能显示字符的动态显示
用户340458 2013-8-29 22:26
用户444552 2013-8-28 09:00
用户377235 2013-8-26 20:52