Raw Text Content QR
bat-jaguar-bee



----------------------------------------------------------------------------------
-- 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