Kingdom_Walker
Newbie level 1
- Joined
- Nov 28, 2012
- Messages
- 1
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,287
Hi, I am a second year electrical engineer student doing a project on multimeter. I have been trying to get the LCD display to display the mode the multimeter is in. I found a code online called LCD_Controller to initialize the LCD display. However, whenever I reset, the display does not come back up again. Can you please take a look at my codes and tell me what's wrong? Thank you!
Code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY lcd_example IS
PORT(
clk : IN STD_LOGIC; --system clock
mode : IN STD_LOGIC_VECTOR(1 DOWNTO 0); -- Select Between Voltmeter,Ammeter,Ohometa and Beta
reset : IN STD_LOGIC; --Active Low
rw, rs, e : OUT STD_LOGIC; --read/write, setup/data, and enable for lcd
lcd_data : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --data signals for lcd
END lcd_example;
ARCHITECTURE behavior OF lcd_example IS
SIGNAL lcd_enable : STD_LOGIC;
SIGNAL lcd_bus : STD_LOGIC_VECTOR(9 DOWNTO 0);
SIGNAL lcd_busy : STD_LOGIC;
COMPONENT lcd_controller IS
PORT(
clk : IN STD_LOGIC; --system clock
reset_n : IN STD_LOGIC; --active low reinitializes lcd
lcd_enable : IN STD_LOGIC; --latches data into lcd controller
lcd_bus : IN STD_LOGIC_VECTOR(9 DOWNTO 0); --data and control signals
busy : OUT STD_LOGIC; --lcd controller busy/idle feedback
rw, rs, e : OUT STD_LOGIC; --read/write, setup/data, and enable for lcd
lcd_data : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --data signals for lcd
END COMPONENT;
BEGIN
--instantiate the lcd controller
dut: lcd_controller
PORT MAP(clk => clk, reset_n => reset, lcd_enable => lcd_enable, lcd_bus => lcd_bus,
busy => lcd_busy, rw => rw, rs => rs, e => e, lcd_data => lcd_data);
PROCESS(clk)
VARIABLE char : INTEGER RANGE 0 TO 10 := 0;
BEGIN
if(clk'EVENT AND clk = '1') THEN
IF(lcd_busy = '0' AND lcd_enable = '0') THEN
lcd_enable <= '1';
IF(mode="00")THEN --Voltmeter
IF(char < 10) THEN
char := char + 1;
END IF;
CASE char IS
WHEN 1 => lcd_bus <= "1001010110"; --V
WHEN 2 => lcd_bus <= "1001101111"; --o
WHEN 3 => lcd_bus <= "1001101100"; --l
WHEN 4 => lcd_bus <= "1001110100"; --t
WHEN 5 => lcd_bus <= "1001101101"; --m
WHEN 6 => lcd_bus <= "1001100101"; --e
WHEN 7 => lcd_bus <= "1001110100"; --t
WHEN 8 => lcd_bus <= "1001100101"; --e
WHEN 9 => lcd_bus <= "1001110010"; --r
WHEN OTHERS => lcd_enable <= '0';
END CASE;
ELSIF(mode="01") THEN --Ammeter
IF(char < 10) THEN
char := char + 1;
END IF;
CASE char IS
WHEN 1 => lcd_bus <= "1001000001"; --A
WHEN 2 => lcd_bus <= "1001101101"; --m
WHEN 3 => lcd_bus <= "1001101101"; --m
WHEN 4 => lcd_bus <= "1001100101"; --e
WHEN 5 => lcd_bus <= "1001110100"; --t
WHEN 6 => lcd_bus <= "1001100101"; --e
WHEN 7 => lcd_bus <= "1001110010"; --r
WHEN OTHERS => lcd_enable <= '0';
END CASE;
ELSIF(mode="10") THEN --Ohmmeter
IF(char < 10) THEN
char := char + 1;
END IF;
CASE char IS
WHEN 1 => lcd_bus <= "1001001111"; --O
WHEN 2 => lcd_bus <= "1001101000"; --h
WHEN 3 => lcd_bus <= "1001101101"; --m
WHEN 4 => lcd_bus <= "1001101101"; --m
WHEN 5 => lcd_bus <= "1001100101"; --e
WHEN 6 => lcd_bus <= "1001110100"; --t
WHEN 7 => lcd_bus <= "1001100101"; --e
WHEN 8 => lcd_bus <= "1001110010"; --r
WHEN OTHERS => lcd_enable <= '0';
END CASE;
ELSIF(mode="11") THEN --Beta"meter
IF(char < 10) THEN
char := char + 1;
END IF;
CASE char IS
WHEN 1 => lcd_bus <= "1001000001"; --B
WHEN 2 => lcd_bus <= "1001100101"; --e
WHEN 3 => lcd_bus <= "1001110100"; --t
WHEN 4 => lcd_bus <= "1001100001"; --a
WHEN 5 => lcd_bus <= "1001101101"; --m
WHEN 6 => lcd_bus <= "1001100101"; --e
WHEN 7 => lcd_bus <= "1001110100"; --t
WHEN 8 => lcd_bus <= "1001100101"; --e
WHEN 9 => lcd_bus <= "1001110010"; --r
WHEN OTHERS => lcd_enable <= '0';
END CASE;
END IF;
ELSE
lcd_enable <= '0';
END IF;
END IF;
END PROCESS;
END behavior;
------------------------------------------
--------------------------------------------------------------------------------
--
-- FileName: lcd_controller.vhd
-- Dependencies: none
-- Design Software: Quartus II 32-bit Version 11.1 Build 173 SJ Full Version
--
-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY
-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY
-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL
-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF
-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS.
--
-- Version History
-- Version 1.0 6/2/2006 Scott Larson
-- Initial Public Release
-- Version 2.0 6/13/2012 Scott Larson
--
-- CLOCK FREQUENCY: to change system clock frequency, change Line 65gfdg
--
-- LCD INITIALIZATION SETTINGS: to change, comment/uncomment lines:
--
-- Function Set
-- 2-line mode, display on Line 93 lcd_data <= "00111100";
-- 1-line mode, display on Line 94 lcd_data <= "00110100";
-- 1-line mode, display off Line 95 lcd_data <= "00110000";
-- 2-line mode, display off Line 96 lcd_data <= "00111000";
-- Display ON/OFF
-- display on, cursor off, blink off Line 104 lcd_data <= "00001100";
-- display on, cursor off, blink on Line 105 lcd_data <= "00001101";
-- display on, cursor on, blink off Line 106 lcd_data <= "00001110";
-- display on, cursor on, blink on Line 107 lcd_data <= "00001111";
-- display off, cursor off, blink off Line 108 lcd_data <= "00001000";
-- display off, cursor off, blink on Line 109 lcd_data <= "00001001";
-- display off, cursor on, blink off Line 110 lcd_data <= "00001010";
-- display off, cursor on, blink on Line 111 lcd_data <= "00001011";
-- Entry Mode Set
-- increment mode, entire shift off Line 127 lcd_data <= "00000110";
-- increment mode, entire shift on Line 128 lcd_data <= "00000111";
-- decrement mode, entire shift off Line 129 lcd_data <= "00000100";
-- decrement mode, entire shift on Line 130 lcd_data <= "00000101";
--
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY lcd_controller IS
PORT(
clk : IN STD_LOGIC; --system clock
reset_n : IN STD_LOGIC; --active low reinitializes lcd
lcd_enable : IN STD_LOGIC; --latches data into lcd controller
lcd_bus : IN STD_LOGIC_VECTOR(9 DOWNTO 0); --data and control signals
busy : OUT STD_LOGIC := '1'; --lcd controller busy/idle feedback
rw, rs, e : OUT STD_LOGIC; --read/write, setup/data, and enable for lcd
lcd_data : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --data signals for lcd
END lcd_controller;
ARCHITECTURE controller OF lcd_controller IS
TYPE CONTROL IS(power_up, initialize, ready, send);
SIGNAL state : CONTROL;
CONSTANT freq : INTEGER := 50; --system clock frequency in MHz
BEGIN
PROCESS(clk)
VARIABLE clk_count : INTEGER := 0; --event counter for timing
BEGIN
IF(clk'EVENT and clk = '1') THEN
CASE state IS
--wait 50 ms to ensure Vdd has risen and required LCD wait is met
WHEN power_up =>
busy <= '1';
IF(clk_count < (50000 * freq)) THEN --wait 50 ms
clk_count := clk_count + 1;
state <= power_up;
ELSE --power-up complete
clk_count := 0;
rs <= '0';
rw <= '0';
lcd_data <= "00110000";
state <= initialize;
END IF;
--cycle through initialization sequence
WHEN initialize =>
busy <= '1';
clk_count := clk_count + 1;
IF(clk_count < (10 * freq)) THEN --function set
--lcd_data <= "00111100"; --2-line mode, display on
lcd_data <= "00110100"; --1-line mode, display on
--lcd_data <= "00110000"; --1-line mdoe, display off
--lcd_data <= "00111000"; --2-line mode, display off
e <= '1';
state <= initialize;
ELSIF(clk_count < (60 * freq)) THEN --wait 50 us
lcd_data <= "00000000";
e <= '0';
state <= initialize;
ELSIF(clk_count < (70 * freq)) THEN --display on/off control
lcd_data <= "00001100"; --display on, cursor off, blink off
--lcd_data <= "00001101"; --display on, cursor off, blink on
--lcd_data <= "00001110"; --display on, cursor on, blink off
--lcd_data <= "00001111"; --display on, cursor on, blink on
--lcd_data <= "00001000"; --display off, cursor off, blink off
--lcd_data <= "00001001"; --display off, cursor off, blink on
--lcd_data <= "00001010"; --display off, cursor on, blink off
--lcd_data <= "00001011"; --display off, cursor on, blink on
e <= '1';
state <= initialize;
ELSIF(clk_count < (120 * freq)) THEN --wait 50 us
lcd_data <= "00000000";
e <= '0';
state <= initialize;
ELSIF(clk_count < (130 * freq)) THEN --display clear
lcd_data <= "00000001";
e <= '1';
state <= initialize;
ELSIF(clk_count < (2130 * freq)) THEN --wait 2 ms
lcd_data <= "00000000";
e <= '0';
state <= initialize;
ELSIF(clk_count < (2140 * freq)) THEN --entry mode set
lcd_data <= "00000110"; --increment mode, entire shift off
--lcd_data <= "00000111"; --increment mode, entire shift on
--lcd_data <= "00000100"; --decrement mode, entire shift off
--lcd_data <= "00000101"; --decrement mode, entire shift on
e <= '1';
state <= initialize;
ELSIF(clk_count < (2200 * freq)) THEN --wait 60 us
lcd_data <= "00000000";
e <= '0';
state <= initialize;
ELSE --initialization complete
clk_count := 0;
busy <= '0';
state <= ready;
END IF;
--wait for the enable signal and then latch in the instruction
WHEN ready =>
IF(lcd_enable = '1') THEN
busy <= '1';
rs <= lcd_bus(9);
rw <= lcd_bus(8);
lcd_data <= lcd_bus(7 DOWNTO 0);
clk_count := 0;
state <= send;
ELSE
busy <= '0';
rs <= '0';
rw <= '0';
lcd_data <= "00000000";
clk_count := 0;
state <= ready;
END IF;
--send instruction to lcd
WHEN send =>
busy <= '1';
IF(clk_count < (50 * freq)) THEN --do not exit for 50us
busy <= '1';
IF(clk_count < freq) THEN --negative enable
e <= '0';
ELSIF(clk_count < (14 * freq)) THEN --positive enable half-cycle
e <= '1';
ELSIF(clk_count < (27 * freq)) THEN --negative enable half-cycle
e <= '0';
END IF;
clk_count := clk_count + 1;
state <= send;
ELSE
clk_count := 0;
state <= ready;
END IF;
END CASE;
--reset
IF(reset_n = '0') THEN
state <= power_up;
END IF;
END IF;
END PROCESS;
END controller;
Last edited by a moderator: