原创 FPGA1602液晶显示

2010-5-25 22:00 4772 8 11 分类: FPGA/CPLD


前几天参加学校的FPGA比赛,做的是频率检测器,就2天时间,做的还可以,从1HZ1MHZ,结果用1602液晶显示,还没有整理好,等整理好了也拿出来,先把1602液晶显示部分整理了下,拿出来和大家分享,我用的板子是EP<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />1C3T144C8N,时钟是24MHZ跑起来没有问题。


<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 


代码我还是贴上来,直接上了……..


 


顶层模块  lcd.v


`timescale 1ns / 1ps


module lcd (


              clk,sys_rst_n,


                       lcd_en,lcd_rs,lcd_rw,


                       lcd_data


                     );


                    


input clk;              //时钟24MHz,周期为41.6ns


input sys_rst_n;        //系统复位信号,低电平复位


 


output lcd_en;          //使能信号,1时读取信息,10(下降沿)执行指令


output lcd_rs;          // 0=输入指令,1=输入数据


output lcd_rw;          //0=LCD写入指令或数据,1=LCD读取信息


output[7:0] lcd_data;     //LCD数据信号


 


 


wire    clk_lcd;        //用于将clk_div模块输出的clk_lcd链接到lcd_ctrl


 


clk_div          U1(      


                                   .clk(clk),


                                   .sys_rst_n(sys_rst_n),


                                   .clk_lcd(clk_lcd)


                                   );


         


lcd_ctrl       U2(


                                   .clk_lcd(clk_lcd),


                                   .sys_rst_n(sys_rst_n),


                                   .lcd_en(lcd_en),


                                   .lcd_rs(lcd_rs),


                                   .lcd_rw(lcd_rw),


                                   .lcd_data(lcd_data)


                            ); 


            


Endmodule


 


分频模块clk_div.v


 


`timescale 1ns / 1ps


module clk_div (


                                   clk,sys_rst_n,


                                   clk_lcd


                            );


 


input   clk;


input   sys_rst_n;                //sys_rst_n为全局复位信号(高电平有效)             


output  clk_lcd;                   //clk_lcd链接到lcd_ctrl


 


reg     [19:0]  cnt;                  //对时钟进行计数分频


reg     clk_BUF;


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


** 模块名称:分频器


** 功能描述:通过计数器实现分频功能.


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


 


always @ (posedge clk or negedge sys_rst_n)


       if(!sys_rst_n)                            //低电平复位


              cnt <= 20'd0;


       else if(cnt >= 26026)                     //学习特权同学,提高代码健壮性


              cnt <= 20'd0;


    else


              cnt <= cnt+1'b1;


             


always @ (posedge clk or negedge sys_rst_n)


    if(!sys_rst_n)


              clk_BUF <= 0;


    else if(cnt == 26026) 


              clk_BUF <= ~clk_BUF;


 


assign clk_lcd = clk_BUF;


 


    


endmodule


 


液晶显示控制模块lcd_ctrl.v


`timescale 1ns / 1ps


module lcd_ctrl (


                  clk_lcd,sys_rst_n,


                              lcd_rs,lcd_rw,lcd_en,


                              lcd_data


                );    


                    


input clk_lcd;


input sys_rst_n;           //系统复位信号,低电平复位


 


output lcd_rs;           // 0=输入指令,1=输入数据


output lcd_rw;           //0=LCD写入指令或数据,1=LCD读取信息


output lcd_en;           //使能信号,1时读取信息,10(下降沿)执行指令


output[7:0] lcd_data;     //LCD数据信号


 


 


parameter      CLEAR          = 4'd1,        //清屏指令


                     SETFUNCTION    = 4'd2,        //模式设置指令


                     SWITCHMODE     = 4'd3,        //开关控制指令


                     SETMODE        = 4'd4,        //设定显示屏或光标移动方向指令


                     SETDDRAM_1     = 4'd5,        //设定第一行DDRAM地址指令


                     WRITERAM_1     = 4'd6,          //向第一行写入的数码


                     WRITERAM_2     = 4'd7,


                     IDLE           = 4'd8;        //空闲


                    


reg[127:0] Data_First = "www.endchina.com";                  //液晶显示的第一行的数据


reg[127:0] Data_Second = "   chick_kid    ";                 //液晶显示的第二行的数据


 


reg     [127:0] Data_First_Buf,Data_Second_Buf;     //液晶显示的数据缓存


 


//LCD状态机寄存器


reg[3:0] state;     //当前状态寄存器


 


reg lcd_rs_reg = 1'b0;          //lcd_rs输出寄存器


reg lcd_rw_reg = 1'b0;           //lcd_rw输出寄存器


reg[7:0] lcd_data_reg;                 //lcd_data输出寄存器


reg lcd_en_sel;


 


reg     [5:0] display_count;


 


//状态控制


always @ (posedge clk_lcd or negedge sys_rst_n)


       if(!sys_rst_n)


              begin


                     state <= CLEAR;                        


                     lcd_rs_reg <= 1'b0;                                                       


                     lcd_data_reg <= 8'b00000000;                                   


                     lcd_en_sel <= 1'b1;                           


                     display_count <= 4'b0;


              end  


       else   


    case(state)


              CLEAR:begin


                            state <= SETFUNCTION;


                            lcd_data_reg <= 8'b00000001;


              end


              SETFUNCTION:begin


                            state <= SWITCHMODE;


                            lcd_data_reg <= 8'b00111000;


        end       


              SWITCHMODE:begin


                            state <= SETMODE;


                            lcd_data_reg <= 8'b00001100;


              end


              SETMODE:begin


                            state <= SETDDRAM_1;


                            lcd_data_reg <= 8'b00000110;


              end


              SETDDRAM_1:begin


                            state <= WRITERAM_1;


                            lcd_data_reg <= 8'b10000000;              //写入第一行显示起始地址:第一行第二个位置   


                Data_First_Buf <= Data_First;


              end


              WRITERAM_1:begin


                if(display_count == 6'd16)               //display_count等于14时表示第一行数据已写完


                    begin


                        lcd_data_reg <= 8'b11000000;     //送入写第二行的指令


                        lcd_rs_reg <= 1'b0;


                        display_count <= 4'b0;


                        Data_Second_Buf <= Data_Second;


                        state <= WRITERAM_2;             //写完第一行进入写第二行状态


                    end


                else


                    begin


                        lcd_data_reg <= Data_First_Buf[127:120];


                        Data_First_Buf <= (Data_First_Buf << 8);


                        lcd_rs_reg <= 1'b1;                         //RS=1表示写数据


                        display_count <= display_count + 1'b1;


                        state <= WRITERAM_1;


                    end


            end


              WRITERAM_2:begin


                if(display_count == 6'd16)


                    begin


                        lcd_en_sel <= 1'b0;


                        lcd_rs_reg <= 1'b0;


                        display_count <= 4'b0;


                        state <= IDLE;                      //写完进入空闲状态


                    end


                else


                    begin


                        lcd_data_reg <= Data_Second_Buf[127:120];


                        Data_Second_Buf <= (Data_Second_Buf << 8);


                        lcd_rs_reg <= 1'b1;


                        display_count <= display_count + 1'b1;


                        state <= WRITERAM_2;


                    end             


            end


              IDLE:begin


                            state <= IDLE;


                     end       


              default:state <= CLEAR;


       endcase


      


/*


功能设定指令


 


  指令功能                           指令编码                  执行时间


                        RS  R/W  DB7  DB6  DB5  DB4  DB3  DB2  DB1  DB0  /us  


       功能设定   0    0    0    0    1    DL   N    F    X    X   40   


功能:设定数据总线位数、显示的行数及字型。参数设定的情况如下:


      位名    设置


      DL      0=数据总线为4        1=数据总线为8


      N       0=显示1              1=显示2


      F       0=5×7点阵/每字符      1=5×10点阵/每字符


        


显示开关控制指令


 


       指令功能                                           指令编码               执行时间                 


             RS  R/W  DB7  DB6  DB5  DB4  DB3  DB2  DB1  DB0  /us  


显示开关控制 0    0    0    0    0    0    1    D    C    B    40  


功能:控制显示器开/关、光标显示/关闭以及光标是否闪烁。参数设定的情况如下:


      位名    设置


       D      0=显示功能关     1=显示功能开


       C      0=无光标         1=有光标


       B      0=光标闪烁       1=光标不闪烁


 


清屏指令


 


    指令功能                             指令编码                 执行时间


             RS  R/W  DB7  DB6  DB5  DB4  DB3  DB2  DB1  DB0  /ms  


    清屏     0    0    0    0    0    0    0    0    0    1   1.64 


 


功能:<1> 清除液晶显示器,即将DDRAM的内容全部填入"空白"ASCII20H;


      <2> 光标归位,即将光标撤回液晶显示屏的左上方;


      <3> 将地址计数器(AC)的值设为0


 


设定显示屏或光标移动方向指令


 


     指令功能                          指令编码                执行时间


             RS  R/W  DB7  DB6  DB5  DB4  DB3  DB2  DB1  DB0  /us  


设定显示屏或 0    0    0    0    0    1   S/C  R/L   X    X    40  


光标移动方向                                              


 


功能:使光标移位或使整个显示屏幕移位。参数设定的情况如下:


      S/C     R/L      设定情况


      0       0        光标左移1格,且AC值减1


      0       1        光标右移1格,且AC值加1


      1       0        显示器上字符全部左移一格,但光标不动


      1       1        显示器上字符全部右移一格,但光标不动


*/


assign lcd_rw = lcd_rw_reg;


assign lcd_rs = lcd_rs_reg;


assign lcd_data = lcd_data_reg;


assign lcd_en = lcd_en_sel ? clk_lcd : 1'b0;


 


endmodule


 


觉得注释的还算详细吧,有什么错误的地方请大家指教,一起学习,嘿嘿

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户1638582 2013-8-20 11:47

不错不错,正在学习,感谢分享!

用户402547 2012-12-25 20:42

很好,很详细。

用户383871 2011-9-15 15:53

您好,想请教FPGA ,您能留一下联系方式吗?谢谢
相关推荐阅读
用户1526653 2010-11-20 21:32
计划赶不上变化
                        好久不来跟新blog,从5月份一直忙,项目,找工作,各种忙。现在总算是心不忙了。在这里我们都可以畅所欲言,时间好快,一混大4了,明年7月份即将走上工作岗...
用户1526653 2010-06-14 18:19
AVR 关于M25P80flash的储存模块 有问题,求助!!!!!!!!!!
    硬件电路   帮老师做的项目,中间有个数据储存模块,还有个AD采样模块,之前也在这上面求助过关于AD多通道采样,后来自己解决了,最后一个M25P80的数据储存模块,我们2个人调了一个星期了,不...
用户1526653 2010-06-06 17:16
FPGA Power Pins
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = ...
用户1526653 2010-05-29 22:28
CLK PLL 浅析
         因为这次做的频率检测系统中,用到了高频时钟输入,一直也想把PLL的输出搞清楚,今天就拿一个简单的程序,自己分析下,实验室有3块板子,因为用EP<?xml:namespace p...
用户1526653 2010-05-27 20:50
FPGA VGA 显示
        今天花了半天的时间把VGA做出来了,800*600液晶显示器,非常的完美。先跟大家分享一个网站,这个网站上列举了基本上所有VGA显示器的时序。个人觉得做的非常好,有兴趣的同学可以挑一个...
EE直播间
更多
我要评论
3
8
关闭 站长推荐上一条 /3 下一条