原创 tft verilog驱动

2010-11-27 18:58 6678 10 12 分类: FPGA/CPLD

       使用的TFT为群创7寸液晶屏AT070TN83,分辨率为800*480FPGA为ep1c6q240c8,晶振为50M


       首先介绍一下TFT接口


       1和2脚VLED,4和5脚GLED,3脚为ADJ。VLED和GLED为背光电源和地,ADJ为用PWM调整背光亮度脚,频率应在100-300HZ,占空比越高越亮。本人背光电源用的+5v


       6和7脚为数字电路部分电源。本人用的是3.3v


       12,16,20,24,28,32,36,38为地


8脚为MODE,9脚为DE,10脚VS,11脚HS。当选用DE模式时HS和VS应浮空,当选用HV模式时,DE脚应浮空。本人使用的是HV模式。


13,14,15,17,18,19分别为b5,b4,b3,b3,b1,b0。本人b0脚未用,直接接地


21,22,23,25,26,27分别为g5,g4,g3,g2,g1,g0


29,30,31,33,34,35分别为 r5,r4,r3,r2,r1,r0。本人r0脚未用 ,直接接地


37脚为DCLK


39脚为L/R,40脚为U/D。本人40脚接地,39脚接高电平,为从左到右,从上到下扫描




这样我总共用了16根颜色信号线分别为5根R,6根G,5根B线。还需要fpga控制的是DCLK,HS,VS,和ADJ脚。


下面附上HV模式下hs和vs的脉冲数的说明




 




本人使用汉字取模软件得到“液晶测试”4个汉字的字模,如下


/////////////////////////////////////////////////////////////////////////


// 汉字字模表                                                          //


// 汉字库: 宋体16.dot,横向取模左高位,数据排列:从左到右从上到下         //


/////////////////////////////////////////////////////////////////////////


struct typFNT_GB16 code GB_16[] =          // 数据表


{


"液", 0x00,0x80,0x40,0x44,0x37,0xFE,0x10,0x20,


      0x81,0x20,0x61,0x3C,0x22,0x44,0x0A,0x64,


      0x16,0x98,0x2B,0x48,0xE2,0x50,0x22,0x20,


      0x22,0x50,0x22,0x8E,0x23,0x04,0x22,0x00,


 


"晶", 0x0F,0xE0,0x08,0x20,0x08,0x20,0x0F,0xE0,


      0x08,0x20,0x08,0x20,0x0F,0xE0,0x08,0x24,


      0x7E,0xFE,0x42,0x84,0x42,0x84,0x7E,0xFC,


      0x42,0x84,0x42,0x84,0x7E,0xFC,0x42,0x84,


 


"测", 0x00,0x00,0x40,0x44,0x27,0xE4,0x24,0x54,


      0x85,0x54,0x65,0x54,0x25,0x54,0x0D,0x54,


      0x15,0x54,0x25,0x54,0xE5,0x54,0x21,0x04,


      0x22,0x84,0x24,0x44,0x28,0x54,0x20,0x08,


 


"试", 0x00,0x20,0x40,0x28,0x20,0x24,0x20,0x20,


      0x0F,0xFE,0x00,0x20,0xE0,0x20,0x27,0xE0,


      0x21,0x20,0x21,0x10,0x21,0x10,0x21,0x10,


      0x29,0xD2,0x37,0x12,0x22,0x0A,0x00,0x04


};


将这些字模数据放在fpga的256*8的mif文件里面(其实128*8就够用了),如下




然后用Tools->MegaWizard Plug-in Manager建立一个tft_rom.v,保存这些数据。


Tft显示程序如下。最终显示结果为屏幕底色为蓝色,中间有个绿色的方框,“液晶测试”字为白色,底色为红色。这4个字沿着方框内部,每隔3s顺指针换一个位置。


程序中计数器没有优化。


/**********************************************************************


*project name :tft


*module name       :tft


*designer        :kang


*version         :1.00


*date              :2010-11-27


**********************************************************************/


module tft             (


                                   //input signals


input                            clk,


input                            rst,


                                   //output signals


output                  vs,


output                  hs,


output                  dclk,


output     reg          adj,


output [4:0]    r,


output [5:0]    g,


output [4:0]    b


                            );


 


//counter_x and counter_y


reg [9:0] counter_x;


reg [9:0] counter_y;


always @(posedge clk or negedge rst)


       begin


       if(!rst) counter_x<=0;


       else if(counter_x>=10'd928) counter_x<=0;


       else counter_x<=counter_x+1'b1;


       end


 


always @(posedge clk or negedge rst)


       begin


       if(!rst) counter_y<=0;


       else if(counter_y>=10'd525) counter_y<=0;


       else if(counter_x>=10'd928) counter_y<=counter_y+1'b1;


       end


 


//adj


reg [31:0] counter_pwm;


always @(posedge clk or negedge rst)


       begin


       if(!rst) counter_pwm<=0;


       else if(counter_pwm>=32'd125000) counter_pwm<=0;


       else counter_pwm<=counter_pwm+1'b1;


       end


 


always @(posedge clk or negedge rst)


       begin


       if(!rst) adj<=0;


       else if(counter_pwm==32'd125000) adj<=~adj;


       end


 


//hs and vs


assign hs=(counter_x<=10'd48);


assign vs=(counter_y<=3);


 


//dclk


assign dclk=clk;


 


//pos_x and pos_y


wire [9:0] pos_x;


wire [9:0] pos_y;


assign pos_x=(counter_x-10'd88);


assign pos_y=(counter_y-10'd32);


 


//valid


wire valid;


assign valid=(pos_x<=10'd800)&&(pos_y<=640);


 


//word


wire word_valid;


reg [9:0] word_origin_x;


reg [9:0] word_origin_y;


reg [31:0] count_word;


always @(posedge clk or negedge rst)


       begin


       if(!rst) count_word<=0;


       else if(count_word==100000000) count_word<=0;


       else count_word<=count_word+1'b1;


       end


reg dir_word_x;


reg dir_word_y;


reg dir_word_x_en;


reg dir_word_y_en;


always @(posedge clk or negedge rst)


       begin


       if(!rst)


              begin


              dir_word_x<=0;


              dir_word_y<=0;


              dir_word_x_en<=1'b1;


              dir_word_y_en<=0;


              end


       else if(dir_word_x_en&!dir_word_x&(word_origin_x==10'd640))


              begin


              dir_word_x<=1'b1;


              dir_word_y<=1'b0;


              dir_word_x_en<=1'b0;


              dir_word_y_en<=1'b1;


              end


       else if(dir_word_x_en&dir_word_x&(word_origin_x==10'd128))


              begin


              dir_word_x<=1'b0;


              dir_word_y<=1'b1;


              dir_word_x_en<=0;


              dir_word_y_en<=1'b1;


              end 


       else if(dir_word_y_en&!dir_word_y&(word_origin_y==10'd416))


              begin


              dir_word_x<=1'b1;


              dir_word_y<=1'b1;


              dir_word_x_en<=1'b1;


              dir_word_y_en<=1'b0;


              end


       else if(dir_word_y_en&dir_word_y&(word_origin_y==10'd32))


              begin


              dir_word_x<=1'b0;


              dir_word_y<=1'b0;


              dir_word_x_en<=1'b1;


              dir_word_y_en<=1'b0;


              end


       end


 


always @(posedge clk or negedge rst)


       begin


       if(!rst)


              begin


              word_origin_x<=0;


              word_origin_y<=0;


              end


       else if((word_origin_x<128)||(word_origin_x>640)||(word_origin_y<32)||(word_origin_y>416))


              begin


              word_origin_x<=10'd128;


              word_origin_y<=10'd32;


              end


       else if(count_word==100000000)


              begin


              if(dir_word_x_en)


                     begin


                     if(dir_word_x) word_origin_x<=word_origin_x-10'd128;


                     else word_origin_x<=word_origin_x+10'd128;


                     end


              else if(dir_word_y_en)


                     begin


                     if(dir_word_y) word_origin_y<=word_origin_y-10'd32;


                     else word_origin_y<=word_origin_y+10'd32;


                     end


              end


       end


assign word_valid=(pos_x>=word_origin_x)&(pos_x<=(word_origin_x+10'd128))&


                            (pos_y>=word_origin_y)&(pos_y<=(word_origin_y+10'd32));


//assign word_valid=1'b1;


wire line_valid;


assign line_valid=((pos_x>=10'd110)&(pos_x<=10'd790)&(pos_y>=10'd10)&(pos_y<=10'd470))&


                            ((pos_x>=10'd780)||(pos_x<=10'd120)||(pos_y>=10'd460)||(pos_y<=10'd20));


 


 


//assign r,g and b


wire [2:0] bitx;


assign bitx=3'd7-pos_x[3:1];


assign r=(!valid)?5'h0line_valid)?5'h00!word_valid)?5'h00:dat[bitx]?5'h1f:5'h1f;


assign g=(!valid)?6'h0line_valid)?6'h3f!word_valid)?6'h00:dat[bitx]?6'h3f:6'h0;


assign b=(!valid)?5'h0line_valid)?5'h00!word_valid)?5'h1f:dat[bitx]?5'h1f:5'h0;


 


//dat


wire [7:0] dat;


tft_rom U1(


                     .address({1'b0,pos_x[6:5],pos_y[4:1],pos_x[4]}),


                     .clock(clk),


                     .q(dat)


                     );


 


                                  


endmodule

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户377235 2016-4-21 21:07

那要怎么更新?

用户377235 2014-4-23 15:24

可以将真个工程文件发给我参考一下吗?524913017@qq.com。

用户372420 2011-6-1 16:55

我最近搞了一块n83液晶屏,但是不知道怎么下手去弄。一直纠结我的问题是,液晶的引脚是不是直接接到fpga上,还是要经过什么处理才能接到fpga上?麻烦作者说一下!
相关推荐阅读
用户282447 2011-01-19 17:05
stm32使用fsmc时地址移位问题
stm32平台使用fsmc时,当操作数据宽度为8位时,HADDR【25:0】与FSMC【25:0】对齐,当操作的数据为16位时,HADDR【25:1】与FSMC【24:0】对齐,HADDR【0】未接。...
用户282447 2011-01-05 19:42
verilog分频
fpga程序里经常会遇见给一个50 MHZ的clk,然后产生一个可变频率的clk‘。尤其是在电机控制中,加减速需要便频率,而fpga中除法又比较耗资源。今天看到一个程序,觉得思想不错,整理如下。   ...
用户282447 2011-01-01 23:47
2011,回顾从前
毕业第一年。    2010很快过去了,大学生活也已经成了历史,貌似很近,又貌似很远。    2011已经来临,是时候该回顾回顾自己大学至今都在做什么了。俗话说,男的把电脑当游戏机,女的把电脑当影碟机...
用户282447 2010-12-24 11:33
sdram verilog程序
sdram芯片用的是hy57v641620hgt-7,fpga用的是EP1C6Q240C8,晶振是50M,经过PLL倍频至125M,系统clk时钟是125M,sdram时钟相移-3ns程序是根据特权的...
用户282447 2010-12-24 11:26
串口verilog程序
发一个自己写的串口程序,波特率115200,一位起始位,8个数据位,一个停止位接收采用8倍过采样。下面有4个module,uart是顶层模块,uart_rx是接收模块,uart_tx是发送模块,uar...
我要评论
2
10
关闭 站长推荐上一条 /3 下一条