VHDL i wyświetlacz LCD 2x16 (HD44780)



Masz problem? Zapytaj na forum elektroda.pl

Poprzedni Następny
Wiadomość
Spis treści
From: "memento" <memento-pl_at_nospam_gazeta.pl>
Subject: VHDL i wyświetlacz LCD 2x16 (HD44780)
Date: Tue, 13 Sep 2005 01:06:28 +0200


Nie tak dawno zadałem pytanie czy ktoś z Państwa zna program napisany w
VHDLu sterujący panelem LCD? Z tego co widzę skonstruowanie czegoś takiego
jest zbyt skomplikowane i pracochlonne. Stąd moje kolejne pytanie brzmi:

Czy ktoś z Państwa wie jak napisać program w VHDL-u sterujący wyświetlaczem
LCD? (np. 2x16, albo 2x20 itp) który jest oparty na kontrolerze HD44780?

Pozdrawiam,
MEMENTO



Poprzedni Następny
Wiadomość
Spis treści
From: "Krzysiek." <_at_nospam_dla.zaufanych.zapytaj>
Subject: =?iso-8859-2?Q?Re:_VHDL_i_wy=B6wietlacz_LCD_2x16_=28HD44780=29?=
Date: Tue, 13 Sep 2005 02:38:07 +0200


memento <memento-pl_at_nospam_gazeta.pl> napisal nam:

Nie tak dawno zadałem pytanie czy ktoś z Państwa zna program napisany
w VHDLu sterujący panelem LCD? Z tego co widzę skonstruowanie czegoś
takiego jest zbyt skomplikowane i pracochlonne. Stąd moje kolejne
pytanie brzmi:

Czy ktoś z Państwa wie jak napisać program w VHDL-u sterujący
wyświetlaczem LCD? (np. 2x16, albo 2x20 itp) który jest oparty na
kontrolerze HD44780?


Masz tu kwalek kodu, wow! it is working wyswietla na lcd hd44780.
Kod kolegi to sie mnie nie pytaj czemu tak a nie inaczej, ja robilem inne
bajerki :-)


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
--

entity dzielnik is
port ( clk : in std_logic;
lcd_data: inout std_logic_vector(7 downto 0):="00110000";
led : out std_logic_vector(7 downto 0):="10000000";
enable: out std_logic:='0';
control: out std_logic_vector(1 downto 0):="00"
);

-- T=ilosc taktow dla zegara 50MHz

constant tInit_2: integer := 20000000; --20czekaj >40ms (2000000T)
constant tInit_1: integer := 2000000; --15czekaj >4.1ms (210000T)
constant tInit_0: integer := 50000; --10czekaj >100us (5000T)
constant tBusy: integer := 40000; --5czekaj na zakonczenie instrukcji
>37us (2000T)
constant tAS: integer := 4; --2ustalenie adresu >40ns (2T)
constant tPWEH: integer := 15; --3czas podtrzymania stanu H na Enable
>230ns (12T)
constant tPWEL: integer := 15; --4czas podtrzymania stanu L na Enable
>270ns (14T)

constant cFuncSet: std_logic_vector(7 downto 0):="00111000";
--0011NF** N=0(1) to 1(2) linia(e) F=0 5x8 matryca znaku
constant cDispOff: std_logic_vector(7 downto 0):="00001000";
constant cDispClr: std_logic_vector(7 downto 0):="00000001";
constant cModeSet: std_logic_vector(7 downto 0):="00000110";
--000001(I/~D)S I=1(0) in(de)krementacja S=(0)1 (no)shift
constant cDispOn: std_logic_vector(7 downto 0):="00001111";

end dzielnik;

architecture Behavioral of dzielnik is
signal clk_1: std_logic:='0';
signal delay:integer range 1 to 100000000:=tInit_2;--zainicjowane czekanie
na ustalenie napiecia (2000000T)

begin

divider:process(clk,lcd_data)
variable CountDown: integer range 0 to 100000000;
begin
if rising_edge(clk) then
if CountDown=0 then
clk_1<='0';
CountDown:= delay;
else
clk_1<='1';
CountDown:= CountDown-1;
end if;
end if;
end process divider;

LCD:process(clk_1)
type State_Type is
(Init_2,Init_1,Init_0,FunctionSet,DisplayOff,DisplayClear,EntryModeSet,Displ
ayOn,Operational);
type Op_Type is (EstablishData,EnableHigh,EnableLow,Start);
type Linia_Type is array (0 to 15) of std_logic_vector (7 downto 0);

variable State : State_Type;
variable OpState :Op_Type;

variable init :std_logic:='1';
variable position :integer range 0 to 15;
variable Linia1 :Linia_Type;
variable write :integer range 0 to 16; --ile znakow ma zapisac

begin
if rising_edge(clk_1) then
case State is
when Init_2 =>
led<="01000000";
if (OpState=EstablishData) then
control <= "00";
lcd_data<="00110000";
else if (OpState=Start) then
State:=Init_1;
delay<=tInit_1;
end if;
end if;

when Init_1 =>
led<="00100000";
if (OpState=EstablishData) then
control <= "00";
lcd_data<="00110000";
else if (OpState=Start) then
State:=Init_0;
delay<=tInit_0;
end if;
end if;

when Init_0 =>
led<="00010000";
if (OpState=EstablishData) then
control <= "00";
lcd_data<="00110000";
else if (OpState=Start) then
State:=FunctionSet;
delay<=tBusy;
end if;
end if;

when FunctionSet =>
led<="00001000";
if (OpState=EstablishData) then
control <= "00";
lcd_data<=cFuncSet;
else if (OpState=Start) then
State:=DisplayOff;
delay<=tAS;
end if;
end if;

when DisplayOff =>
led<="00000100";
if (OpState=EstablishData) then
control <= "00";
lcd_data<= cDispOff;
else if (OpState=Start) then
State:=DisplayClear;
delay<=tAS;
end if;
end if;

when DisplayClear =>
led<="00000010";
if (OpState=EstablishData) then
control <= "00";
lcd_data<= cDispClr;
else if (OpState=Start) then
State:=EntryModeSet;
delay<=tAS;
end if;
end if;

when EntryModeSet =>
led<="00000001";
if (OpState=EstablishData) then
control <= "00";
lcd_data<= cModeSet;
else if (OpState=Start) then
State:=DisplayOn;
delay<=tAS;
Linia1(0) :="01010111"; --W
Linia1(1) :="01101111"; --o
Linia1(2) :="01110111"; --w
Linia1(3) :="00100001"; --!
Linia1(4) :="01001001"; --I
Linia1(5) :="01110100"; --t
Linia1(6) :="00100111"; --'
Linia1(7) :="01110011"; --s
Linia1(8) :="00100000"; --
Linia1(9) :="01110111"; --w
Linia1(10):="01101111"; --o
Linia1(11):="01110010"; --r
Linia1(12):="01101011"; --k
Linia1(13):="01101001"; --i
Linia1(14):="01101110"; --n
Linia1(15):="01100111"; --g
write:=16;
end if;
end if;

when DisplayOn =>
if (OpState=EstablishData) then
led<="00000011";
init:='0';
control <= "00";
lcd_data<= cDispOn;
else if (OpState=Start) then
State:=Operational;
delay<=tAS;
end if;
end if;

when Operational =>
if (OpState=EstablishData) then
led<="01010101";
control <= "01";
lcd_data<= Linia1(Position);
Position:=Position+1;
write:=write-1;
else if (OpState=Start) then
led<="10101010";
delay<=tAS;
end if;
end if;
when others => null;
end case;

case OpState is
when EstablishData => delay<=tPWEH; enable<='0'; OpState:=EnableHigh;
when EnableHigh => delay<=tPWEL; enable<='1'; OpState:=EnableLow;
when EnableLow => delay<=tBusy; enable<='0'; OpState:=Start;
when Start => if (init='1' or write>0) then
OpState:= EstablishData;
else
delay<=tAS;
end if;
enable<='0';
when others => enable<='0';
end case;
end if;

end process LCD;
end Behavioral;




Poprzedni Następny
Wiadomość
Spis treści
From: "Jacek R. Radzikowski" <jacek_at_nospam_spamer.die.die.die.piranet.org>
Subject: Re: VHDL i wy?wietlacz LCD 2x16 (HD44780)
Date: Mon, 12 Sep 2005 23:22:52 +0000 (UTC)


memento <memento-pl_at_nospam_gazeta.pl> wrote:
Nie tak dawno zada?em pytanie czy kto? z Pa?stwa zna program napisany w
VHDLu steruj?cy panelem LCD? Z tego co widz? skonstruowanie czego? takiego
jest zbyt skomplikowane i pracochlonne. St?d moje kolejne pytanie brzmi:

Czy kto? z Pa?stwa wie jak napisa? program w VHDL-u steruj?cy wy?wietlaczem
LCD? (np. 2x16, albo 2x20 itp) kt?ry jest oparty na kontrolerze HD44780?

Sterować w jakim sensie? Dekoder adresowy, kompresja 8b->4b czy wysyłanie
instrukcji? Jeśli to ostatnie to najprościej będzie wpakować rdzeń jakiegoś
prostego, małego procka z OpenCores i napisać kilka linijek programu.

pzdr.
j.

Pozdrawiam,
MEMENTO