----------------------------------------------------------------------------------
-- Company:
-- Engineer: Anastazja Sofińska
--
-- Create Date: 25.06.2025 07:51:35
-- Design Name:
-- Module Name: testownik - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
entity testownik is
PORT(
reset : in STD_LOGIC;
Clock100MHz : in STD_LOGIC;
LCD_RS : out STD_LOGIC;
LCD_E : out STD_LOGIC;
DATA_BUS : out STD_LOGIC_VECTOR (3 DOWNTO 0)
);
end testownik;
architecture Behavioral of testownik is
type state_type is (
IDLE, ENABLE1, ENABLE2, INIT1, INIT2, INIT3, INIT4, FUNC_SET, DISPLAY_ON, MODE_SET, WRITE_CHAR, RETURN_BACK, SEND_UPPER, SEND_LOWER, DISPLAY_OFF, DISPLAY_CLEAR, SET_CURSOR_LINE1
);
signal curr_state : state_type := INIT1;
signal next_state : state_type := INIT2;
signal lcd_data_buf : STD_LOGIC_VECTOR (7 DOWNTO 0) := (others => '0');
signal tick_2ms : STD_LOGIC := '0';
signal tick_cnt : integer range 0 to 250000 := 0;
signal char_idx : STD_LOGIC_VECTOR (4 downto 0) := (others => '0');
signal char_data : STD_LOGIC_VECTOR (7 DOWNTO 0);
signal char_reg : STD_LOGIC_VECTOR (7 DOWNTO 0) := "10000001";
shared variable line_flag : STD_LOGIC := '0';
signal rst_counter : STD_LOGIC_VECTOR (3 downto 0) := (others => '0');
signal is_ready : boolean := true;
begin
char_data <= char_reg;
-- pomocniczy zegar ~2.5 ms
process(Clock100MHz)
begin
if rising_edge(Clock100MHz) then
if reset = '1' then
tick_cnt <= 0;
tick_2ms <= '0';
else
tick_cnt <= tick_cnt + 1;
if tick_cnt = 250000 then
tick_cnt <= 0;
tick_2ms <= not tick_2ms;
end if;
end if;
end if;
end process;
-- FSM do obsługi LCD
process(tick_2ms, reset)
begin
if reset = '1' then
curr_state <= INIT1;
lcd_data_buf <= (others => '0');
next_state <= INIT2;
LCD_E <= '1';
LCD_RS <= '0';
line_flag := '0';
elsif rising_edge(tick_2ms) then
case curr_state is
when IDLE =>
if is_ready then
LCD_E <= '1';
curr_state <= next_state;
is_ready <= false;
else
is_ready <= true;
end if;
when ENABLE1 =>
LCD_E <= '0';
curr_state <= SEND_LOWER;
when ENABLE2 =>
LCD_E <= '0';
curr_state <= IDLE;
when INIT1 =>
LCD_RS <= '0';
lcd_data_buf <= "00000011";
rst_counter <= rst_counter + 1;
if rst_counter = "1001" then
next_state <= INIT2;
curr_state <= SEND_LOWER;
end if;
when INIT2 =>
LCD_RS <= '0';
lcd_data_buf <= "00000011";
rst_counter <= rst_counter + 1;
if rst_counter = "1011" then
next_state <= INIT3;
curr_state <= SEND_LOWER;
end if;
when INIT3 =>
LCD_RS <= '0';
lcd_data_buf <= "00000011";
rst_counter <= rst_counter + 1;
if rst_counter = "1100" then
next_state <= INIT4;
curr_state <= SEND_LOWER;
end if;
when INIT4 =>
LCD_RS <= '0';
lcd_data_buf <= "00000010";
next_state <= FUNC_SET;
curr_state <= SEND_LOWER;
when FUNC_SET =>
LCD_RS <= '0';
lcd_data_buf <= "00101000"; -- 4-bit, 2 linie
next_state <= DISPLAY_OFF;
curr_state <= SEND_UPPER;
when DISPLAY_OFF =>
LCD_RS <= '0';
lcd_data_buf <= "00001000";
next_state <= DISPLAY_CLEAR;
curr_state <= SEND_UPPER;
when DISPLAY_CLEAR =>
LCD_RS <= '0';
lcd_data_buf <= "00000001";
next_state <= DISPLAY_ON;
curr_state <= SEND_UPPER;
when DISPLAY_ON =>
LCD_RS <= '0';
lcd_data_buf <= "00001100";
next_state <= MODE_SET;
curr_state <= SEND_UPPER;
when MODE_SET =>
LCD_RS <= '0';
lcd_data_buf <= "00000110";
next_state <= SET_CURSOR_LINE1;
curr_state <= SEND_UPPER;
when SET_CURSOR_LINE1 =>
LCD_RS <= '0';
lcd_data_buf <= "10000000";
next_state <= WRITE_CHAR;
curr_state <= SEND_UPPER;
when WRITE_CHAR =>
if char_idx = "11011" then
curr_state <= IDLE;
next_state <= IDLE;
elsif char_idx = "01100" and line_flag = '0' then
LCD_RS <= '0';
lcd_data_buf <= "11000000";
line_flag := '1';
curr_state <= SEND_UPPER;
next_state <= WRITE_CHAR;
else
LCD_RS <= '1';
lcd_data_buf <= char_data;
char_idx <= char_idx + 1;
curr_state <= SEND_UPPER;
next_state <= WRITE_CHAR;
end if;
when RETURN_BACK =>
LCD_RS <= '0';
lcd_data_buf <= "10000000";
next_state <= WRITE_CHAR;
curr_state <= SEND_UPPER;
when SEND_UPPER =>
LCD_E <= '1';
DATA_BUS <= lcd_data_buf(7 downto 4);
curr_state <= ENABLE1;
when SEND_LOWER =>
LCD_E <= '1';
DATA_BUS <= lcd_data_buf(3 downto 0);
curr_state <= ENABLE2;
when others =>
curr_state <= next_state;
end case;
end if;
end process;
-- Przypisywanie znaków do LCD
process(tick_2ms, reset)
begin
if reset = '1' then
char_reg <= (others => '0');
elsif rising_edge(tick_2ms) then
if curr_state = WRITE_CHAR then
case char_idx is
-- Linia 1: "Ile to 2+2? "
when "00000" => char_reg <= "01001001"; -- I
when "00001" => char_reg <= "01101100"; -- l
when "00010" => char_reg <= "01100101"; -- e
when "00011" => char_reg <= "00100000"; --
when "00100" => char_reg <= "01110100"; -- t
when "00101" => char_reg <= "01101111"; -- o
when "00110" => char_reg <= "00100000"; --
when "00111" => char_reg <= "00110010"; -- 2
when "01000" => char_reg <= "00101011"; -- +
when "01001" => char_reg <= "00110010"; -- 2
when "01010" => char_reg <= "00111111"; -- ?
when "01011" => char_reg <= "00100000"; -- spacja
-- Linia 2: "A:2 B:3 C:1 D:4"
when "01100" => char_reg <= "01000001"; -- A
when "01101" => char_reg <= "00111010"; -- :
when "01110" => char_reg <= "00110010"; -- 2
when "01111" => char_reg <= "00100000"; --
when "10000" => char_reg <= "01000010"; -- B
when "10001" => char_reg <= "00111010"; -- :
when "10010" => char_reg <= "00110011"; -- 3
when "10011" => char_reg <= "00100000"; --
when "10100" => char_reg <= "01000011"; -- C
when "10101" => char_reg <= "00111010"; -- :
when "10110" => char_reg <= "00110100"; -- 4
when "10111" => char_reg <= "00100000"; --
when others => char_reg <= "00100000"; -- spacja
end case;
end if;
end if;
end process;
end Behavioral;
Read 5 times, last 5 hours ago