Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
961 Views

driving character lcd

Hi all. 

I am wondering how to drive the character lcd on the Cyclone III development kit. I can understand as far as driving a seven segment display. I assume it is almost the same concept i.e. some form of mapping to the character codes are required. 

 

I have a written an arithmetic block in verilog and would like to display the answer on the character lcd. Is it just adding another verilog module to do this, or does it involve something else? 

 

I had a look at the fpgaforfun link http://www.fpga4fun.com/textlcdmodule.html 

and cannot understand where the 'C' part comes in. 

 

Thanks.
0 Kudos
5 Replies
Altera_Forum
Honored Contributor I
57 Views

Usually the LCD is driven by a CPU and some software written in C. 

You could control the LCD from pure HDL instead but you'll have to handle the communication protocol yourself, probably using a state machine.
Altera_Forum
Honored Contributor I
57 Views

Thanks. Since I'm focusing on the arithmetic block part, and the text lcd is just for display, I guess it's better for me to do the usual way like you mentioned. But how... is the CPU you mentioned available as a Megafunction to be instantiated? 

Why isn't there any instruction which tells how to do this?
Altera_Forum
Honored Contributor I
57 Views

You can use the Sopc builder tool to create a Nios II CPU with a LCD controller. 

There are some tutorials available on the Altera web site about Nios systems design.
Altera_Forum
Honored Contributor I
57 Views

Hello, 

 

I'm posting my working Verilog state machine for driving the Character LCD. Sorry there are not many comments. This module requires a 5MHz clock for correct LCD timing. The module initializes the LCD according to the some constants that you can modify as you wish. 

 

Asserting the write input will start an LCD write cycle, which writes the a character on the text bus to the current cursor position. Change the cursor position by asserting the write and addr inputs together, with the new cursor position on the text bus. 

 

Thomas 

 

module LCD_driver_char (input clk, input wire addr, input wire text, input wire write, output busy, output reg LCD_RS = 0, output reg LCD_RW = 0, output reg LCD_E = 0, inout LCD_data); assign LCD_data = LCD_RW ? 8'bzzzzzzzz : data_reg; assign busy = ~|state || ~state || state; reg state; reg countclk; reg data_reg; reg text_hold; reg addr_hold; initial begin state <= 0; countclk <= 0; data_reg <= 0; text_hold <= 0; addr_hold <= 0; end always @ (posedge clk) begin if (write) begin state <= 1'b1; text_hold <= text; addr_hold <= addr; end if (state == 2'b00) begin if (countclk == 200000) state <= 6'b010000; else countclk <= countclk + 1'b1; end else if (state == 2'b01) begin if (~state) begin state <= 2'b10; countclk <= 20'h00000; LCD_RW <= 0; LCD_RS <= 0; if (state == 2'b00) begin data_reg <= 8'b00111000; // Function Set state <= 2'b01; end else if (state == 2'b01) begin data_reg <= 8'b00001110; // Display Config state <= 2'b10; end else if (state == 2'b10) begin data_reg <= 8'b00000001; // Display Clear state <= 2'b11; end else if (state == 2'b11) begin data_reg <= 8'b00000110; // Memory Mode state <= 2'b10; end end else if (~write) begin if (state) begin state <= 2'b10; state <= 1'b0; countclk <= 20'h00000; LCD_RW <= 0; LCD_RS <= ~addr_hold; data_reg <= addr_hold ? (text_hold ? 8'b11000000 : 8'b10000000) + text_hold : text_hold; end end end else if (state == 2'b10) begin if (~state) begin if (countclk == 4) begin LCD_E <= 1; countclk <= countclk + 1'b1; end else if (countclk == 16) begin LCD_E <= 0; countclk <= countclk + 1'b1; end else if (countclk == 50) begin state <= 1; countclk <= 0; LCD_RW <= 1; LCD_RS <= 0; end else begin countclk <= countclk + 1'b1; end end else begin if (countclk == 4) begin LCD_E <= 1; countclk <= countclk + 1'b1; end else if (countclk == 16) begin LCD_E <= 0; if (LCD_data == 0) begin state <= 2'b11; state <= 0; end countclk <= countclk + 1'b1; end else if (countclk == 50) begin countclk <= 0; end else begin countclk <= countclk + 1'b1; end end end else if (state == 2'b11) begin if (countclk == 50) state <= 2'b01; else countclk <= countclk + 1'b1; end end endmodule
Altera_Forum
Honored Contributor I
57 Views

Hello, 

 

I'm very new to verilog. Do you have sample top level module for the driver(LCD_driver_char) above to start with?
Reply