注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

东月之神

在单纯的观念里面,生命就容易变得比较深刻!

 
 
 

日志

 
 
关于我

别驻足,梦想要不停追逐,别认输,熬过黑暗才有日出,要记住,成功就在下一步,路很苦,汗水是最美的书!

网易考拉推荐

verilog lcd1602(转)  

2011-08-10 21:01:38|  分类: FPGA |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

顶层模块  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

  评论这张
 
阅读(224)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017