Lab 11 LCD
Lab 11 LCD
Lab 11 LCD
The most widely used character LCDs are the ones that include the Hitachi HD44780 LCD
controller. Character LCDs generally include 14 pins as a contact interface. In addition to these
pins, LCDs also have 2 extra pins for backlight power supply terminals. The pin out and pin
description is as follows:
RS (register select) pin: There are two important registers inside the LCD. This pin is used
for their selection. If RS = 0, the instruction command code register is selected, then
allowing the user to send a command such as clear display, set cursor move etc. If RS=1,
the data register is selected and allowing the user to send data to be displayed on the
LCD.
R/W (read/write) pin: This pin allows the user to write information from LCD. If R/W = 1,
data can be read from LCD, if R/W=0, data can be sent to LCD so that LCD displays
E (enable) pin: This pin is used by the LCD to latch information presented to its data
pins. When data is supplied to data pins, a high-to-low pulse must be applied to this pin
in order to for the LCD to latch in data presented at the data pins.
D0-D7 (Data Lines) pins: These pins are used to send information to the LCD or read the
contents of the LCD’s internal registers.
VDD, VSS and VEE: The voltage VCC and VSS provided by +5V and ground respectively
while VEE is used for controlling LCD contrast. Variable voltage on the VEE pin is used to
specify the contrast (or darkness) of the characters on the LCD screen
An LCD screen consist of two lines each containing 16 characters. Each character consists of 5x8
and 5x11 dot matrix.
DDRAM memory is used for storing characters to be displayed. The size of this memory is
sufficient for storing 80 characters. Some memory locations are directly connected to the
characters on display. Its works quite simply: it is sufficient to configure the display so as to
increment addresses automatically (shift right) and set the starting address for the message
that should be displayed (for example 00 hex).
After that, all characters sent through lines D0-D7 will be displayed in the message format we
are used to- from left to right. In this case, displaying starts from the first field of the first line
since the address is 00 hex. If more than 16 characters are sent, then all of them will be
memorized, but only the first sixteen characters will be visible. In order to display the rest of
them, a shift command should be used.
CG ROM memory contains the default character map with all characters that can be displayed
on the screen. Each character is assigned to one memory location. The addresses of CGROM
memory locations match the characters of ASCII. If the program being currently executed
encounters a command “send character P to port”, then the binary value 0101 0000 appears on
the port. This value is the ASCII equivalent to the character P. It is then written to LCD, which
results in displaying the symbol from 0101 0000 location of CGROM. In other words, the
character “P” is displayed. This applies to all letters of alphabet (capitals and small), but not to
numbers.
Apart from standard characters, the LCD display can also display symbols defined by the user
itself. It can be any symbol in the size of 5x8 pixels. RAM memory called CGRAM in the size of
64 bytes enables it. Memory registers are 8 bits wide, but only 5 lower bits are used. Logic one
(1) in every register represents a dimmed dot, while 8 locations grouped together represent
one character. It is best illustrated in figure below:
The Spartan™-3A FPGA Starter Kit board prominently features a 2-line by 16-character liquid
crystal display (LCD). The FPGA controls the LCD via the eight-bit data interface shown in Figure.
The Spartan-3A Starter Kit board also supports the four-bit data interface to remain compatible
with other Xilinx development boards.
Lab Task1: Follow the VERLIOG code shown below, and design the 16x2 LCD controller.
The controller first send the command to configure LCD and then send a String
“NUTECH ” to display. First simulate the design by writing the test bench and then
implement your design on FPGA board.
module LCD_FSM (
// Data Pins
output reg [7:0] LCD_DATA,
// Control Pins
output reg LCD_ENABLE,
output reg LCD_RS,
// Clock
input CLK,
input RST
);
//
// State parameters
parameter S0 = 5'd0, S1 = 5'd1, S2 = 5'd2, S3 = 5'd3, S4 = 5'd4,
S5 = 5'd5, S6 = 5'd6, S7 = 5'd7, S8 = 5'd8, S9 = 5'd9,
S10 = 5'd10, S11 = 5'd11, S12 = 5'd12, S13 = 5'd13,
S14 = 5'd14, S15 = 5'd15, S16 = 5'd16, S17 = 5'd17,
S18 = 5'd18, S19 = 5'd19, S20 = 5'd20, S21 = 5'd21,
S22 = 5'd22, S23 = 5'd23, S24 = 5'd24, S25 = 5'd25,
S26 = 5'd26, S27 = 5'd27, IDLE = 5'd28;
end
else begin
cnt <= cnt + 1;
end
case (current_state)
//-------------------Function Set-------------------
S0: begin
current_state <= S1;
LCD_DATA <= 8'h38;
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b0;
end
S1: begin
current_state <= S2;
LCD_DATA <= 8'h38;
LCD_ENABLE <= 1'b1;
LCD_RS <= 1'b0;
end
S2: begin
current_state <= S3;
LCD_DATA <= 8'h38;
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b0;
end
//-------------------Reset Display-------------------
S3: begin
current_state <= S4;
LCD_DATA <= 8'b00000001;
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b0;
end
S4: begin
current_state <= S5;
LCD_DATA <= 8'b00000001;
LCD_ENABLE <= 1'b1;
LCD_RS <= 1'b0;
end
S5: begin
current_state <= S6;
LCD_DATA <= 8'b00000001;
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b0;
end
//-------------------Display On-------------------
S6: begin
current_state <= S7;
LCD_DATA <= 8'b00001110;
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b0;
end
S7: begin
current_state <= S8;
LCD_DATA <= 8'b00001110;
LCD_ENABLE <= 1'b1;
LCD_RS <= 1'b0;
end
S8: begin
current_state <= S9;
LCD_DATA <= 8'b00001110;
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b1;
end
// Display "NUTECH"
S9: begin
current_state <= S10;
LCD_DATA <= 8'h4E; // N
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b1;
end
S10: begin
current_state <= S11;
LCD_ENABLE <= 1'b1;
LCD_RS <= 1'b1;
end
S11: begin
current_state <= S12;
LCD_DATA <= 8'h55; // U
LCD_ENABLE <= 1'b1;
LCD_RS <= 1'b1;
end
S12: begin
current_state <= S13;
LCD_DATA <= 8'h55; // U
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b1;
end
S13: begin
current_state <= S14;
LCD_DATA <= 8'h54; // T
LCD_ENABLE <= 1'b1;
LCD_RS <= 1'b1;
end
S14: begin
current_state <= S15;
LCD_DATA <= 8'h54; // T
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b1;
end
S15: begin
current_state <= S16;
LCD_DATA <= 8'h45; // E
LCD_ENABLE <= 1'b1;
LCD_RS <= 1'b1;
end
S16: begin
current_state <= S17;
LCD_DATA <= 8'h45; // E
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b1;
end
S17: begin
current_state <= S18;
LCD_DATA <= 8'h43; // C
LCD_ENABLE <= 1'b1;
LCD_RS <= 1'b1;
end
S18: begin
current_state <= S19;
LCD_DATA <= 8'h43; // C
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b1;
end
S19: begin
current_state <= S20;
LCD_DATA <= 8'h48; // H
LCD_ENABLE <= 1'b1;
LCD_RS <= 1'b1;
end
S20: begin
current_state <= S21;
LCD_DATA <= 8'h48; // H
LCD_ENABLE <= 1'b0;
LCD_RS <= 1'b1;
end
// Inputs
reg CLK;
reg RST;
// Outputs
wire [7:0] LCD_DATA;
wire LCD_ENABLE;
wire LCD_RS;
initial begin
// Initialize Inputs
CLK = 0;
RST = 1;
end
endmodule
Waveform: