Xilinx ML405 Evaluation platform
Till den manövern kan du behöva en tillståndsmaskin och dokumentatione på displayen. Utförandet beror på hur LCD;n förväntar sig att du kommunicerar med den. När jag försökte mig på något liknanade fick jag vackert ta och skriva funktionalitetn för att initiera och kommunicera med displayen själv. Det var iofs roligt att testa men det blir lätt fel. Men man lär sig inget om man inte försöker.
Lycka till!
Lycka till!
Började läsa på hur man kommunicerar med displayen och den är givetvis kopplad i 4-bitsläge istället för 8-bitsläge. Så datan ska delas upp och skickas i 2 nibblar.
Har skrivit:
Har även kopierat in massa konstanter för alla bokstäver och kommandon:
-- Clear screen.
constant CLR: charcode := "00000001";
-- Display ON, with cursor.
constant DON: charcode := "00001110";
-- Set Entry Mode to increment cursor automatically after each character
-- is displayed.
constant SEM: charcode := "00000110";
-- Home cursor
constant HOME: charcode := "00000010";
-- Function set for 8-bit data transfer and 2-line display
constant SET: charcode := "00111000";
-- The alphabet - UPPER CASE only.
constant A: charcode := "01000001";
constant B: charcode := "01000010";
constant C: charcode := "01000011";
osv. som jag hittade på nätet.
Ska börja filura på tillståndsmaskinen, måste leta upp alla timingkrav.
Har skrivit:
Kod: Markera allt
entity LCD is
Port (
CLOCK : in STD_LOGIC;
RESET : in STD_LOGIC;
MESSAGE : in STD_LOGIC_VECTOR(0 to 3) );
LCD_RS : out STD_LOGIC;
LCD_RW : out STD_LOGIC;
LCD_ENABLE : out STD_LOGIC;
LCD_DATA : out STD_LOGIC_VECTOR(0 to 3)
);
end LCD;
-- Clear screen.
constant CLR: charcode := "00000001";
-- Display ON, with cursor.
constant DON: charcode := "00001110";
-- Set Entry Mode to increment cursor automatically after each character
-- is displayed.
constant SEM: charcode := "00000110";
-- Home cursor
constant HOME: charcode := "00000010";
-- Function set for 8-bit data transfer and 2-line display
constant SET: charcode := "00111000";
-- The alphabet - UPPER CASE only.
constant A: charcode := "01000001";
constant B: charcode := "01000010";
constant C: charcode := "01000011";
osv. som jag hittade på nätet.
Ska börja filura på tillståndsmaskinen, måste leta upp alla timingkrav.
Fundera lite på vilken bitordning du ska ha i dina vektorer. Vanligen används (3 downto 0) istället för (0 to 3). I den kod jag har sett, och gjort, har i alla fall "downto" varit vanligare än "to".
Sen kan det vara bra att tänka lite på klockning också och använda enable-signaler om du ska klocka ner vissa block jämfört med ursprungsklockan. Då skulle en inledningen av en process kunna se ut som:
(kod tagen från en bit av min LCD testkod)
Ett trevligt kommando i mitt tycke är kommandot block som delar in en fil i subblock. Då kan "lokala" signaler användas i blocket och det blir lättare att lyfta ut det om man önskar att dela upp koden i fler filer. En del verktyg har (eller har haft) en tendens att syntetisera och optimera bättre med större filer medan konsturktörerna har brutit ner funktionen i massor av småfiler.
Ett exempel på hur jag använder "block" vid kodning:
De signaler som är typade innanför blockgränserna är lokala vilket gör att jag kan ha fler tillståndsmaskiner i samma vhdl-fil med samma namn på tillståndsvariablerna utan att det blir problem. (f.ö. innehåller blocket tre processer därav namnet "huvudprocess" det finns även två timerprocesser.)
Sen kan det vara bra att tänka lite på klockning också och använda enable-signaler om du ska klocka ner vissa block jämfört med ursprungsklockan. Då skulle en inledningen av en process kunna se ut som:
Kod: Markera allt
process(clk)
begin
if (rising_edge(clk)) then
if (rst='1') then
Kommando_LCD <= "00";
databyte_LCD <= x"00";
tillst <= T_0;
bytebuffer <= (others => '0');
elsif (ce='1') then
.....
Ett trevligt kommando i mitt tycke är kommandot block som delar in en fil i subblock. Då kan "lokala" signaler användas i blocket och det blir lättare att lyfta ut det om man önskar att dela upp koden i fler filer. En del verktyg har (eller har haft) en tendens att syntetisera och optimera bättre med större filer medan konsturktörerna har brutit ner funktionen i massor av småfiler.
Ett exempel på hur jag använder "block" vid kodning:
Kod: Markera allt
-- purpose: Skriver data till LCD
-- Indata: databyte_LCD
-- Kommando_LCD 00=inget 01=skrivdata 10=skriv adress 11=initiera
-- Utdata: LCD_klar=1 om skrivning kan ske
-- LCD_data LCD_rs LCD_en till motsvarande pinnar på LCD
LCD_block: block
type mystates is (T_init0, T_init1, T_init2, T_init3, T_init4,
T_init5, T_init6, T_init7, T_init7b, T_init8, T_init9,
T_init10, T_init11, T_sd0,T_sd1,T_sd2,T_sd3, T_vantlage0);
signal tillst,ret_tillst : mystates;
signal LWcntr_data,LWcntr : std_logic_vector(31 downto 0);
signal LWcntr_en, LWcntr_rdy, LWcntr_run : std_logic;
signal SWcntr_data,SWcntr : std_logic_vector(7 downto 0);
signal SWcntr_en, SWcntr_rdy, SWcntr_run : std_logic;
begin -- block LCD_block
huvudprocess: process (clk)
begin -- process huvudprocess
if (rising_edge(clk)) then
if (resetn='0') then
LCD_klar <= '0';
tillst <= T_init0;
LCD_en <= '0';
LCD_rs <= '0';
LWcntr_en <= '0';
SWcntr_en <= '0';
LWcntr_data <= (others => '0');
SWcntr_data <= (others => '0');
elsif (ce='1') then
case tillst is
......
end process;
end block LCD_block;
Är det mycket kringkomponenter som krävs om man gör ett eget kort? Finns det någon väldigt enkel/billig FPGA som man kan använda sig av? Behöver inte vara särskilt kraftfull alls. Syfte: http://elektronikforumet.com/forum/view ... hp?t=26271