logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak zmieniać napisy na LCD 2x16 w Spartan 3E na płycie MMFPGA_12?

LATEX 07 Lut 2011 20:03 1685 6
REKLAMA
  • #1 9118059
    LATEX
    Poziom 2  
    Posty: 4
    Witam
    Od jakiegoś czasu zacząłem przygodę z układem spartan 3e. korzystam z płyty MMFPGA_12 firmy PROPOX.
    Wykonałem program do obsługi wyświetlacza LCD 2*16 po 4 bitach.
    Chciałbym wykonać program, który po wciśnięciu jednego przycisku wyświetli jakiś tam napis, a po wciśnięciu innego przycisku napis zmieni się na inny.
    Próbowałem to zrobić we własnym zakresie ale kończą mi się pomysły. wykonałem program, który wyświetla drugi napis, ale go nadpisuje a nie wyświetla od nowa.

    Prosiłbym o jakąkolwiek pomoc w tym temacie.
  • REKLAMA
  • #2 9121418
    lss
    Poziom 21  
    Posty: 352
    Pomógł: 59
    Ocena: 20
    Musisz za każdym razem wyczyścić wyświetlacz a potem dać napis a wiec algorytm jest taki:
    1) incjalizacja
    2) czyszczenie zawartości LCD
    3) pierwszy napis
    4) n-te czyszczenie zawartości LCD
    5) n-ty napisz
  • REKLAMA
  • #3 9129090
    LATEX
    Poziom 2  
    Posty: 4
    Robie tak jak podpowiadasz ale ciągle mi nadpisuje. Dołączam zrzut programu, może to coś pomoże.

    
    ------------------------------------------------------------------------------
    ------------------------------------------------------------------------------
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    
    
    entity LCD is
    port(
    		clk_50MHz 	:in	std_logic; -- zegar systemowy 50MHz
    		reset			:in	std_logic; -- reset systemu
    		A				:in	std_logic;
    		B				:in	std_logic;
    		-- LCD 
    		LCD_RS		:out	std_logic;
    		LCD_E			:out	std_logic;
    		LCD_D			:out	std_logic_vector(3 downto 0)
    	 );	
    end LCD;
    
    	
    architecture Behavioral of LCD is
    
    signal clk_1Hz		: std_logic; -- zegar 1[Hz]
    signal clk_LCD    : std_logic; -- zegar sterujacy LCD 1[kHz]
    
    signal init_state : integer range 0 to 100;
    signal data_state : integer range 0 to 100;
    
    type napis is array (16 downto 0) of std_logic_vector(7 downto 0);
    signal tekst1 : napis;
    signal tekst2 : napis;
    
    begin							 
    -------------------------------------------------------------------
    -- generacja zegara 1Hz oraz zegara 1kHz
    -------------------------------------------------------------------
    process(clk_50MHz,reset)
    variable counter      : integer range 0 to 50000000;
    variable counter_LCD  : integer range 0 to 50000;
    begin
    	if(reset='0')then
    		counter := 0;
    		counter_LCD := 0;
    		clk_1Hz  <= '0';
    		clk_LCD  <= '0';
    	-- reakcja na zbocze narastajace zegara
    	elsif(clk_50MHz'event and clk_50MHz='1')then
    	   -- inkrementacja licznikow
    		counter := counter + 1;
    		counter_LCD := counter_LCD + 1;
    		if(counter=50000000)then
    			counter := 0;
    			clk_1Hz <= not clk_1Hz;   -- generacja zegara 1Hz
    		end if;
    		if(counter_LCD=50000)then
    			counter_LCD := 0;
    			clk_LCD <= not clk_LCD;   -- generacja zegara 1kHz
    		end if;		
    	end if;
    end process;
    
    -------------------------------------------------------------------
    -- obsuga wywietlacza LCD
    -------------------------------------------------------------------
    process(clk_LCD,reset)
    variable delay_count : integer range 0 to 100;
    variable i           : integer range 0 to 16;
    begin
    	if(reset='0')then
    		LCD_RS <= '0';
    		LCD_E  <= '0';
    		LCD_D  <= (others => '0');
    		
    		delay_count := 0;
    		init_state <= 0;
    		data_state <= 0;
    		
    		i := 0;
    		
    		tekst1(0)  <= "01001111"; --O
    		tekst1(1)  <= "01010000"; --P
    		tekst1(2)  <= "01010000"; --P
    		tekst1(3)  <= "01010000"; --P
    		tekst1(4)  <= "01010000"; --P
    		tekst1(5)  <= "01010000"; --P
    		tekst1(6)  <= "01010000"; --P
    		tekst1(7)  <= "01010000"; --P
    		tekst1(8)  <= "01010000"; --P
    		tekst1(9)  <= "01010000"; --P
    		tekst1(10) <= "01010000"; --P
    		tekst1(11) <= "01010000"; --P
    		tekst1(12) <= "01010000"; --P
    		tekst1(13) <= "01010000"; --P
    		tekst1(14) <= "01010000"; --P
    		tekst1(15) <= "01001111"; --O
    		
    		tekst2(0)  <= "01010000"; --P
    		tekst2(1)  <= "01001111"; --O
    		tekst2(2)  <= "01001111"; --O
    		tekst2(3)  <= "01001111"; --O
    		tekst2(4)  <= "01001111"; --O
    		tekst2(5)  <= "01001111"; --O
    		tekst2(6)  <= "01001111"; --O
    		tekst2(7)  <= "01001111"; --O
    		tekst2(8)  <= "01001111"; --O
    		tekst2(9)  <= "01001111"; --O
    		tekst2(10) <= "01001111"; --O
    		tekst2(11) <= "01001111"; --O
    		tekst2(12) <= "01001111"; --O
    		tekst2(13) <= "01001111"; --O
    		tekst2(14) <= "01001111"; --O
    		tekst2(15) <= "01010000"; --P
    		
    	-- reakcja na zbocze narastajace zegara
    	elsif(clk_LCD'event and clk_LCD='1')then
    
    ----------------------- Inicjalizacja ----------------------------
    ------------------------------------------------------------------		
    		-- Power On
    		if(init_state=0)then
    			delay_count := delay_count + 1;
    			if(delay_count=20)then
    				delay_count := 0;
    				init_state <= 1;
    			end if;
    		end if;
    		
    		------------------------------------------
    		-- First 0x03
    		if(init_state=1)then
    			LCD_D <= "0011";
    			LCD_E <= '1';
    			init_state <= 2;
    		end if;
    		-- Delay
    		if(init_state=2)then
    			LCD_E <= '0';
    			delay_count := delay_count + 1;
    			if(delay_count=10)then
    				delay_count := 0;
    				init_state <= 3;
    			end if;
    		end if;
    		-- Second 0x03
    		if(init_state=3)then
    			LCD_D <= "0011";
    			LCD_E <= '1';
    			init_state <= 4;
    		end if;
    		-- Delay
    		if(init_state=4)then
    			LCD_E <= '0';
    			delay_count := delay_count + 1;
    			if(delay_count=10)then
    				delay_count := 0;
    				init_state <= 5;
    			end if;
    		end if;
    		-- Third 0x03
    		if(init_state=5)then
    			LCD_D <= "0011";
    			LCD_E <= '1';
    			init_state <= 6;
    		end if;
    		-- Delay
    		if(init_state=6)then
    			LCD_E <= '0';
    			delay_count := delay_count + 1;
    			if(delay_count=10)then
    				delay_count := 0;
    				init_state <= 7;
    			end if;
    		end if;
    		-------------------------------------------------
    		
    		-- Four Bit Mode --
    		if(init_state=7)then
    			LCD_D <= "0010";
    			LCD_E <= '1';
    			init_state <= 8;
    		end if;
    		-- Delay
    		if(init_state=8)then
    			LCD_E <= '0';
    			init_state <= 9;
    		end if;
    		
    		
    		-- Set Interface Length --
    		-- 4 MSB
    		if(init_state=9)then
    			LCD_D <= "0010";
    			LCD_E <= '1';
    			init_state <= 10;
    		end if;
    		-- Delay
    		if(init_state=10)then
    			LCD_E <= '0';
    			init_state <= 11;
    		end if;
    		-- 4 LSB
    		if(init_state=11)then
    			LCD_D <= "1000";
    			LCD_E <= '1';
    			init_state <= 12;
    		end if;
    		-- Delay
    		if(init_state=12)then
    			LCD_E <= '0';
    			init_state <= 13;
    		end if;
    		
    		-- Turn Off Display --
    		-- 4 MSB
    		if(init_state=13)then
    			LCD_D <= "0000";
    			LCD_E <= '1';
    			init_state <= 14;
    		end if;
    		-- Delay
    		if(init_state=14)then
    			LCD_E <= '0';
    			init_state <= 15;
    		end if;
    		-- 4 LSB
    		if(init_state=15)then
    			LCD_D <= "1000";
    			LCD_E <= '1';
    			init_state <= 16;
    		end if;
    		-- Delay
    		if(init_state=16)then
    			LCD_E <= '0';
    			init_state <= 17;
    		end if;
    		
    		-- Clear Display --
    		-- 4 MSB
    		if(init_state=17)then
    			LCD_D <= "0000";
    			LCD_E <= '1';
    			init_state <= 18;
    		end if;
    		-- Delay
    		if(init_state=18)then
    			LCD_E <= '0';
    			init_state <= 19;
    		end if;
    		-- 4 LSB
    		if(init_state=19)then
    			LCD_D <= "0001";
    			LCD_E <= '1';
    			init_state <= 20;
    		end if;
    		-- Delay
    		if(init_state=20)then
    			LCD_E <= '0';
    			init_state <= 21;
    		end if;
    
    		-- Set Cursor Move Direction --
    		-- 4 MSB
    		if(init_state=21)then
    			LCD_D <= "0000";
    			LCD_E <= '1';
    			init_state <= 22;
    		end if;
    		-- Delay
    		if(init_state=22)then
    			LCD_E <= '0';
    			init_state <= 23;
    		end if;
    		-- 4 LSB
    		if(init_state=23)then
    			LCD_D <= "0110";
    			LCD_E <= '1';
    			init_state <= 24;
    		end if;
    		-- Delay
    		if(init_state=24)then
    			LCD_E <= '0';
    			init_state <= 25;
    		end if;
    		
    		-- Enable Display/Cursor --
    		-- 4 MSB
    		if(init_state=25)then
    			LCD_D <= "0000";
    			LCD_E <= '1';
    			init_state <= 26;
    		end if;
    		-- Delay
    		if(init_state=26)then
    			LCD_E <= '0';
    			init_state <= 27;
    		end if;
    		-- 4 LSB
    		if(init_state=27)then
    			LCD_D <= "1111";
    			LCD_E <= '1';
    			init_state <= 28;
    		end if;
    		-- Delay
    		if(init_state=28)then
    			LCD_E <= '0';
    			init_state <= 29;
    			data_state <= 1;
    		end if;
    
    
    ------------------------------------------------------------------
    ------------------------------------------------------------------
    		-- Data --
    		-- 4 MSB
    		if(data_state=1 and A = '0')then
    			data_state <= 2;
    		end if;
    		if(data_state=2)then
    			LCD_D <= tekst1(i)(7 downto 4);
    			LCD_E <= '1';
    			LCD_RS <= '1';
    			data_state <= 3;
    		end if;
    		-- Delay
    		if(data_state=3)then
    			LCD_E <= '0';
    			data_state <= 4;
    		end if;
    		-- 4 LSB
    		if(data_state=4)then
    			LCD_D <= tekst1(i)(3 downto 0);
    			LCD_E <= '1';
    			data_state <= 5;
    		end if;
    		-- Delay
    		if(data_state=5)then
    			LCD_E <= '0';
    			data_state <= 2;
    			
    			i := i + 1;
    			if(i=16)then
    
    				data_state <= 6;
    			end if;
    		end if;
    -----koniec pierwszego napisu-----		
    		
    		-- Data --
    		-- 4 MSB
    		if(data_state=6 and B = '0')then
    		
    		-- Clear Display --
    		-- 4 MSB	
    			LCD_D <= "0000";
    			LCD_E <= '1';
    			data_state <=7;
    		end if;
    		-- Delay
    		if(data_state=7)then
    			LCD_E <= '0';
    			data_state <=8;
    		end if;
    		-- 4 LSB
    		if(data_state=8)then
    			LCD_D <= "0001";
    			LCD_E <= '1';
    			data_state <=9;
    		end if;
    		-- Delay
    		if(data_state=9)then
    			LCD_E <= '0';
    			data_state <=10;
    		end if;
    ----------drugi napis---------------------		
    		if(data_state=10) then
    			LCD_D <= tekst2(i)(7 downto 4);
    			LCD_E <= '1';
    			LCD_RS <= '1';
    			data_state <= 11;
    		end if;
    		-- Delay
    		if(data_state=11)then
    			LCD_E <= '0';
    			data_state <= 12;
    		end if;
    		-- 4 LSB
    		if(data_state=12)then
    			LCD_D <= tekst2(i)(3 downto 0);
    			LCD_E <= '1';
    			data_state <= 13;
    		end if;
    		-- Delay
    		if(data_state=13)then
    			LCD_E <= '0';
    			data_state <= 10;
    			
    			i := i + 1;
    			if(i=16)then
    				data_state <= 14;
    			end if;
    		end if;
    	
    ------------------------------------------------------------------
    ------------------------------------------------------------------
    		
    	end if;
    end process;
    
    end Behavioral;
    
    
  • #4 9130063
    tymon_x
    Poziom 30  
    Posty: 1021
    Pomógł: 171
    Ocena: 15
    Zmień to coś, na maszynę stanów do takiej postaci:
    com: process(p_clk, rst_i, next_state) is 
    	begin
    	if rst_i = '1' then
    		present_state <= state_1;
    	elsif rising_edge(p_clk) then
    		present_state <= next_state;
    	end if;
    end process;


    h_com: process(present_state, A, B) is
    	begin
    	cos1    <= '0';
    	cos2    <= '0'; 
    	---------------------------------------
    	case present_state is
    	---------------------------------------
    		when state_1 =>
    			cos1  <= '0';	
    			cos2  <= '1';
    			if A = '1' then 
    				next_state <= state_1; 
    			else
    				next_state <= state_2;
    			end if;
    		------------------------------------
    		when state_2 =>
    			cos1  <= '1';	
    			cos2  <= '0';	
    			if B = '1' then 
    				next_state <= state_1; 
    			else
    				next_state <= state_2;
    			end if;
    		------------------------------------
    	end case;
    	----------------------------------------
    end process;


    type state_type is (state_1, state_2);
    signal present_state, next_state : state_type;


    Gdzie state_1 i 2 to nazwy czynności, które coś robią. Tobie i nam będzie łatwiej szukać błędu...
    Także, by się przydała nazwa sterownika od LCD (chociaż zapewne na 93.4% chodzi o HD44780).
  • REKLAMA
  • #5 9130214
    LATEX
    Poziom 2  
    Posty: 4
    Nie będę ukrywał, że jestem mocno początkujący jeżeli chodzi o układy FPGA jak i wogóle o programowanie. Czytałem już gdzieś że takie coś jak ja chcę wykonać to właśnie mam stworzyć maszynę stanów. Dokładnie to chodzi mi o stworzenie menu wyboru. Ten program który wkleiłem rozumiem całkowicie.

    Ale z tego co mi tu radzicie to muszę się wczytać dokładnie na czym polega i jak się tworzy taką maszynę stanów bo chyba na tym będzie łatwiej, no i będzie działać.
    A może ktoś z Was zna jakiś poradnik, książkę czy coś podobnego gdzie będzie coś opisane apropo tej maszyny stanów?

    Chciałbym żeby ktoś mnie naprowadził do prawidłowego rozwiązania, sam program chce wykonać sam bo tylko wtedy się tego nauczę i będę to rozumiał.
  • REKLAMA
  • #7 9133926
    LATEX
    Poziom 2  
    Posty: 4
    dobra temat ogranięty :)
    Wszystko działa tak jak chciałem brakowało czegoś w kodzie i trzeba było wyzerować wartość "i" po wyświetleniu pierwszego napisu

    Mimo wszystko dzięki wielkie za pomoc

Podsumowanie tematu

✨ Użytkownik rozpoczął pracę z układem Spartan 3E na płycie MMFPGA_12 firmy PROPOX i stworzył program do obsługi wyświetlacza LCD 2x16. Chciałby, aby po naciśnięciu przycisków wyświetlał różne napisy, jednak napotkał problem z nadpisywaniem tekstu. Otrzymał porady dotyczące konieczności czyszczenia wyświetlacza przed wyświetleniem nowego napisu oraz sugestię, aby zastosować maszynę stanów do zarządzania zmianą napisów. Użytkownik zrozumiał, że musi lepiej poznać koncepcję maszyn stanów, aby poprawnie zaimplementować funkcjonalność. Po dalszych próbach i wskazówkach, udało mu się rozwiązać problem, dodając odpowiednie zerowanie wartości w kodzie.
REKLAMA