基于FPGA的LCD1602驱动

一、功能描述

本设计实现LCD_1602的接口,具体功能定义如下:

1、异步复位信号;

2、按下复位键后在LCD_1602液晶屏显示内部设置好的字符,每间隔0.1秒显示一个字符。

二、输入输出信号描述


三、设计思想

1、首先把50MHz的时钟信号转化为10Hz的信号,实现每0.1秒显示一个字符,设计一个分频器。

2、LCD_RW设置为0,因为只有写信号,没有读信号。

3、指令参数设置,LCD_RS设置为0,在每个10Hz时钟的上升沿,对LCD_DATA输入一个参数,实现内部参数的设置,依次为清零、归位、光标右移、画面不动、显示开、光标不显示、光标闪烁关、光标右移一个字符位、设置八位数据接口、两行显示、5*8点阵字符。

4、显示数据的输入,LCD_RS设置为1,在每个10Hz时钟的上升沿,对LCD_DATA输入一个8位字符代码并在液晶屏显示。

/*** code ***/

`define LINE_1 12   //the number of line 1
`define LINE_2 19   //the number of line 1 and line 2
//=========================================================
// Company:  Jackin
// Engineer: Jackin
//
// Create Date:   2012-2-26   
// Design Name:   LCD_1602   
// Module Name:   LCD_1602   
// Project Name:  LCD_1602   
// Target Device: EP2C35F672
// Tool versions: Modelsim SE PLUS 6.2b  &  Quartus II 9.0 
// Description:   CFAH1602B-TMC-JP port
//              
// Dependencies:
// 
// Revision:
// Additional Comments:
//=========================================================
module LCD_1602(reset,   
                clock,   
                LCD_DATA,
                LCD_RW,
                LCD_EN,
                LCD_RS,
                LCD_ON,
                LCD_BLON
                );

input reset;  //reset
input clock;  //50MHz Clock
 
output [7:0] LCD_DATA; //8-bit LCD DATA
output LCD_RW;   //LCD Read/Write Select,0=Write,1=Read
output LCD_EN;   //LCD Enable
output LCD_RS;   //LCD Command/Data select,0=Command,1=Data
output LCD_ON;   //LCD Power ON/OFF,0=OFF,1=ON
output LCD_BLON; //LCD Back Light ON/OFF,0=OFF,1=ON

reg LCD_RS;
reg [7:0] LCD_DATA;

//Fixed signal
assign LCD_ON = 1'b1;  //Power On
assign LCD_BLON = 1'b1;//Back Light On
assign LCD_RW = 1'b0;  //Because of no write,so LCD_RW signal
                       //is always low level

//---------------------------------------------------------
//Produce 10Hz clock signal
//---------------------------------------------------------

reg LCD_CLOCK;    //10Hz Clock
reg [21:0] count; //counter

always@(posedge clock or negedge reset)
begin
   if(!reset)  //reset
       begin 
       count <= 22'd0;
       LCD_CLOCK <= 1'b0;
       end
   else if(count == 2499999)  //20Hz turn
       begin
       count <= 22'd0;
       LCD_CLOCK <= ~LCD_CLOCK;
       end
   else
       count <= count + 1'b1;  //count
end

//enable negative edge
assign LCD_EN = LCD_CLOCK;

//---------------------------------------------------------
//LCD internal parameter Settings
//---------------------------------------------------------

//Set parameters 
parameter     IDLE = 10'b00_0000_0000; //initial state
parameter    CLEAR = 10'b00_0000_0001; //clear
parameter   RETURN = 10'b00_0000_0010; //return home
parameter     MODE = 10'b00_0000_0100; //entry mode set
parameter  DISPLAY=10'b00_0000_1000;//display ON/OFF control
parameter   SHIFT=10'b00_0001_0000;//cursor or display shift
parameter FUNCTION = 10'b00_0010_0000; //function set
parameter    CGRAM = 10'b00_0100_0000; //set CGRAM address
parameter    DDRAM = 10'b00_1000_0000; //set DDRAM address
parameter    WRITE = 10'b01_0000_0000; //write data to RAM
parameter     STOP = 10'b10_0000_0000; //release control

reg [9:0] state; //state machine code
reg [5:0] char_count;  //char counter
reg [7:0] data_display;//display data

//If read,LCD_RS is high level,else is low level
always@(posedge LCD_CLOCK or negedge reset)
begin
    if(!reset)
       LCD_RS <= 1'b0;
    else if(state == WRITE)
       LCD_RS <= 1'b1;
    else
       LCD_RS <= 1'b0;
end

//State machine
always@(posedge LCD_CLOCK or negedge reset)
begin
   if(!reset)
   begin
       state <= IDLE;
       LCD_DATA <= 8'bzzzz_zzzz;
       char_count <= 6'd0;
   end
   else
   begin
      case(state)
      //start
      IDLE:begin  
            state <= CLEAR;
            LCD_DATA <= 8'bzzzz_zzzz;
           end
      //clear
      CLEAR:begin  
             state <= RETURN;
             LCD_DATA <= 8'b0000_0001;
            end 
      //home
      RETURN:begin  
             state <= MODE;
             LCD_DATA <= 8'b0000_0010;
             end
      //cursor move to the right
      //display don't move
      MODE:begin  
             state <= DISPLAY;
             LCD_DATA <= 8'b0000_0110;
           end
      //display on
      //cursor and blinking of cursor off
      DISPLAY:begin  
             state <= SHIFT;
             LCD_DATA <= 8'b0000_1100;
              end
      //cursor moving
      //move to the right
      SHIFT:begin  
             state <= FUNCTION;
             LCD_DATA <= 8'b0001_0100;
            end
      //Set interface data length(8-bit)
      //numbers of display line(2-line)
      //display font type(5*8 dots)
      FUNCTION:begin
             state <= DDRAM;
             LCD_DATA <= 8'b0011_1000;
               end
      //Set DDRAM address in address counter
      DDRAM:begin
             state <= WRITE;
             if(char_count <= `LINE_1)
                LCD_DATA <= 8'b1000_0000;//line 1
             else
                LCD_DATA <= 8'b1100_0000;//line 2
            end
      //Write data into internal RAM
      WRITE:begin
             if(char_count == `LINE_1)
                state <= DDRAM;
             else
                state <= WRITE;
             if(char_count == `LINE_2)
                state <= STOP;
             char_count <= char_count + 1'b1;
             LCD_DATA <= data_display;
            end
      //Finish
      STOP:state <= STOP;
      //Other state
      default:state <= IDLE;
      endcase   
   end
end

//---------------------------------------------------------
//the data of display
//---------------------------------------------------------

always@(char_count)
begin
   case(char_count)
       6'd0: data_display = "H";
       6'd1: data_display = "e";
       6'd2: data_display = "l";
       6'd3: data_display = "l";
       6'd4: data_display = "o";
       6'd5: data_display = ",";
       6'd6: data_display = "J";
       6'd7: data_display = "a";
       6'd8: data_display = "c";
       6'd9: data_display = "k";
       6'd10: data_display = "i";
       6'd11: data_display = "n";
       6'd12: data_display = "!";
       6'd13: data_display = "W";
       6'd14: data_display = "e";
       6'd15: data_display = "l";
       6'd16: data_display = "c";
       6'd17: data_display = "o";
       6'd18: data_display = "m";
       6'd19: data_display = "e";
       default:data_display = 8'd32;
   endcase
end
endmodule

你可能感兴趣的:(FPGA)