搜索
bottom↓
回复: 74

CPLD/FPGA TFT 一点经验分享交流

[复制链接]

出0入0汤圆

发表于 2011-1-20 15:35:24 | 显示全部楼层 |阅读模式
搞了一阵子TFT,搞出来点彩条竖条东东,后面也没有搞下去,逼近这个彩条竖条多是定死的东西,看点时序慢慢琢磨,多能理解这个时序。时序就不说了,我搞的彩条竖条是像素点往后移一个点的,也没有去深究了,大家看屏的时序,一般的pdf的时序参数多比较模糊点,放大多还是可以看出来的,我用的是群创的7寸屏,手册上的屏时序是按每秒60帧来刷屏的,其他刷新没有试过,不知道会怎么样。

接下来的是要做单片机和CPLD通信的,说这个之前在说另外一个东西 SRAM ,我一开始理解的是既要读SRAM又要写SRAM这个这么实现,百思不得其解,后来想到了一点,他可能是分时钟周期来实现的,比如第一个始终周期读SRAM,第一个始终周期写SRAM,一个时钟周期就能实现读or写?显然不会的,他可能是:比如

第1个clk 准备读ram的地址 ,第3个clk 读信号,第5个clk 取出ram端口的数据。
第2个clk 准备些ram的地址,第4个clk 写信号,第6个clk 把数据写入ram的端口。

大家看到了吧,奇数和偶数时钟。

以上的情况多是我猜测的。

等等接着写。。。

说完了这些,我得接着猜, CPLD 和 MCU 通信的。
一般的TFT 多有这么几个信号 D0-D7,A0-A2,WR,RD等
D0-D7当然是接单片机的P0.0-P0.7,不错是8位数据,当然我说的是256色TFT的控制器,64K的可能就是D15-D0 了,没有见过这些16位的,可以数据线是16位的也可能是2个8位拼接成16位,当然这也是我的猜想。
A2-A0一般接P2.7-P2.5 ,比如 A2-A0 = 000 表示X方向低8位地址, D0-D7就是低8位地址数据;
                            A2-A0 = 001 表示X方向高8位地址, D0-D7就是高8位地址数据;
                            A2-A0 = 010 表示Y方向低8位地址, ---省略号---
                            A2-A0 = 011 表示Y方向高8位地址, ---省略号---
                            A2-A0 = xxx  就是一些控制状态了,D0-D7 ,D0 表示X地址自动加1,D1表示Y方向自动加1,D2-D3表示背光亮度,D4背景色,D5前景
                                         色,D6-D7 设置写入方式,单点,多点什么的,   还有其他的就是什么读页号,比如这ram能存2屏的数据,一个在2
                                         个页之间切换显示。
这些A2-A0就再不是我的猜测了,卖CPLD TFT 控制器的公司多有这个使用手册 。



接下来是好得说WR这个异步时钟怎么和CPLD的时钟同步,这个WR信号对于CPLD而言就是异步信号了,一般大家书上看到的ASIC/FPGA多是同步设计的例子,异步的基本没有看过, 对于异步设计,本人也找到一点东西,比如跨时钟域请用FIFO等。用570在里面开了一个4b的fifo,好像占用还是可以,不大92LE,看FIFO手册,看的头大。
另外一个就是过2次DFF,用系统时钟抽取WR信号,系统时钟一般比WR频率高很多(比如10倍),我看了at89c51的WR低电平脉冲式400ns ,50M时钟,就是20ns时钟周期。看我下面那张图吧:




(原文件名:WR同步.JPG)


前2个DFF就是把WR同步到本地时钟SYSCLK,我的是54M的话一个周期就是18.5ns  (27M的话就是37ns), 这个请看ASIC中的异步时序设计.pdf,里面有个MTBF
计算,可以降低亚稳态。 后面一个非门,一个与门一个DFF就是所谓的下降沿微分 ,就是当输入一个下降沿在与门的输出端会输出一个正脉冲。
请按图上WR上有0,经过2个SYSCLK后WR的0出现在了第三个DFF的输入端,随后与门的输出端出现一个从0到1的跳变。不算非门,与门延时,(应该是数百ps级吧?)   ,那就是2个SYSCLK后输出一个上升沿,这个上升沿用于触发单片机的D0-D7数据,SYSCLK用54M,那就是37ns,也就是WR出现写信号后延时37ns后读入D0-D7的数据,在ednchina上看到特权的blog 好像有提到说WR后,至少160ns数据才是稳定的,这个要怎么办呢?,160//18.5=8.6 。我要级联9个DFF?
还是用54M二分频后抽取WR进2次DFF,也就是74ns,还有没有其他办法呢?求解


查ATMEL的AT89C51的datasheet
                                                12M Oscillator
                           
名称      参数                                  Min          Max
tWLWH    /WR Pluse Width                       400ns      

tQVWX   Data vaild to /WR Transition           23ns


tQVWX 这个参数不知道是什么意思,难道说WR变低后23ns后D0-D7端口的数据就是稳定的?



点击此处下载 ourdev_612483MMU405.pdf(文件大小:570K) (原文件名:异步FIFO结构.pdf)
点击此处下载 ourdev_612484VPXCKS.doc(文件大小:174K) (原文件名:异步FIFO结构及FPGA设计.doc)
点击此处下载 ourdev_612485SWPQTC.pdf(文件大小:262K) (原文件名:ASIC中的异步时序设计.pdf)


现在领悟到的就是这么多了,或者说多是我猜的。



第二天:
某个控制器的手册
对数据寄存器写入数据操作后一段时间内(比如单点写入是200ns、多点或8点写入是550ns)那就不得对控制板进行任何操作,以便控制板将8个点位颜色值写入SRAM显存,如你的CPU时钟很高,可用插入空指令等的办法实现延时。

比如他用的是54M的晶振,那就是一个周期 18.5ns刷屏的应该是27M DCLK时钟   200/18.5=10.8  550/18.5=29.7
上面的18.5取整数18。,那是不是说写入一个单点数据,也就是说写入8位的显示值整个过程要耗费18个时钟周期?

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2011-1-20 16:24:04 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-20 16:46:34 | 显示全部楼层
坛子里这方面的高手很多。

出0入0汤圆

发表于 2011-1-20 16:46:47 | 显示全部楼层
kankan

出0入0汤圆

 楼主| 发表于 2011-1-20 16:52:51 | 显示全部楼层
回复【2楼】eworker  
坛子里这方面的高手很多。
-----------------------------------------------------------------------
那些代码看不懂,很乱,整不出头绪,再说发上来共享的虽然也实现了一些东西,总是还有不烧瑕疵。

出0入0汤圆

发表于 2011-1-20 18:00:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-20 19:49:30 | 显示全部楼层
脚印!

出0入0汤圆

发表于 2011-1-20 21:02:26 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-20 21:10:43 | 显示全部楼层
脚印

出0入0汤圆

发表于 2011-1-20 21:46:22 | 显示全部楼层
打个指模

出0入0汤圆

发表于 2011-1-20 22:56:19 | 显示全部楼层
回复【9楼】kenson  
-----------------------------------------------------------------------

第1个clk 准备读ram的地址 ,第3个clk 读信号,第5个clk 取出ram端口的数据。
第2个clk 准备些ram的地址,第4个clk 写信号,第6个clk 把数据写入ram的端口。

这一点明显有问题嘛。。。

1T准备了读地址,2T准备写地址, 3T读? 读哪一个地址? 这时读到的是2T准备的地址。。。

读/写是要连续的, 读完才可以写,如读:要依次完成 送地址->读有效->取走数据,写也一样。

其实读写RAM时序很简单。 只控制WR和A(地址)信号就可以。 RD,CS信号直接接低电平就可以了!

出0入0汤圆

发表于 2011-1-20 23:56:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-21 08:08:05 | 显示全部楼层
不错,顶,我未来一两个月也要对付这个东西。
不过我用的是FPGA,FIFO/SRAM控制都是有IP可以用的。感觉也可以用SDRAM,用片上RAM BLOCK生成写入缓冲和读出行缓冲的话,SDRAM的首次读写延迟就可以得到缓解。

出0入0汤圆

 楼主| 发表于 2011-1-21 08:14:58 | 显示全部楼层
回复【10楼】cicnx  
回复【9楼】kenson  
-----------------------------------------------------------------------
第1个clk 准备读ram的地址 ,第3个clk 读信号,第5个clk 取出ram端口的数据。
第2个clk 准备些ram的地址,第4个clk 写信号,第6个clk 把数据写入ram的端口。
这一点明显有问题嘛。。。
1t准备了读地址,2t准备写地址, 3t读? 读哪一个地址? 这时读到的是2t准备的地址。。。
读/写是要连续的, 读完才可以写,如读:要依次完成 送地址->读有效->取走数据,写也一样。
其实读写ram时序很简单。 只控制wr和a(地址)信号就可以。 rd,cs信号直接接低电平就可以了!


-----------------------------------------------------------------------
用的是ISSI 的 5128  SRAM 控制信号仅有WE OE CE,CE我们一般多接地了.就剩下了WE,OE了
那些多是我的一些猜想,也就是我蒙的

出0入0汤圆

发表于 2011-1-21 09:02:15 | 显示全部楼层
回复【13楼】zgq800712  SEED
回复【10楼】cicnx  
回复【9楼】kenson  
-----------------------------------------------------------------------
第1个clk 准备读ram的地址 ,第3个clk 读信号,第5个clk 取出ram端口的数据。
第2个clk 准备些ram的地址,第4个clk 写信号,第6个clk 把数据写入ram的端口。
这一点明显有问题嘛。。。
1t准备了读地址,2t准备写地址, 3t读? 读哪一个地址? 这时读到的是2t准备的地址。。。
读/写是要连续的, 读完才可以写,如读:要依次完成 送地址->读有效->取走数据,写也一样。
其实读写ram时序很简单。 只控制wr和a(地址)信号就可以。 rd,cs信号直接接低电平就可以了!
-----------------------------------......
-----------------------------------------------------------------------
CE,OE都接地吧! 控制会简单点。

出0入0汤圆

 楼主| 发表于 2011-1-21 15:18:07 | 显示全部楼层
回复【15楼】cicnx  
回复【13楼】zgq800712  seed
回复【10楼】cicnx  
回复【9楼】kenson  
-----------------------------------------------------------------------
第1个clk 准备读ram的地址 ,第3个clk 读信号,第5个clk 取出ram端口的数据。
第2个clk 准备些ram的地址,第4个clk 写信号,第6个clk 把数据写入ram的端口。
这一点明显有问题嘛。。。
1t准备了读地址,2t准备写地址, 3t读? 读哪一个地址? 这时读到的是2t准备的地址。。。
读/写是要连续的, 读完才可以写,如读:要依次完成 送地址->读有效->取走数据,写也一样。
其实读写ram时序很简单。 只控制wr和a(地址)信号就可以。 rd,cs信号直接接低电平就可以了!
------------......
-----------------------------------------------------------------------


再看SRAM的时序,看的头晕头痛,电脑职业病

把CE,OE多接地。
看来看去这个SRAM的时序,真的看得要吐的感觉。




读要3个时钟周期   第一个时钟周期WE=1  ; 第二个时钟周期 给出 address(19根地址信号); 第三个时钟周期就可以读出IO口上的数据了。
                  还要接着读就重复 第二个和第三个时钟周期干的事情;  

上面的假设对不对?


      -------------------------------------------------------------
                           WE=1
      -----------------------------------------------------------

                      _________________  _____________
                     /   address       \/              
                     \_________________/\_____________
                          

           _____________  _______  _____________  ____________
          /    PREVIOUS \/       \/   data      \/                 
          \___ data ____/\_______/\___VALID_____/\____________


             -----        -----         -----
            |     |      |     |       |
            |     |      |     |       |
     -------       ------       -------      


写要3个时钟周期   第一个时钟周期 给出 adderss(19根地址信号);  第2个时钟周期  WE=0 ;  第三个时钟周期送要写的数据到IO口上。
                   还要接着写的话是不是 还要 重复 写的3个时钟周期?还是WE=0了,接着就是重复 写SRAM 第一个时钟周期,第3个时钟周期?

不知道上面这些对不对?

出0入0汤圆

发表于 2011-1-21 16:50:34 | 显示全部楼层
那么复杂干嘛?

T1,T3,T5 ....奇数周期用来读出数据。 T2,T4,T6 ...偶数周期写入数据就可以了

54MHZ的时钟可以达到 27M读 27M写了。。。

出0入0汤圆

发表于 2011-1-21 21:37:55 | 显示全部楼层
回复【17楼】cicnx
-----------------------------------------------------------------------

不要把问题想的那到简单的!那么要是数据间有延时呢?几个时钟后你就不知道是那里的数据了1

出0入0汤圆

 楼主| 发表于 2011-1-22 08:13:22 | 显示全部楼层
回复【17楼】cicnx
那么复杂干嘛?  
t1,t3,t5 ....奇数周期用戳鍪?t2,t4,t6 ...偶数周期写入数据就可以了
54mhz的时钟可以达到 27m读 27m写了。。。

-----------------------------------------------------------------------


上面有人说读和写实连续,他是说 T1 T2 T3 用来读 ,T4,T5,T6 用来写 这个意思
我再想想你的意思



回复【18楼】TigerRay
回复【17楼】cicnx  
-----------------------------------------------------------------------
不要把问题想的那到简单的!那么要是数据间有延时呢?几个时钟后你就不知道是那里的数据了1
-----------------------------------------------------------------------

出0入0汤圆

 楼主| 发表于 2011-1-22 11:07:21 | 显示全部楼层
VGA/LCD controller's verilog,VHDL Source code,Testdench
http://asic.co.in/projects/vga_files/vga_lcd.htm


(原文件名:block_diagram.gif)


•CRT and LCD display support

•24bit Standard VGA interface

•Separate VSYNC/HSYNC and combined CSYNC synchronization signals

•Composite BLANK signal

•TripleDisplay support

•12bit Interface

•Compatible with DVI transmitters and 12bit VGA ADCs

•4 different output modes

•Can be used simultaneous with the 24bit interface

•User programmable video resolutions

•User programmable video timing

•User programmable video control signals polarization levels

•32bpp, 24bpp and 16bpp color modes

•8bit gray-scale and 8bit pseudo-color modes

•Supports video- and/or color-lookup-table bankswitching during vertical retrace

•32bit WISHBONE revB.3 compliant slave and master interfaces

•Operates from a wide range of input clock frequencies

•Static synchronous design

•Fully synthesizeable
  





点击此处下载 ourdev_612792IQLKJG.rar(文件大小:590K) (原文件名:vga_lcd.rar)




这个是quartus 报告:

Total combinational functions        1,262 / 33,216 ( 4 % )
Dedicated logic registers        814 / 33,216 ( 2 % )
Revision Name        vga_lcd
Top-level Entity Name        vga_lcd
Family        Cyclone II
Device        EP2C35F672C8
Timing Models        Final
Total logic elements        1,385 / 33,216 ( 4 % )
Total registers        814
Total pins        198 / 475 ( 42 % )
Total virtual pins        0
Total memory bits        16,256 / 483,840 ( 3 % )
Embedded Multiplier 9-bit elements        0 / 70 ( 0 % )
Total PLLs        0 / 4 ( 0 % )

出0入0汤圆

发表于 2011-1-22 12:21:03 | 显示全部楼层
回复【18楼】TigerRay  
回复【17楼】cicnx
-----------------------------------------------------------------------
不要把问题想的那到简单的!那么要是数据间有延时呢?几个时钟后你就不知道是那里的数据了1
-----------------------------------------------------------------------

不明白你所说的数据间延时指的是什么?

我说的在奇数周期读数据,偶数周期写入。 那是考虑到刷屏是一个固定的速率,所以这样分配处理起来相对简单一些。

出0入0汤圆

 楼主| 发表于 2011-1-22 13:01:53 | 显示全部楼层
回复【21楼】cicnx  
回复【18楼】tigerray  
回复【17楼】cicnx
-----------------------------------------------------------------------
不要把问题想的那到简单的!那么要是数据间有延时呢?几个时钟后你就不知道是那里的数据了1
-----------------------------------------------------------------------
不明白你所说的数据间延时指的是什么?
我说的在奇数周期读数据,偶数周期写入。 那是考虑到刷屏是一个固定的速率,所以这样分配处理起来相对简单一些。
-----------------------------------------------------------------------
cicnx 是。。。。? 难道是做这个的?

用可能用54M的晶振,65.536M的。
这个CPLD TFT的方案看到有5家在做,

广东韦泰科技
安徽世龙
武汉中显
上海众贤
还有一家上海的,不知道叫什么


其他的应该还有很多, 这些事08年左右毕业的学生搞得?从10年时候才知道有这个东西

出0入0汤圆

 楼主| 发表于 2011-1-22 14:58:11 | 显示全部楼层
always @(posedge clk or negedge aclr)
          if (~aclr)      rp <= #1 0;
          else if (sclr)  rp <= #1 0;
          else if (frreq) rp <= #1 {rp[aw-1:1], lsb(rp)};



问下大家上面的   #1 0; 上面意思?1和0中间有个空格,是else的情况?

出0入0汤圆

 楼主| 发表于 2011-1-24 09:15:37 | 显示全部楼层
不知道我上面讲的SRAM的时序是不是对的,早上我又看了下IS61WV5128BLL的时序, 地址信号(A0-A18),WE信号(0写,1读),DATA信号(D0-D7);





参数:


(原文件名:IS61WV5128BLL读时序参数.JPG)




时序

(原文件名:IS61WV5128BLL读时序.JPG)

出0入0汤圆

发表于 2011-1-24 12:26:29 | 显示全部楼层
做了记号,方便阅读

出0入0汤圆

发表于 2011-1-24 14:24:13 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2011-1-24 14:32:12 | 显示全部楼层
重大问题:

想问下大家,液晶屏里里面的刷屏时序是按每秒60帧,如果30,40,50可以吗?


这个屏的时序是要HS,VS的,VS就是一帧,HS就是一整行数据,每行可见的显示是800个点/列,
等n个HS后就是刷完一帧/屏的数据了,那个n里面有480个可见行数。

出0入0汤圆

发表于 2011-1-24 17:29:37 | 显示全部楼层
mark!!!

出0入0汤圆

发表于 2011-1-24 23:03:02 | 显示全部楼层
SEED  有什么问题直接问我 真是的
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4437397
这里有我的SRAM VGA 的代码
有问题问我 记住了吗?
I am CrazyBingo

出0入0汤圆

发表于 2011-1-24 23:07:29 | 显示全部楼层

(原文件名:I am CrazyBingo.jpg)


(原文件名:22012011_007.jpg)

出0入0汤圆

发表于 2011-1-24 23:08:22 | 显示全部楼层

(原文件名:22012011_011.jpg)

出0入0汤圆

 楼主| 发表于 2011-1-25 10:00:02 | 显示全部楼层
点击此处下载 ourdev_613252VG5B09.pdf(文件大小:225K) (原文件名:AT080技术手册.pdf)
点击此处下载 ourdev_613253T2AL67.pdf(文件大小:1.05M) (原文件名:ds_TFT_UserManual.pdf)
点击此处下载 ourdev_613254X7KORN.pdf(文件大小:268K) (原文件名:TI07DH使用手册.pdf)
点击此处下载 ourdev_613255U3ANSH.pdf(文件大小:113K) (原文件名:TI07V技术手册.pdf)
点击此处下载 ourdev_613256IPZJ80.pdf(文件大小:640K) (原文件名:ZX-TY070I84B-0808使用说明书V15.pdf)
点击此处下载 ourdev_613257MFGYP6.pdf(文件大小:593K) (原文件名:ZX-TY070I84B-1616使用说明书V15.pdf)
点击此处下载 ourdev_613258XKWE3E.pdf(文件大小:640K) (原文件名:ZX-TY070I84S-0808使用说明书V15.pdf)
点击此处下载 ourdev_613259NZ55HJ.pdf(文件大小:593K) (原文件名:ZX-TY070I84S-1616使用说明书V15.pdf)




这些控制器读写周期,世龙20ns,众贤40ns,中显45ns 真的那么快?
20ns就是50M了,晶振用的应该也是54M,加了什么结构呢?
40ns就是25M了,晶振也应该是54M,50M之类的,
这些东西为什么能有这么高的写入速度,是怎么回事呢?

出0入0汤圆

发表于 2011-1-25 12:00:55 | 显示全部楼层
呵呵,你要看他的周期速度,很多公司连续速度只有两三MHZ就顶不住了.

单次**ns有什么用

出0入0汤圆

发表于 2011-1-25 13:38:23 | 显示全部楼层
mark 跟着学习~

出0入0汤圆

发表于 2011-1-25 14:28:48 | 显示全部楼层
MARK,TFT

出0入0汤圆

 楼主| 发表于 2011-1-26 08:15:09 | 显示全部楼层
在 Crazy Bingo 的VGA美女里面学到了一点东西,总结下大家参考

一些基础的知识和术语,建立保持时间,优化时钟,相关逻辑靠近布局布线可减少延时,时序约束。
门控时钟 一般用于组合逻辑,与门/或门驱动DFF的CLK,如果有其他附件逻辑在与门/或门里,容易因竞争产生不希望的毛刺---特权博客
使能时钟 使能时钟这要是用于时序逻辑中,比门控时钟要来的稳定,而使能时钟有效期间的每个时钟周期都会锁存输入数据,最后写入结束后锁存寄存器里的数据是上升前的0-T(T=1/clk)时间内锁存的数据  ---特权博客
时序逻辑超前滞后,实际上你在时序逻辑判断时钟给一个信号赋值,但经过建立时间,组合延时,保持时间之后,已经是下一个clk了,数据的出现实际滞后了一个clk,所以要保证时序的绝对准确,要把条件减小1,这样因为超前+滞后 刚刚满足了时序

出0入0汤圆

发表于 2011-1-26 13:52:45 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2011-1-26 23:15:24 | 显示全部楼层
又是关于读写SRMA的时序的,看手册迷糊了。
读sram  是  
1T.给出address地址到sram的地址端口上
2T.WE=1 (WE=1是读控制)
3T.sram数据口的数据就是第1步地址所对应的data,可以去走了 ?






写sram  是  
1T.给出address地址到sram的地址端口上
2T.WE=0 (WE=0是写控制)
3T.然后就是给出要写的数据到sram口的data口上?

是2和3对调,好像又不是,杯具,。想不出来了。

用的是 IS61WV5128BLL
http://www.issi.com/pdf/61-64WV5128Axx-Bxx.pdf


Mode     WE  CE  OE  I/O Operation   Vdd Current
Read     H   L   L      Dout            Icc
Write    L   L   X      Din             Icc

出0入0汤圆

发表于 2011-1-27 08:41:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-27 15:39:36 | 显示全部楼层
mark TFT

出0入0汤圆

发表于 2011-1-27 16:02:37 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2011-1-27 19:45:17 | 显示全部楼层
补充一个微分电路,在书上找到了。
书名是 VHDL与数字电路设计,书嘛,是以前学校复印的,当教材用的。 作者:卢毅 赖杰,科学出版社,


(原文件名:微分电路.JPG)




(原文件名:微分电路2.JPG)

出0入0汤圆

 楼主| 发表于 2011-1-30 21:24:01 | 显示全部楼层
事到如今搞不知道sram既要写入数据,又要读出数据到屏上连续显示。
论坛上发的其他的TFT的控制器的代码无从下手看起。看了几个,看不懂。




T6963C控制器图形液晶模块VHDL控制代码-T6963C Graphic LCD module controller VHDL control code

----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity LCD is
        generic(divide_to_100k:integer:=500);
       
    Port ( clk,rst : in  STD_LOGIC;
                          s0_a,s1_a,s2_a,s3_a,s4_a,s5_a,s6_a: out std_logic;
                                c1,c2: out  STD_LOGIC;
           wr : out  STD_LOGIC;
           rd : out  STD_LOGIC;
           cd : out  STD_LOGIC;
           lcd_rst : out  STD_LOGIC;
           lcd_data : out  STD_LOGIC_VECTOR (7 downto 0));
end LCD;

architecture Behavioral of LCD is

signal clk_100k:std_logic;
type state is (s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15);
signal current_s:state;
--type state_s is (s0_0,s1_1,s2_2);
--signal current_s_s:state_s;

type instruction_code is array(0 to 12)of std_logic_vector(7 downto 0);
constant c_code:instruction_code:=(x"00",x"00",x"40",x"1e",x"00",x"41",x"80",x"94",x"07",x"00",x"24",x"b0",x"b2");
                                                                                        --c_t_starting_add                 --c_t_width          --c_t_on                   --c_add_p c_auto_w_off
                                                                                                                                                                          --c_or_mode                                                          c_auto_w_on
type data_buffer is array(0 to 14)of std_logic_vector(7 downto 0);
constant data_buf:data_buffer:=(x"57",x"57",x"57",x"0E", x"13",x"11",x"15",x"59",
                                                                                  x"44",x"44",x"5A",x"0E", x"43",x"4F",x"4D");
                                                                                                       
begin

c1<='1';
c2<='1';

process(clk)
variable cnt:integer range 0 to divide_to_100k;
        begin
        if rising_edge(clk) then
                cnt:=cnt+1;
                if cnt=divide_to_100k then
                        cnt:=0;
                end if;
                if cnt<divide_to_100k/2 then
                        clk_100k<='0';
                else
                        clk_100k<='1';
                end if;
        end if;
end process;


process(clk_100k)-------------clk_100k
variable cnt1:integer range 0 to 500000;                --cnt1 for loop
variable cnt1_1:integer range 0 to 1000;         --cnt1_1 for writing operation
variable code_cnt:integer range 0 to 13;                --cnt1_2 array of code
variable data_cnt:integer range 0 to 480;

        begin
        if rising_edge(clk_100k) then
                if rst='1' then
                        current_s<=s0;
                        cnt1:=0;
                        cnt1_1:=0;
                        code_cnt:=0;
                        data_cnt:=0;
                        lcd_rst<='0';
                                s0_a<='0';
                                s1_a<='0';
                                s2_a<='0';
                                s3_a<='0';
                                s4_a<='0';
                                s5_a<='0';
                                s6_a<='0';

                else               
                        case current_s is
                        when s0=>
                                wr<='1';
                                rd<='1';
                               
                                cnt1:=cnt1+1;
                                if cnt1<250000 then
                                        lcd_rst<='0';
                                elsif cnt1<500000 then--500
                                        lcd_rst<='1';
                                elsif cnt1=500000 then--500                        --delay for lcd_initial
                                        lcd_rst<='1';
                                        cnt1:=0;
                                        current_s<=s1;
                                end if;       
                                s0_a<='0';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='1';
                                s4_a<='1';
                                s5_a<='1';
                                s6_a<='1';
                               
                        when s1=>
                                if cnt1<2 then                                --control amount of c_code
                                        if cnt1_1<1*3 then                                       
                                                cd<='0';
                                        elsif cnt1_1<2*3 then
                                                lcd_data<=c_code(code_cnt);
                                                if cnt1_1=(2*3-1) then
                                                        code_cnt:=code_cnt+1;
                                                end if;
                                        elsif cnt1_1<3*3 then
                                                wr<='0';
                                        elsif cnt1_1<4*3 then
                                                wr<='1';
                                   -----------------------------writing a parameter
                                       
                                        elsif cnt1_1<5*3 then
                                                cd<='0';
                                        elsif cnt1_1<6*3 then
                                                lcd_data<=c_code(code_cnt);
                                                if cnt1_1=6*3-1 then
                                                        code_cnt:=code_cnt+1;
                                                end if;
                                        elsif cnt1_1<7*3 then
                                                wr<='0';
                                        elsif cnt1_1<8*3 then
                                                wr<='1';
                                        -----------------------------writing a parameter       
                                       
                                        elsif cnt1_1<9*3 then
                                                cd<='1';
                                        elsif cnt1_1<10*3 then
                                                lcd_data<=c_code(code_cnt);
                                                if cnt1_1=10*3-1 then
                                                        code_cnt:=code_cnt+1;
                                                end if;
                                        elsif cnt1_1<11*3 then
                                                wr<='0';
                                        elsif cnt1_1<12*3 then
                                                wr<='1';
                                        end if;       
                                end if;                                       
                                        -----------------------------writing a code       
                                       
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;
                                        cnt1:=cnt1+1;
                                        if cnt1=2 then
                                                current_s<=s2;
                                                cnt1:=0;
                                        end if;
                                end if;
                               
                                s0_a<='1';
                                s1_a<='0';
                                s2_a<='1';
                                s3_a<='1';
                                s4_a<='1';
                                s5_a<='1';
                                s6_a<='1';
                               
                        when s2=>
                                if cnt1<2 then                                --control amount of c_code
                                        if cnt1_1<1*3 then
                                                cd<='1';
                                        elsif cnt1_1<2*3 then
                                                lcd_data<=c_code(code_cnt);
                                                if cnt1_1=2*3-1 then
                                                        code_cnt:=code_cnt+1;
                                                end if;
                                        elsif cnt1_1<3*3 then
                                                wr<='0';
                                        elsif cnt1_1<4*3 then
                                                wr<='1';
                                        end if;       
                                end if;                                                               
                                        -----------------------------writing a code               
                                       
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;
                                        cnt1:=cnt1+1;
                                        if cnt1=2 then
                                                current_s<=s3;
                                                cnt1:=0;
                                        end if;
                                end if;
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='0';
                                s3_a<='1';
                                s4_a<='1';
                                s5_a<='1';
                                s6_a<='1';
                               
                        when s3=>-------------------------set add_p and auto_write               
                                if cnt1_1<1*3 then                                       
                                        cd<='0';
                                elsif cnt1_1<2*3 then
                                        lcd_data<=c_code(8);
                                elsif cnt1_1<3*3 then
                                        wr<='0';
                                elsif cnt1_1<4*3 then
                                        wr<='1';
                           -----------------------------writing a parameter
                               
                                elsif cnt1_1<5*3 then
                                        cd<='0';
                                elsif cnt1_1<6*3 then
                                        lcd_data<=c_code(9);
                                elsif cnt1_1<7*3 then
                                        wr<='0';
                                elsif cnt1_1<8*3 then
                                        wr<='1';
                                -----------------------------writing a parameter       
                               
                                elsif cnt1_1<9*3 then
                                        cd<='1';
                                elsif cnt1_1<10*3 then
                                        lcd_data<=c_code(10);
                                elsif cnt1_1<11*3 then
                                        wr<='0';
                                elsif cnt1_1<12*3 then
                                        wr<='1';
                                end if;       
                                -----------------------------writing a code               
                               
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;
                                        current_s<=s4;
                                end if;
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='0';
                                s4_a<='1';
                                s5_a<='1';
                                s6_a<='1';
                               
                        when s4=>
                                if cnt1_1<1*3 then
                                        cd<='1';
                                elsif cnt1_1<2*3 then
                                        lcd_data<=c_code(11);
                                elsif cnt1_1<5*3 then
                                        wr<='0';
                                elsif cnt1_1<6*3 then
                                        wr<='1';
                                end if;       
                                -----------------------------writing a code               
                               
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;
                                        current_s<=s5;
                                        data_cnt:=0;
                                end if;
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='1';
                                s4_a<='0';
                                s5_a<='1';
                                s6_a<='1';
                        when s5=>
                                if cnt1_1<1*3 then                                       
                                        cd<='0';
                                elsif cnt1_1<2*3 then
                                        lcd_data<=x"37";
                                        data_cnt:=data_cnt+1;
                                elsif cnt1_1<3*3 then
                                        wr<='0';
                                elsif cnt1_1<4*3 then
                                        wr<='1';
                                end if;
                           -----------------------------writing a data       
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;
                                        if data_cnt=480 then
                                                current_s<=s6;
                                                data_cnt:=0;
                                        end if;
                                end if;
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='1';
                                s4_a<='1';
                                s5_a<='0';
                                s6_a<='1';       
                        when s6=>
                                if cnt1_1<1*3 then
                                        cd<='1';
                                elsif cnt1_1<2*3 then
                                        lcd_data<=c_code(12);
                                elsif cnt1_1<3*3 then
                                        wr<='0';
                                elsif cnt1_1<4*3 then
                                        wr<='1';
                                end if;       
                                -----------------------------writing a code               
                               
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;----------------------------------------------------------
                                        current_s<=s7;--------------------------------------------------------
                                end if;       
                               
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='1';
                                s4_a<='1';
                                s5_a<='1';
                                s6_a<='0';                               
                        when s7=>-------------------------set add_p and auto_write               
                                if cnt1_1=0 then                                       
                                        cd<='0';
                                elsif cnt1_1=1 then
                                        lcd_data<=x"00";
                                elsif cnt1_1=2 then
                                        wr<='0';
                                elsif cnt1_1=3 then
                                        wr<='1';
                           -----------------------------writing a parameter
                               
                                elsif cnt1_1=4 then
                                        cd<='0';
                                elsif cnt1_1=5 then
                                        lcd_data<=x"00";
                                elsif cnt1_1=6 then
                                        wr<='0';
                                elsif cnt1_1=7 then
                                        wr<='1';
                                -----------------------------writing a parameter       
                               
                                elsif cnt1_1=8 then
                                        cd<='1';
                                elsif cnt1_1=9 then
                                        lcd_data<=c_code(10);
                                elsif cnt1_1=10 then
                                        wr<='0';
                                elsif cnt1_1=11 then
                                        wr<='1';
                                end if;       
                                -----------------------------writing a code               
                               
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;
                                        current_s<=s8;
                                end if;
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='0';
                                s4_a<='1';
                                s5_a<='1';
                                s6_a<='1';
                               
                        when s8=>
                                if cnt1_1=0 then
                                        cd<='1';
                                elsif cnt1_1=1 then
                                        lcd_data<=c_code(11);
                                elsif cnt1_1=2 then
                                        wr<='0';
                                elsif cnt1_1=3 then
                                        wr<='1';
                                end if;       
                                -----------------------------writing a code               
                               
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;
                                        current_s<=s9;
                                        data_cnt:=0;
                                end if;
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='1';
                                s4_a<='0';
                                s5_a<='1';
                                s6_a<='1';                               
                        when s9=>
                                if cnt1_1=0 then                                       
                                        cd<='0';
                                elsif cnt1_1=1 then
                                        lcd_data<=x"00";
                                        data_cnt:=data_cnt+1;
                                elsif cnt1_1=2 then
                                        wr<='0';
                                elsif cnt1_1=3 then
                                        wr<='1';
                                end if;
                           -----------------------------writing a data       
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;
                                        if data_cnt=480 then
                                                current_s<=s10;
                                                data_cnt:=0;
                                        end if;
                                end if;
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='1';
                                s4_a<='1';
                                s5_a<='0';
                                s6_a<='1';
                               
                        when s10=>
                                if cnt1_1=0 then
                                        cd<='1';
                                elsif cnt1_1=1 then
                                        lcd_data<=c_code(12);
                                elsif cnt1_1=2 then
                                        wr<='0';
                                elsif cnt1_1=3 then
                                        wr<='1';
                                end if;       
                                -----------------------------writing a code               
                               
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;----------------------------------------------------------
                                        current_s<=s11;--------------------------------------------------------
                                end if;       
                               
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='1';
                                s4_a<='1';
                                s5_a<='1';
                                s6_a<='0';
                               
                               

                        when s11=>-------------------------set add_p and auto_write               
                                if cnt1_1=0 then                                       
                                        cd<='0';
                                elsif cnt1_1=1 then
                                        lcd_data<=c_code(8);
                                elsif cnt1_1=2 then
                                        wr<='0';
                                elsif cnt1_1=3 then
                                        wr<='1';
                           -----------------------------writing a parameter
                               
                                elsif cnt1_1=4 then
                                        cd<='0';
                                elsif cnt1_1=5 then
                                        lcd_data<=c_code(9);
                                elsif cnt1_1=6 then
                                        wr<='0';
                                elsif cnt1_1=7 then
                                        wr<='1';
                                -----------------------------writing a parameter       
                               
                                elsif cnt1_1=8 then
                                        cd<='1';
                                elsif cnt1_1=9 then
                                        lcd_data<=c_code(10);
                                elsif cnt1_1=10 then
                                        wr<='0';
                                elsif cnt1_1=11 then
                                        wr<='1';
                                end if;       
                                -----------------------------writing a code               
                               
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;
                                        current_s<=s12;
                                end if;
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='0';
                                s4_a<='1';
                                s5_a<='1';
                                s6_a<='1';
                               
                        when s12=>
                                if cnt1_1=0 then
                                        cd<='1';
                                elsif cnt1_1=1 then
                                        lcd_data<=c_code(11);
                                elsif cnt1_1=2 then
                                        wr<='0';
                                elsif cnt1_1=3 then
                                        wr<='1';
                                end if;       
                                -----------------------------writing a code               
                               
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;
                                        current_s<=s13;
                                        data_cnt:=0;
                                end if;
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='1';
                                s4_a<='0';
                                s5_a<='1';
                                s6_a<='1';                               
                        when s13=>
                                if cnt1_1=0 then                                       
                                        cd<='0';
                                elsif cnt1_1=1 then
                                        lcd_data<=data_buf(data_cnt);
                                        data_cnt:=data_cnt+1;
                                elsif cnt1_1=2 then
                                        wr<='0';
                                elsif cnt1_1=3 then
                                        wr<='1';
                                end if;
                           -----------------------------writing a data       
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;
                                        if data_cnt=15 then
                                                current_s<=s14;
                                                data_cnt:=0;
                                        end if;
                                end if;
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='1';
                                s4_a<='1';
                                s5_a<='0';
                                s6_a<='1';
                               
                        when s14=>
                                if cnt1_1=0 then
                                        cd<='1';
                                elsif cnt1_1=1 then
                                        lcd_data<=c_code(12);
                                elsif cnt1_1=2 then
                                        wr<='0';
                                elsif cnt1_1=3 then
                                        wr<='1';
                                end if;       
                                -----------------------------writing a code               
                               
                                cnt1_1:=cnt1_1+1;
                                if cnt1_1=100 then       
                                        cnt1_1:=0;----------------------------------------------------------
                                        current_s<=s15;--------------------------------------------------------
                                end if;       
                               
                                s0_a<='1';
                                s1_a<='1';
                                s2_a<='1';
                                s3_a<='1';
                                s4_a<='1';
                                s5_a<='1';
                                s6_a<='0';

                        when s15=>
                                null;
                        when others=>
                                current_s<=s0;
                        end case;
                end if;
        end if;
end process;
                                       
                               

end Behavioral;

出0入0汤圆

 楼主| 发表于 2011-1-31 13:09:24 | 显示全部楼层
现在有头绪了,奇偶时钟读写,拨开乌云,阳光明媚。

不明白这个sram的写操作,时序读上看的郁闷,不知道哪位大侠知道?解答下?我快成功了。剩下的就是细节了。



sram写时序看不来,我是ce,oe多接地了。
读sram就是 如果we一直是0的画,输出地址 10ns之后就可以读sram数据口上的电压了。
写sram看了,看不明白,希望哪位大侠能 解答下。这一步就海阔天空了。

出0入0汤圆

 楼主| 发表于 2011-2-2 09:50:13 | 显示全部楼层

(原文件名:aaa.JPG)




大家看上面的图,屏时钟是要每个周期多要送数据的。屏手册是说在屏时钟的下降沿读数据。
读/写ram在系统时钟的2个时钟周期里面可以完成,比如读,第一个时钟周期S0(S2)送出WE和地址,第二个时钟周期S1(S3)就是数据了。

但是每个屏时钟时钟周期对视要有数据的,我要在S0-S1写入数据到sram,那这个屏时钟周期的数据不是没有了吗?




难道是这样,下面的图:



(原文件名:aaa.JPG)


S0写sram,S1读sram。
S1读sram是送出WE和地址,过个10ns后就有稳定的数据可用了,让屏时钟的下降沿给采进去了。
S0写sram时序不明白,pdf看了不理解,还郁闷,还望大侠指点。

出0入0汤圆

发表于 2011-2-2 15:29:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-5 02:09:07 | 显示全部楼层
标记

出0入0汤圆

发表于 2011-4-6 10:16:28 | 显示全部楼层
mark~

出0入0汤圆

发表于 2011-4-6 17:04:46 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-6 17:57:30 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-6 19:05:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-6 20:19:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-5 23:42:53 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-8 19:04:39 | 显示全部楼层
现在还不能很好理解。先mark

出0入0汤圆

发表于 2011-6-8 19:23:49 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-9 04:53:13 | 显示全部楼层
mark

出0入10汤圆

发表于 2011-6-9 09:16:49 | 显示全部楼层
这些控制器读写周期,世龙20ns,众贤40ns,中显45ns 真的那么快?
20ns就是50M了,晶振用的应该也是54M,加了什么结构呢?
40ns就是25M了,晶振也应该是54M,50M之类的,
这些东西为什么能有这么高的写入速度,是怎么回事呢?

别的公司的怎么样,我没测过。众贤的这个数据是广告(符合国情),实测能达到13.5M的写入速度。
25M时误码率太高。 我的13.5M与25M指的是连续不间断的WR信号的频率.  对占空比没有严格要求。只要低电平或高电分别达到CPLD的
门槛就行。

出0入0汤圆

发表于 2011-8-24 10:18:54 | 显示全部楼层
收藏一下!

出0入0汤圆

发表于 2011-10-27 21:35:26 | 显示全部楼层
跟个贴,以后好查找!

出0入0汤圆

发表于 2011-10-28 08:48:28 | 显示全部楼层
【58楼】 widesoft2 通关:
您得好好补习一下CPLD异步知识了

出0入0汤圆

发表于 2011-11-17 14:20:50 | 显示全部楼层
控制起来比LCD12864难度大多了,特别用FPGA做比单片机难!

出0入0汤圆

发表于 2011-11-23 10:59:17 | 显示全部楼层
fpc-ftp300d01z-00有40根引线,它们是怎么定义的。
我也想用FPGA来驱动它。希望大家帮帮我。

出0入0汤圆

发表于 2011-12-4 10:16:26 | 显示全部楼层
标记

出5入8汤圆

发表于 2011-12-4 10:25:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-4 16:11:57 | 显示全部楼层
高手挺多啊,顶

出0入0汤圆

发表于 2011-12-4 22:39:25 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-1-1 19:39:46 | 显示全部楼层
回复【21楼】cicnx
-----------------------------------------------------------------------

这个方法很好!

出0入0汤圆

发表于 2013-3-7 16:03:52 | 显示全部楼层
标记一下,这个做8寸以上的屏可以,学习学习。
谢谢!

出0入0汤圆

发表于 2015-12-25 09:34:38 | 显示全部楼层
不错 FPGA TFT
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-3 08:07

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表