artur 0 2 сентября, 2016 Опубликовано 2 сентября, 2016 · Жалоба Доброе время суток, помогите разобраться почему описаная схема по управлению лцд-дисплеем отказывается работать в железе... Компелятор не ругаеться, в симуляторе тоже все хорошо выглядит. Я с начала думал что паузы между командами слишком маленькие, увеличил, всеравно не работает, но не так чтобы совсем не работает, не пишит текст. Инициализацию принемает, а текст не пишит ну и сам Код: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity lcd_v5 is port ( clk : in std_logic; -- System clk -- daten_bereit : in std_logic; -- data_input : in std_logic_vector(7 downto 0); busy : out std_logic := '1'; -- busy Flag rs : out std_logic := '0'; -- data or instruction, instruction = '0', data = '1' rw : out std_logic := '0'; -- read or write, read = '1', write = '0' enable_lcd : out std_logic := '0'; -- enable for read of write data : out std_logic_vector(7 downto 0) := (others => '0') -- daten ); end entity; architecture beh of lcd_v5 is type zustaende is (begining, waitx, ini_data_send, lcd_enable, lcd_desable, ini_loop, ready); signal zustand : zustaende := begining; type mem_data is array(0 to 11) of std_logic_vector(7 downto 0); constant daten : mem_data := ( x"30", -- data_reset(0) "0011 0000" x"30", -- data_reset(1) "0011 0000" x"30", -- data_reset(2) "0011 0000" x"3c", -- data_ini_1(3) "0011 1100" x"0f", -- data_ini_2(4) "0000 1111" x"07", -- data_ini_3(5) "0000 0111" x"01", -- data_ini_4(6) "0000 0001" x"59", -- Y(7) x"65", -- e(8) x"61", -- a(9) x"21", -- !(10) x"00" -- (11) ); type delay_type is array(0 to 6) of std_logic_vector(23 downto 0); constant delay : delay_type := ( x"4c4b40", -- 100 ms(0) x"033450", -- 4.2ms(1) x"0013ba", -- 101us(2) x"0009c4", -- delay_50us(3) x"000032", -- delay_1us(4) x"2625a0", -- delay_50ms(5) x"030d40" -- delay_4ms(6) ); signal addr_delay : integer range 0 to 6 := 0; signal addr_delay_i : integer range 0 to 6 := 0; signal addr_data : integer range 0 to 11 := 0; signal counter : std_logic_vector(23 downto 0) := (others => '0'); signal cnt_en : std_logic := '0'; signal cnt_fert : boolean := false; signal initialisierung : boolean := false; signal pause_halten : boolean := true; signal daten_gesendet : std_logic_vector(1 downto 0) := "00"; signal versions_nr : boolean := false; signal load : std_logic := '0'; signal data_out : std_logic_vector(7 downto 0) := (others => '0'); begin process(clk) variable cnt_intern : integer range -2 to 5000000 := 2; begin if rising_edge(clk) then if cnt_en = '1' then if load = '1' then cnt_intern := to_integer(unsigned(counter)); else cnt_intern := cnt_intern - 1; cnt_fert <= false; end if; if cnt_intern = 0 then cnt_fert <= true; end if; end if; end if; end process; -- automat -- process(clk) variable durchlauf : integer range 0 to 12 := 0; begin if (rising_edge(clk)) then case zustand is when begining => counter <= delay(addr_delay); cnt_en <= '1'; load <= '1'; rw <= '0'; busy <= '1'; zustand <= waitx; if versions_nr = true then rs <= '1'; else rs <= '0'; end if; when waitx => load <= '0'; if cnt_fert = true then if initialisierung = false then case daten_gesendet is when "01" => zustand <= lcd_enable; cnt_en <= '0'; when "10" => cnt_en <= '0'; zustand <= lcd_desable; when others => data_out <= (others => '0'); if pause_halten = true then enable_lcd <= '0'; cnt_en <= '0'; pause_halten <= false; zustand <= ini_data_send; else cnt_en <= '0'; enable_lcd <= '0'; addr_delay <= addr_delay_i; zustand <= ini_loop; durchlauf := durchlauf + 1; end if; end case; else cnt_en <= '0'; zustand <= ready; durchlauf := 0; end if; else zustand <= waitx; end if; when ini_data_send => data_out <= daten(addr_data); addr_delay <= 4; daten_gesendet <= "01"; zustand <= begining; when lcd_enable => addr_delay <= 4; enable_lcd <= '1'; zustand <= begining; daten_gesendet <= "10"; when lcd_desable => enable_lcd <= '0'; zustand <= begining; daten_gesendet <= "00"; when ini_loop => data_out <= (others => '0'); if durchlauf > 2 then addr_data <= addr_data + 1; addr_delay_i <= 3; addr_delay <= 3; pause_halten <= true; zustand <= begining; if durchlauf = 7 then versions_nr <= true; addr_data <= addr_data + 1; addr_delay <= 5; addr_delay_i <= 5; pause_halten <= true; zustand <= begining; end if; else addr_delay <= addr_delay + 1; addr_delay_i <= addr_delay_i + 1; addr_data <= addr_data + 1; pause_halten <= true; zustand <= begining; end if; if durchlauf >= 11 then durchlauf := 0; addr_data <= addr_data + 1; addr_delay <= 6; initialisierung <= true; zustand <= begining; end if; when ready => zustand <= ready; end case; end if; end process; data <= data_out; end beh; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_su 1 3 сентября, 2016 Опубликовано 3 сентября, 2016 · Жалоба А какой LCD? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Александр77 1 3 сентября, 2016 Опубликовано 3 сентября, 2016 · Жалоба Вот что сильно путает, так это вложенность Ifов друг в друга при проверке одной и той же переменной ..... if durchlauf > 2 then addr_data <= addr_data + 1; addr_delay_i <= 3; addr_delay <= 3; pause_halten <= true; zustand <= begining; if durchlauf = 7 then ..... Получается железу надо проверить что durchlauf больше 2, а в каких то случаях при этом еще и равно 7. На мой взгляд, лучше разбить проверку на две части 1) значение больше 2, но меньше 7 2) значение равно 7. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 3 сентября, 2016 Опубликовано 3 сентября, 2016 · Жалоба Доброе время суток, помогите разобраться почему описаная схема по управлению лцд-дисплеем отказывается работать в железе... Компелятор не ругаеться, в симуляторе тоже все хорошо выглядит. У Вас очень сложный и неправильный путь для написания кода. Могу рассказать как надо... По скайпу... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artur 0 4 сентября, 2016 Опубликовано 4 сентября, 2016 · Жалоба У Вас очень сложный и неправильный путь для написания кода. Могу рассказать как надо... По скайпу... очень хорошая идея, давайте, напишите когда вам позвонить А какой LCD? 1602a-1 v1.3 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 4 сентября, 2016 Опубликовано 4 сентября, 2016 · Жалоба очень хорошая идея, давайте, напишите когда вам позвонить Да хоть завтра, после 11-ти... Как увидите мою машину в сети, так и звоните... а сейчас можете прислать запрос на включение в адресную книгу... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artur 0 4 сентября, 2016 Опубликовано 4 сентября, 2016 · Жалоба Вот что сильно путает, так это вложенность Ifов друг в друга при проверке одной и той же переменной ..... if durchlauf > 2 then addr_data <= addr_data + 1; addr_delay_i <= 3; addr_delay <= 3; pause_halten <= true; zustand <= begining; if durchlauf = 7 then ..... Получается железу надо проверить что durchlauf больше 2, а в каких то случаях при этом еще и равно 7. На мой взгляд, лучше разбить проверку на две части 1) значение больше 2, но меньше 7 2) значение равно 7. Дело в том что только при "durchlauf = 7" должна произойти задержка в 50мс (т.е. когда цепь "durchlauf = 7" это значит что инитиализазия закончина и начинается текст который должен выдаваться при каждом включении), потом должна опять выполняться цепь "durchlauf > 2" пока не достигнет "durchlauf >= 11". Инитиализацию он понимает, а вот текст не пишит Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 5 сентября, 2016 Опубликовано 5 сентября, 2016 · Жалоба может пример поможет, также смотрим state flow -- 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; -- -- Prints "123456789" on a HD44780 compatible 8-bit interface character LCD -- module using the lcd_controller.vhd component. -- -------------------------------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY lcd_example IS PORT( clk : IN STD_LOGIC; --system clock 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 => '1', 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(char < 10) THEN char := char + 1; END IF; CASE char IS WHEN 1 => lcd_bus <= "1000110001"; WHEN 2 => lcd_bus <= "1000110010"; WHEN 3 => lcd_bus <= "1000110011"; WHEN 4 => lcd_bus <= "1000110100"; WHEN 5 => lcd_bus <= "1000110101"; WHEN 6 => lcd_bus <= "1000110110"; WHEN 7 => lcd_bus <= "1000110111"; WHEN 8 => lcd_bus <= "1000111000"; WHEN 9 => lcd_bus <= "1000111001"; WHEN OTHERS => lcd_enable <= '0'; END CASE; ELSE lcd_enable <= '0'; END IF; END IF; END PROCESS; END behavior; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artur 0 6 сентября, 2016 Опубликовано 6 сентября, 2016 · Жалоба может пример поможет, также смотрим state flow -- 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; -- -- Prints "123456789" on a HD44780 compatible 8-bit interface character LCD -- module using the lcd_controller.vhd component. -- -------------------------------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY lcd_example IS PORT( clk : IN STD_LOGIC; --system clock 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 => '1', 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(char < 10) THEN char := char + 1; END IF; CASE char IS WHEN 1 => lcd_bus <= "1000110001"; WHEN 2 => lcd_bus <= "1000110010"; WHEN 3 => lcd_bus <= "1000110011"; WHEN 4 => lcd_bus <= "1000110100"; WHEN 5 => lcd_bus <= "1000110101"; WHEN 6 => lcd_bus <= "1000110110"; WHEN 7 => lcd_bus <= "1000110111"; WHEN 8 => lcd_bus <= "1000111000"; WHEN 9 => lcd_bus <= "1000111001"; WHEN OTHERS => lcd_enable <= '0'; END CASE; ELSE lcd_enable <= '0'; END IF; END IF; END PROCESS; END behavior; спасибо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
artur 0 11 сентября, 2016 Опубликовано 11 сентября, 2016 · Жалоба может пример поможет, также смотрим state flow -- 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; -- -- Prints "123456789" on a HD44780 compatible 8-bit interface character LCD -- module using the lcd_controller.vhd component. -- -------------------------------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY lcd_example IS PORT( clk : IN STD_LOGIC; --system clock 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 => '1', 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(char < 10) THEN char := char + 1; END IF; CASE char IS WHEN 1 => lcd_bus <= "1000110001"; WHEN 2 => lcd_bus <= "1000110010"; WHEN 3 => lcd_bus <= "1000110011"; WHEN 4 => lcd_bus <= "1000110100"; WHEN 5 => lcd_bus <= "1000110101"; WHEN 6 => lcd_bus <= "1000110110"; WHEN 7 => lcd_bus <= "1000110111"; WHEN 8 => lcd_bus <= "1000111000"; WHEN 9 => lcd_bus <= "1000111001"; WHEN OTHERS => lcd_enable <= '0'; END CASE; ELSE lcd_enable <= '0'; END IF; END IF; END PROCESS; END behavior; Ошибку нашел :-), проблема была в неправильной комбинации при инициализации. Оказывается что уже давно все работало, из-за такой мелочи сидел почти месяц... Хотел выставить видео, но оно оказалось слишком большое (43 мб). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 11 сентября, 2016 Опубликовано 11 сентября, 2016 · Жалоба Ошибку нашел :-), проблема была в неправильной комбинации при инициализации. Оказывается что уже давно все работало, из-за такой мелочи сидел почти месяц... Хотел выставить видео, но оно оказалось слишком большое (43 мб). Даже добавлю. То что "Оказывается.." совсем не удивляет, ибо способ разработки совсем не лучший. А удивляет то, что я предлагаю показать как работать без ошибок, а Вы отказываетесь... Но это уже Ваше дело... Посмотрите хотя бы у меня в "Кратком Курсе" раздел "Дополнительно об автоматах"... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться