whwlxl 发表于 2010-8-3 18:44:49

50M晶振 EPM240 + 512KSRAM 做 800*600 TFT LCD 控制器

才接触Verilog,找了块人家的液晶转接板自己学习学习,也没钱打板子。

转接板上:

2跟地址线,8根数据线,CS,RD,WE信号与外部接口

LCDClk, Hsync Vsync, DE, R0,R1,R2, G0,G1,G2, B0,B1,驱动液晶,目前发现有问题在研究中……
希望有经验的大侠也一起帮忙指导。

主要是以前软件出身,难以一下转化到硬件语言的设计上来,纯技术交流!


把代码贴出来,一起调试:
module TFTDRV(
        inputGCLK,
        output TFT_CLK,
        output TFT_Hsync,
        output TFT_Vsync,
        output TFT_DE,
        output TFT_R0_3,
        output TFT_R1_4,
        output TFT_R2_5,
        output TFT_G0_3,
        output TFT_G1_4,
        output TFT_G2_5,
        output TFT_B0_2_4,
        output TFT_B1_3_5,
       
        output RAM_A,
        inoutRAM_D1,
        inoutRAM_D2,
        output RAM_WE1,
        output RAM_WE2,

        inoutEB_D,
        inputEB_A,
        inputEB_CS,
        inputEB_WR,
        inputEB_RD,
        output EB_BUSY
);



reg        reg_tft_rgb = 8'b00000000;
regreg_scan_addr = 20'd0;        //TFT LCD Scan Data Address

TFT_CTRL        U1(
.INCLK(GCLK),
.LCDCLK(TFT_CLK),
.RGB(reg_tft_rgb),
.Hsync(TFT_Hsync),
.Vsync(TFT_Vsync),
.DE(TFT_DE),
.R0_3(TFT_R0_3),
.R1_4(TFT_R1_4),
.R2_5(TFT_R2_5),
.G0_3(TFT_G0_3),
.G1_4(TFT_G1_4),
.G2_5(TFT_G2_5),
.B0_2_4(TFT_B0_2_4),
.B1_3_5(TFT_B1_3_5)
);


//RAM data inout port control
reg reg_ram_we1 = 1'b1;        //RAM Read=1/Write=0 Control Signal
reg reg_ram_wdr1 = 8'b00000000;        //RAM Write Data Reg

assign RAM_D1 = (reg_ram_we1)?8'bzzzz_zzzz:reg_ram_wdr1;
assign RAM_WE1 = reg_ram_we1;


reg reg_ram_we2 = 1'b1;        //RAM Read=1/Write=0 Control Signal
reg reg_ram_wdr2 = 8'b00000000;        //RAM Write Data Reg

assign RAM_D2 = (reg_ram_we2)?8'bzzzz_zzzz:reg_ram_wdr2;
assign RAM_WE2 = reg_ram_we2;

//regreg_ram_addr = 20'h00000;        //RAM Address Line
//assign RAM_A = reg_ram_addr;
reg reg_ram_idx = 1;
assign RAM_A = (reg_ram_idx)?reg_scan_addr:reg_cmd_addr;


//Extern Bus Command addres
regreg_cmd_addr = 20'd0;
reg reg_cmd_x = 10'd0;
reg reg_cmd_y = 10'd0;

parameter   XYHL_STA= 1'b0;
parameter        XYHL_END = 1'b1;
reg reg_cmd_xyhl = XYHL_STA;        //Extern Bus Write X or Y High Or Low Byte


reg reg_rw_ram_flg = 1'b1;        //Read = 1; Write = 0;

reg reg_eb_wr_q1 = 1'b1;
reg reg_eb_wr_q2 = 1'b1;

reg reg_eb_rd_q2 = 1'b1;
reg reg_eb_rd_q1 = 1'b1;        //Extern Bus Read Signal
reg reg_eb_dat =8'd0;
reg reg_eb_busy = 1'b1;        //Extern Bus Command Status

assign EB_D = reg_eb_rd_q2?8'bzzzz_zzzz:reg_eb_dat;
assign EB_BUSY = reg_eb_busy;

parameter        EBCMD_X = 2'b01;        //X address
parameter        EBCMD_Y = 2'b10;        //Y address
parameter        EBCMD_P = 2'b11;        //Page Select
parameter        EBCMD_C = 2'b00;        //Color data

always @ ( negedge GCLK )
begin
        if( TFT_CLK == 1 )
                reg_tft_rgb = RAM_D1;
        else
                reg_tft_rgb = reg_tft_rgb;
                /*
                //Perp. TFT scan for next GCLK
                reg_ram_idx <= 1'b1;        //for scan addr;
                reg_ram_we1 <= 1'b1;
               
                //Now Read/Write
                if( reg_eb_busy )
                        begin
                        reg_eb_busy <= 1'b0;
                        if( reg_rw_ram_flg )        //Read;
                                reg_eb_dat = RAM_D1;
                        else
                                reg_eb_dat = reg_eb_dat;
                        end
                end
                */
end

always @ ( posedge GCLK )
begin
//---------EB BUS Oprating--------------------
        reg_eb_wr_q1 <= EB_WR;        reg_eb_wr_q2 <= reg_eb_wr_q1;
        reg_eb_rd_q1 <= EB_RD;        reg_eb_rd_q2 <= reg_eb_rd_q1;
       
        if( !EB_WR & reg_eb_wr_q2 & !EB_CS )        //EB Write
                begin
                        case( EB_A )
                        EBCMD_X:
                                begin
                                if( reg_cmd_xyhl==XYHL_STA )
                                        begin
                                        reg_cmd_x <= EB_D;
                                        reg_cmd_xyhl <= XYHL_END;
                                        end
                                else
                                        begin
                                        reg_cmd_x <= EB_D;
                                        reg_cmd_xyhl <= XYHL_STA;
                                        reg_cmd_addr <= reg_cmd_x+reg_cmd_y*10'd800;
                                        end
                                end
                        EBCMD_Y:
                                begin
                                if( reg_cmd_xyhl==XYHL_STA )
                                        begin
                                        reg_cmd_y <= EB_D;
                                        reg_cmd_xyhl <= XYHL_END;
                                        end
                                else
                                        begin
                                        reg_cmd_y <= EB_D;
                                        reg_cmd_xyhl <= XYHL_STA;
                                        reg_cmd_addr <= reg_cmd_x+reg_cmd_y*10'd800;
                                        end
                                end
                        EBCMD_C:
                                begin
                                reg_ram_wdr1 <= EB_D;
                                reg_cmd_xyhl <= XYHL_STA;
                                reg_eb_busy <= 1'b1;
                                reg_rw_ram_flg <= 1'b0;        //write
                                end
                        EBCMD_P:
                                begin
                        //        reg_cmd_x <= EB_D;
                        //        reg_cmd_xyhl <= XYHL_STA;
                        //        reg_next_sm <= 3d'2;
                                reg_rw_ram_flg <= 1'b1;
                        //        reg_cmd_addr <= reg_cmd_x+reg_cmd_y*10'd800;
                                reg_eb_busy <= 1'b1;
                                end
                        endcase
                end
       
        //---------RAM Scan Oprating------------------
        if( TFT_CLK == 1 )
                begin
                //Perp. TFT scan for next GCLK
                reg_ram_idx <= 1'b1;        //for scan addr;
                reg_ram_we1 <= 1'b1;
                end
        else
                begin
                if( TFT_DE == 1 )
                        begin
                        if( reg_scan_addr < 20'd480000 )
                                reg_scan_addr <= reg_scan_addr+1'b1;
                        else
                                reg_scan_addr <= 0;
                        end
                else
                        begin
                        if( reg_scan_addr < 20'd480000 )
                                reg_scan_addr <= reg_scan_addr;
                        else
                                reg_scan_addr <= 0;
                        end
                       
                //--------
                if( reg_eb_busy )
                        begin
                        reg_eb_busy <= 1'b0;
                        if( reg_rw_ram_flg )        //Read;
                                reg_ram_we1 <= 1'b1;
                        else
                                reg_ram_we1 <= 1'b0;
                               
                                reg_ram_idx <= 1'b0;
                                if( reg_cmd_addr < 20'd479999 )
                                        reg_cmd_addr <= reg_cmd_addr+1'b1;
                                else
                                        reg_cmd_addr <= 0;
                        end
                end       
end
endmodule



module TFT_CTRL(
        inputINCLK,
        inputRGB,
        output LCDCLK,
        output Hsync,
        output Vsync,
        output DE,
        output R0_3,
        output R1_4,
        output R2_5,
        output G0_3,
        output G1_4,
        output G2_5,
        output B0_2_4,
        output B1_3_5
);

//---------TFT LCD Ctrl-----------
//Ref the NL8060bc31-01 LCD Datasheet
reg thp= 1'b0;        //assign to TFT_Hsync
reg tvp= 1'b0;        //assign to TFT_Vsync
reg h_de = 1'b0;        //Hsync de
reg v_de = 1'b0;        //Vsync de
reg h_counter = 10'b00_0000_0000;        //1024 max
reg v_counter = 10'b00_0000_0000;        //1024 max

reg reg_tft_clk = 1'b0;
always @( posedge INCLK )
        reg_tft_clk <= ~reg_tft_clk;        //TFT CLK

assignLCDCLK = reg_tft_clk;


//Hsync & Vsync period counter (th&tv)
always @( posedge LCDCLK )
        if( h_counter==10'd1023 )//==th-1
        begin
                h_counter <= 0;
                if( v_counter==10'd624 )//==tv-1
                        v_counter <= 0;
                else
                        v_counter <= v_counter+1'b1;
        end
        else
                h_counter <= h_counter+1'b1;


//Hsync & Vsync & DE line control
assign Hsync = thp;
assign Vsync = tvp;
assign DE = h_de&v_de;

assign R2_5   = RGB;
assign R1_4   = RGB;
assign R0_3   = RGB;

assign G2_5   = RGB;
assign G1_4   = RGB;
assign G0_3   = RGB;

assign B1_3_5 = RGB;
assign B0_2_4 = RGB;

always @( posedge LCDCLK )
begin
        ///////////////////////////////////////////////////////////////////
        //
        //                Hsync Line Control
        //
        ///////////////////////////////////////////////////////////////////
        //thp period(72)
        if( h_counter<7'd72 )//<thp
                thp <= 0;
        else
                thp <= 1;
        //thb period(128) thd period(800)
        if( h_counter<8'd200 | h_counter>10'd999)        //hc<thp+thb | hc>thp+thb+thd-1
                h_de <= 0;
        else
                h_de <= 1;
       
        ///////////////////////////////////////////////////////////////////
        //
        //                Vsync Line Control
        //
        ///////////////////////////////////////////////////////////////////
        //tvp period(2)
        if( v_counter<3'd2 )//tvp
                tvp <= 0;
        else
                tvp <= 1;
        //tvb period(22)/tvd period(600)
        if( v_counter<5'd24 | v_counter>10'd623)        //vc<tvp+tvb | vc>tvp+tvb+tvd-1
                v_de <= 0;
        else
                v_de <= 1;
end

endmodule

honami520 发表于 2010-8-4 08:21:19

无图无真相

xjf20072608 发表于 2010-8-4 09:27:15

eworker 发表于 2010-8-4 09:46:43

坛子里这方面的高手不少。

hy317 发表于 2010-8-4 10:30:32

mark

whwlxl 发表于 2010-8-4 14:06:07

今天调试了一下,基本可以显示图片了。但是时序还要优化!
另外想问问:没有外部复位信号的CPLD如何自己复位?

40130064 发表于 2010-8-4 14:28:36

240宏够吗?我只有100脚的570 IO不够,正在郁闷中

R0,R1,R2, G0,G1,G2, B0,B1 这个是叫多少色?

LuoPan19770708 发表于 2010-8-4 18:26:38

这个应该上是256色。

whwlxl 发表于 2010-8-5 11:11:29

240肯定够,我用的就是别人的驱动板,自己没有画板子。也没钱打板子!

以前没有玩过verilog现在手头上有块转接板就自己玩玩练练手,说不定哪天能用上!

256色正解 因为一共才8位嘛!

niba 发表于 2010-8-5 17:27:14

用哪家的板子哦。。

zxky001 发表于 2010-8-5 23:03:43

www.mcutech.cn256色单片机并行总线控制TFT彩色液晶屏

whwlxl 发表于 2010-8-12 12:21:44

不知道是哪家的了,很旧的一块板子了,自己用万用表量了下引脚接口然会画了它的原理图,然后对着写程序!
现在已经能完全驱动了,单片机接口也可以操作了写x,y,color方式。只是数据从单片机写快了会有点闪屏(有麻点),
不写数据了又正常显示了,应该不是写数据或从RAM读数据到TFT的问题,因为只要不写数据就不闪屏(也没有麻点了)。

正在思考原因在哪!

again 发表于 2010-8-12 13:31:36

思路问题
解决办法,25M数据交替读写,外部写入速度降低到25M

again 发表于 2010-8-12 13:33:17

论坛不是有相应代码呀,好几位兄弟发过了

lvhaian 发表于 2010-8-12 13:36:06

还有下文么?

whwlxl 发表于 2010-8-12 14:53:24

回复【12楼】again
-----------------------------------------------------------------------
解决办法,25M数据交替读写,外部写入速度降低到25M

应该不是你说的这个问题,应该是Verilog中的逻辑问题,我现在在想办法找出问题的根源!

281229961 发表于 2010-8-12 15:56:40

楼主上原理图啊?

whwlxl 发表于 2010-8-12 16:09:33

这个板子简单的要死,就一片cpld和2片512k-8bitSRAM,然后外部与单片机的接口。和verilog无关,只是分配引脚的时候看看原理图就好了!

lvhaian 发表于 2010-8-12 16:25:10

现在进展如何了。

whwlxl 发表于 2010-8-12 17:39:26

回复【18楼】lvhaian 安哥
-----------------------------------------------------------------------------------
还没进展,读写以及显示都没有问题, 但是当读写数据时屏幕会出现麻子,读写晚后恢复正常,
还在找原因。

whwlxl 发表于 2010-8-14 15:40:23

郁闷,想了很多办法,依然是偶尔在写数据时,写错地方。

地址同步这个问题很麻烦啊!

tly823875 发表于 2010-8-14 17:13:46

回复【12楼】again
思路问题
解决办法,25m数据交替读写,外部写入速度降低到25m
-----------------------------------------------------------------------

我就是这样做的,呵呵!

bj-stm8 发表于 2010-8-14 17:42:16

这个要顶

whwlxl 发表于 2010-8-15 09:18:00

我的东西都弄好了,支持x,y设置,8bit颜色数据读写!
做完了才发现进步了很多,对于以前不理解的verilog里的东西也理解了很多!
希望以后多交流!

niba 发表于 2010-8-15 09:29:01

CPLD没写费了吧。。看资料只能刷100次

huaruinadz 发表于 2010-8-15 14:51:23

华瑞纳电子为您提供晶振全系列,各种厂家,封装,频点,质量保证,价格优势,长期现货,零售批发.联系范先生 QQ 659888573 手机13924789528http://store.taobao.com/shop/view_shop-9b9adcd49a1ea0bfe20910b1181045a6.htm
谢谢.

lvhaian 发表于 2010-8-15 14:52:28

【23楼】 whwlxl

能分享下么?

whwlxl 发表于 2010-8-15 19:16:32

回复【21楼】tly823875
-----------------------------------------------------------------------

哎,调试发现还是有偶尔有麻点出现,可能还是地址同步的问题,想了很多办法了。
我看了你的是18位地址总线,不需要计算地址,容易很多!我的是要先写2次8bit x, 2次8bit y,
然后自己计算地址。这个地方很容易出现问题。

tly823875 发表于 2010-8-16 09:38:21

回复【27楼】whwlxl
回复【21楼】tly823875
-----------------------------------------------------------------------
哎,调试发现还是有偶尔有麻点出现,可能还是地址同步的问题,想了很多办法了。
我看了你的是18位地址总线,不需要计算地址,容易很多!我的是要先写2次8bit x, 2次8bit y,
然后自己计算地址。这个地方很容易出现问题。
-----------------------------------------------------------------------
你走到我前面了,我还没有计算地址呢,我是实现了一个字节对应8个点而已。
你说的嘛点问题,我遇到过,我的解决方法是改变读写sram的位置,后来就没有了
另外还要注意:数据的延时问题,估计1~2个clk
显示图像要画出边框,才能准确的看到位置是否完全正确,分辨率太高,点细,放大镜也看不清楚,呵呵

whwlxl 发表于 2010-8-16 12:41:01

回复【28楼】tly823875
-----------------------------------------------------------------------
谢谢你的支持,关于像素对齐现在是没问题的,我放一副图片,边框用不同颜色来显示。就知道显示与写数据是否有偏移了。
地址计算涉及到乘法,延时严重。我的数据麻点只是出现在连续设置x,y地址然后写颜色时出现麻点。如果是写数据地址自动
+1模式不会出现麻点,不写数据更不会。分析下来主要是地址计算后的写入问题,这个同步关系要搞好。你可以试着这样做,
会麻烦很多的。特别是时序上的安排!因为我的数据线8位,地址线2位,

写入方式 A1~A0
   00: x 低, x 高;(写入完整后计算RAM地址)
   01: y 低, y 高;(写入完整后计算RAM地址)
   02: 颜色数据地址自动加1

读方式 A1~A0
   02: 颜色数据地址自动加1


郁闷啊!麻点(偶尔出现在连续设置x,y后写颜色数据到ram)这个难题真难解决。
我目前也是25兆的速度在搞,时钟0: 先读数据到TFT,然后地址增加1;时钟1:读/写 RAM数据如此交替。

capron 发表于 2010-8-16 15:56:29

这个要顶,继续观察

wangweigang0 发表于 2010-8-16 19:13:33

能不能把最新的程序公布下啊,想学习啊

li20030505 发表于 2010-8-17 21:49:14

mark

bad_fpga 发表于 2010-8-17 22:55:07

关注

zxky001 发表于 2010-8-17 23:46:58

http://cache.amobbs.com/bbs_upload782111/files_32/ourdev_575702.jpg
(原文件名:04.jpg)

beny 发表于 2010-8-18 09:12:44

做个记号

liurangzhou 发表于 2010-9-27 19:47:31

MARK

whwlxl 发表于 2010-10-23 11:18:19

问了下一些坛子的牛人,据说是要搞时序约束,不知道有没有这方面的资料和建议

Robbins 发表于 2014-5-8 19:50:07

逻辑设计是最重要的,不一定要做时序约束,只要能保证数据能正确写入和读出就没问题了。
页: [1]
查看完整版本: 50M晶振 EPM240 + 512KSRAM 做 800*600 TFT LCD 控制器