Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Spartan 3E LCD Code Display problems.

Status
Not open for further replies.

come512l

Newbie level 6
Joined
Sep 10, 2011
Messages
14
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Paris
Activity points
1,365
Hi, I'm trying to display a word on the LCD (Spartan 3E VHDL) depends on the condition inputted by the user through switch. Sample if I press 011 on the switch, I will display the word BLINK, can anyone guide me on whats wrong with the code below.


Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity lcd is
			port(
			clk, reset : in bit;
			selectchar : std_logic_vector(2 downto 0);
			SF_D : out bit_vector(3 downto 0);
			LCD_E, LCD_RS, LCD_RW, SF_CE0 : out bit;
			LED : out bit_vector(7 downto 0) );
end lcd;


architecture behavior of lcd is

		type tx_sequence is (high_setup, high_hold, oneus, low_setup, low_hold, fortyus, done);
		signal tx_state : tx_sequence := done;
		signal tx_byte : bit_vector(7 downto 0);
		signal tx_init : bit := '0';
		type init_sequence is (idle, fifteenms, one, two, three, four, five, six, seven, eight, done);
		signal init_state : init_sequence := idle;
		signal init_init, init_done : bit := '0';
		signal i : integer range 0 to 750000 := 0;
		signal i2 : integer range 0 to 2000 := 0;
		signal i3 : integer range 0 to 82000 := 0;
		signal SF_D0, SF_D1 : bit_vector(3 downto 0);
		signal LCD_E0, LCD_E1 : bit;
		signal mux : bit;
		type display_state is (init, function_set, entry_set, set_display, clr_display, pause, set_addr, char_f, char_p, char_g,
		char_a,char_s, done);
		signal cur_state : display_state := init;


begin


		LED <= tx_byte; --for diagnostic purposes
		SF_CE0 <= '1'; --disable intel strataflash
		LCD_RW <= '0'; --write only
		--The following "with" statements simplify the process of adding and removing states.
--when to transmit a command/data and when not to
		
		if (selectchar = "001") then

		with cur_state select
		tx_init <= '0' when init | pause | done,
		'1' when others;
		--control the bus
		with cur_state select
		mux <= '1' when init,
		'0' when others;
		--control the initialization sequence
		with cur_state select
		init_init <= '1' when init,
		'0' when others;
		--register select
		with cur_state select
		LCD_RS <= '0' when function_set|entry_set|set_display|clr_display|set_addr,
		'1' when others;
		--what byte to transmit to lcd
		--refer to datasheet for an explanation of these values
		with cur_state select
		tx_byte <= "00101000" when function_set,
		"00000110" when entry_set,
		"00001100" when set_display,
		"00000001" when clr_display,
		"10000000" when set_addr,
		"01001111" when char_f,    ---O
		"01001110" when char_p,    ---N
		"00000000" when char_g,    ---
		"00000000" when char_a,    ---
		"00000000" when char_s,    ---
		"00000000" when others;
		
		end if;
		
		if (selectchar = "010") then
		

		with cur_state select
		tx_init <= '0' when init | pause | done,
		'1' when others;
		--control the bus
		with cur_state select
		mux <= '1' when init,
		'0' when others;
		--control the initialization sequence
		with cur_state select
		init_init <= '1' when init,
		'0' when others;
		--register select
		with cur_state select
		LCD_RS <= '0' when function_set|entry_set|set_display|clr_display|set_addr,
		'1' when others;
		--what byte to transmit to lcd
		--refer to datasheet for an explanation of these values
		with cur_state select
		tx_byte <= "00101000" when function_set,
		"00000110" when entry_set,
		"00001100" when set_display,
		"00000001" when clr_display,
		"10000000" when set_addr,
		"01000010" when char_f,    ---O
		"01001100" when char_p,    ---F
		"01001001" when char_g,    ---F
		"00000000" when char_a,    ---
		"00000000" when char_s,    ---
		"00000000" when others;	
		
		end if;
		
		if (selectchar = "011") then
		

		with cur_state select
		tx_init <= '0' when init | pause | done,
		'1' when others;
		--control the bus
		with cur_state select
		mux <= '1' when init,
		'0' when others;
		--control the initialization sequence
		with cur_state select
		init_init <= '1' when init,
		'0' when others;
		--register select
		with cur_state select
		LCD_RS <= '0' when function_set|entry_set|set_display|clr_display|set_addr,
		'1' when others;
		--what byte to transmit to lcd
		--refer to datasheet for an explanation of these values
		with cur_state select
		tx_byte <= "00101000" when function_set,
		"00000110" when entry_set,
		"00001100" when set_display,
		"00000001" when clr_display,
		"10000000" when set_addr,
		"01000010" when char_f,    ---B
		"01001100" when char_p,    ---L
		"01001001" when char_g,    ---I
		"01001110" when char_a,    ---N
		"01001011" when char_s,    ---K
		"00000000" when others;	
		
		end if;
		
		if (selectchar = "011") then
		

		with cur_state select
		tx_init <= '0' when init | pause | done,
		'1' when others;
		--control the bus
		with cur_state select
		mux <= '1' when init,
		'0' when others;
		--control the initialization sequence
		with cur_state select
		init_init <= '1' when init,
		'0' when others;
		--register select
		with cur_state select
		LCD_RS <= '0' when function_set|entry_set|set_display|clr_display|set_addr,
		'1' when others;
		--what byte to transmit to lcd
		--refer to datasheet for an explanation of these values
		with cur_state select
		tx_byte <= "00101000" when function_set,
		"00000110" when entry_set,
		"00001100" when set_display,
		"00000001" when clr_display,
		"10000000" when set_addr,
		"01000001" when char_f,    ---A
		"01001100" when char_p,    ---L
		"01010100" when char_g,    ---T
		"01000101" when char_a,    ---E
		"01010010" when char_s,    ---R
		"00000000" when others;	
		
		end if;
		
		if (selectchar = "100") then
		

		with cur_state select
		tx_init <= '0' when init | pause | done,
		'1' when others;
		--control the bus
		with cur_state select
		mux <= '1' when init,
		'0' when others;
		--control the initialization sequence
		with cur_state select
		init_init <= '1' when init,
		'0' when others;
		--register select
		with cur_state select
		LCD_RS <= '0' when function_set|entry_set|set_display|clr_display|set_addr,
		'1' when others;
		--what byte to transmit to lcd
		--refer to datasheet for an explanation of these values
		with cur_state select
		tx_byte <= "00101000" when function_set,
		"00000110" when entry_set,
		"00001100" when set_display,
		"00000001" when clr_display,
		"10000000" when set_addr,
		"01000010" when char_f,    ---B
		"01001100" when char_p,    ---L
		"01001001" when char_g,    ---I
		"01001110" when char_a,    ---N
		"01001011" when char_s,    ---K
		"00000000" when others;	
		
		end if;


--main state machine


		display: process(clk, reset)
		
		begin
		
				if(reset='1') then
				cur_state <= function_set;
				elsif(clk='1' and clk'event) then
				case cur_state is
				--refer to intialize state machine below
				when init =>
				if(init_done = '1') then
				cur_state <= function_set;
				else
				cur_state <= init;
				end if;
				
--every other state but pause uses the transmit state machine


				when function_set =>
									if(i2 = 2000) then
									cur_state <= entry_set;
									else
									cur_state <= function_set;
									end if;
				when entry_set =>
									if(i2 = 2000) then
									cur_state <= set_display;
									else
									cur_state <= entry_set;
									end if;
				when set_display =>
									if(i2 = 2000) then
									cur_state <= clr_display;
									else
									cur_state <= set_display;
									end if;
				when clr_display =>
									i3 <= 0;
									if(i2 = 2000) then
									cur_state <= pause;
									else
									cur_state <= clr_display;
									end if;
				when pause =>
									if(i3 = 82000) then
									cur_state <= set_addr;
									i3 <= 0;
									else
									cur_state <= pause;
									i3 <= i3 + 1;
									end if;
				when set_addr =>
									if(i2 = 2000) then
									cur_state <= char_f;
									else
									cur_state <= set_addr;
									end if;
				when char_f =>
									if(i2 = 2000) then
									cur_state <= char_p;
									else
									cur_state <= char_f;
									end if;
				when char_p =>
									if(i2 = 2000) then
									cur_state <= char_g;
									else
									cur_state <= char_p;
									end if;
				when char_g =>
									if(i2 = 2000) then
									cur_state <= char_a;
									else
									cur_state <= char_g;
									end if;
				when char_a =>
									if(i2 = 2000) then
									cur_state <= char_s;
									else
									cur_state <= char_a;
									end if;
				when char_s =>
									if(i2 = 2000) then
									cur_state <= done;
									else
									cur_state <= char_s;
									end if;
				when done =>
								cur_state <= done;
				
				end case;
				end if;
				end process display;
				with mux select
				SF_D <= SF_D0 when '0', --transmit
				SF_D1 when others; --initialize
				with mux select
				LCD_E <= LCD_E0 when '0', --transmit
				LCD_E1 when others; --initialize
				--specified by datasheet
				transmit : process(clk, reset, tx_init)
				begin
				if(reset='1') then
				tx_state <= done;
				elsif(clk='1' and clk'event) then
				case tx_state is
				when high_setup => --40ns
				LCD_E0 <= '0';
				SF_D0 <= tx_byte(7 downto 4);
				if(i2 = 2) then
				tx_state <= high_hold;
				i2 <= 0;
				else
				tx_state <= high_setup;
				i2 <= i2 + 1;
				end if;
				when high_hold => --230ns
				LCD_E0 <= '1';
				SF_D0 <= tx_byte(7 downto 4);
				if(i2 = 12) then
				tx_state <= oneus;
				i2 <= 0;
				else
				tx_state <= high_hold;
				i2 <= i2 + 1;
				end if;
				when oneus =>
				LCD_E0 <= '0';
				if(i2 = 50) then
				tx_state <= low_setup;
				i2 <= 0;
				else
				tx_state <= oneus;
				i2 <= i2 + 1;
				end if;
				when low_setup =>
				LCD_E0 <= '0';
				SF_D0 <= tx_byte(3 downto 0);
				if(i2 = 2) then
				tx_state <= low_hold;
				i2 <= 0;
				else
				tx_state <= low_setup;
				i2 <= i2 + 1;
				end if;
				when low_hold =>
				LCD_E0 <= '1';
				SF_D0 <= tx_byte(3 downto 0);
				if(i2 = 12) then
				tx_state <= fortyus;
				i2 <= 0;
				else
				tx_state <= low_hold;
				i2 <= i2 + 1;
				end if;
				when fortyus =>
				LCD_E0 <= '0';
				if(i2 = 2000) then
				tx_state <= done;
				i2 <= 0;
				else
				tx_state <= fortyus;
				i2 <= i2 + 1;
				end if;
				when done =>
				LCD_E0 <= '0';
				if(tx_init = '1') then
				tx_state <= high_setup;
				i2 <= 0;
				else
				tx_state <= done;
				i2 <= 0;
				end if;
				end case;
				end if;
				end process transmit;
				--specified by datasheet
				power_on_initialize: process(clk, reset, init_init) --power on initialization sequence
				begin
				if(reset='1') then
				init_state <= idle;
				init_done <= '0';
				elsif(clk='1' and clk'event) then
				case init_state is
				when idle =>
				init_done <= '0';
				if(init_init = '1') then
				init_state <= fifteenms;
				i <= 0;
				else
				init_state <= idle;
				i <= i + 1;
				end if;
				when fifteenms =>
				init_done <= '0';
				if(i = 750000) then
				init_state <= one;
				i <= 0;
				else
				init_state <= fifteenms;
				i <= i + 1;
				end if;
				when one =>
				SF_D1 <= "0011";
				LCD_E1 <= '1';
				init_done <= '0';
				if(i = 11) then
				init_state<=two;
				i <= 0;
				else
				init_state<=one;
				i <= i + 1;
				end if;
				when two =>
				LCD_E1 <= '0';
				init_done <= '0';
				if(i = 205000) then
				init_state<=three;
				i <= 0;
				else
				init_state<=two;
				i <= i + 1;
				end if;
				when three =>
				SF_D1 <= "0011";
				LCD_E1 <= '1';
				init_done <= '0';
				if(i = 11) then
				init_state<=four;
				i <= 0;
				else
				init_state<=three;
				i <= i + 1;
				end if;
				when four =>
				LCD_E1 <= '0';
				init_done <= '0';
				if(i = 5000) then
				init_state<=five;
				i <= 0;
				else
				init_state<=four;
				i <= i + 1;
				end if;
				when five =>
				SF_D1 <= "0011";
				LCD_E1 <= '1';
				init_done <= '0';
				if(i = 11) then
				init_state<=six;
				i <= 0;
				else
				init_state<=five;
				i <= i + 1;
				end if;
				when six =>
				LCD_E1 <= '0';
				init_done <= '0';
				if(i = 2000) then
				init_state<=seven;
				i <= 0;
				else
				init_state<=six;
				i <= i + 1;
				end if;
				when seven =>
				SF_D1 <= "0010";
				LCD_E1 <= '1';
				init_done <= '0';
				if(i = 11) then
				init_state<=eight;
				i <= 0;
				else
				init_state<=seven;
				i <= i + 1;
				end if;
				when eight =>
				LCD_E1 <= '0';
				init_done <= '0';
				if(i = 2000) then
				init_state<=done;
				i <= 0;
				else
				init_state<=eight;
				i <= i + 1;
				end if;
				when done =>
				
				init_state <= done;
				init_done <= '1';
				
				end case;
				
				end if;
				
				end process power_on_initialize;
				
				end behavior;
 

hi,

You have to use delay for every instruction.refer the LCD datasheet
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top