Presentation is loading. Please wait.

Presentation is loading. Please wait.

Software Environment ISE 5.x Interaction with simple LCDs

Similar presentations


Presentation on theme: "Software Environment ISE 5.x Interaction with simple LCDs"— Presentation transcript:

1 Software Environment ISE 5.x Interaction with simple LCDs
Tutorial - LCD Xilinx Integrated Software Environment ISE 5.x Interaction with simple LCDs Authors: V.Sklyarov, I.Skliarova Copyright (c) 2003 by Valery Sklyarov and Iouliia Skliarova: DETUA, IEETA, Aveiro University, Portugal

2 HD44780U Dot Matrix LCD Controller/Driver
Expansion connector Two LCDs can function at the same time LCD control KS0073 Driver & Controller for dot matrix LCD

3 Connections GND ext_a<0> (FPGA pin H14) 5V cs_lcd (FPGA pin A9)
Expansion connector see manual on EA DIP 204-4 (Electronic Assembly - Germany) see Spartan IIE development platform (Trenz Electronic - Germany) GND ext_a<0> (FPGA pin H14) 5V cs_lcd (FPGA pin A9) contrast resistor ext_rw (FPGA pin D16) GND

4 NET "clk48in" TNM_NET = "clk48in";
TIMESPEC "TS_clk48in" = PERIOD "clk48in" 48 MHz HIGH 50 %; NET "clk48in" LOC = "t9"; NET "init" LOC = "p15"; NET "ext_a<2>" LOC = "H15"; NET "ext_a<1>" LOC = "F16"; NET "ext_a<0>" LOC = "H13"; NET "csn_lcd" LOC = "G14"; NET "cs_lcd" LOC = "G13"; NET "ext_d<2>" LOC = "D15"; NET "ext_rw" LOC = "D16"; NET "ext_d<6>" LOC = "F13"; NET "ext_d<4>" LOC = "E14"; NET "ext_d<0>" LOC = "C16"; NET "ext_d<7>" LOC = "G12"; NET "ext_d<5>" LOC = "F12"; NET "ext_d<3>" LOC = "E13"; NET "ext_d<1>" LOC = "D14"; NET "cpld_cs" LOC = "m16"; NET "cpld_rw" LOC = "m15"; NET "a<1>" LOC = "t10"; NET "a<2>" LOC = "m10"; NET "d<0>" LOC = "b16"; NET "d<1>" LOC = "e15"; NET "d<2>" LOC = "f14"; NET "d<3>" LOC = "G15"; NET "d<4>" LOC = "J14"; NET "d<5>" LOC = "L13"; NET "d<6>" LOC = "L16"; NET "d<7>" LOC = "P16";

5 Example 1 library IEEE; use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Hitachi_lcd is port ( cpld_rw: inout std_logic; cpld_cs: out std_logic; a : out std_logic_vector(2 downto 1); d : inout std_logic_vector(7 downto 0); clk : in std_logic; -- clock 48 MHz rst : in std_logic; -- reset ext_a : out std_logic_vector(2 downto 0); -- LCD control ext_d : out std_logic_vector(7 downto 0); -- LCD data ext_rw : out std_logic; LCD read/write cs_lcd : out std_logic; LCD chip select active high csn_lcd : out std_logic LCD data direction ); end Hitachi_lcd;

6 signal div: unsigned (20 downto 0);
architecture Behavioral of Hitachi_lcd is signal state : std_logic_vector(3 downto 0); signal lled : std_logic_vector(7 downto 0); onboard leds (3 downto 0) signal lpb : std_logic_vector(7 downto 0); -- onboard pushbuttons signal dipswitch : std_logic_vector(7 downto 0); signal clk: std_logic; local clock signal div: unsigned (16 downto 0); -- local clock divider signal reset: std_logic; -- lcd reset sequence active signal cmd: std_logic_vector (7 downto 0); -- data/command to lcd signal rs: std_logic; register select bit for lcd signal idx: integer range 0 to 3; -- sequencer index for lcd timing signal cs: std_logic; chip select for lcd signal cnt: unsigned (5 downto 0); -- character, command counter constant line1: string(1 to 16):= "LCD operations :"; strings to display constant line2: string(1 to 4):= "DEMO"; begin process(clk48, rst) -- local clock generator if rst= '1' then div <= (others=> '0'); elsif rising_edge(clk48) then div<= div + 1; end if; end process; clk<= div(div'left); -- the following blue text is included just in order to read dip switchers through CPLD -- see tutorial 2 for details signal div: unsigned (20 downto 0); This line can be changed as follows in order to see how each character is displayed from left to right

7 process(clk48, rst) begin if rst= '1' then state<= (others=> '0'); elsif rising_edge(clk48) then state<= state + 1; end if; end process; cpld_cs <= '1'; case state is when "0000" => a <= "00"; -- address = 00 => push buttons cpld_rw <= '1'; -- read from cpld when "0001" => cpld_cs <= '0'; -- chip select for cpld active when "0010" => lpb <= d; -- latch cpld data when "0011" => cpld_cs <= '1'; -- chip select inactive when "0100" => a <= "10"; -- address = 01 => led's cpld_rw <= '0'; -- write to cpld when "0101" => cpld_cs <= '0'; -- generate chip select pulse when "0110" => cpld_cs <= '1'; when "0111" => a <= "01"; -- address = 01 => Dip switch when "1000" => cpld_cs <= '0'; -- chip select for cpld active when "1001" => dipswitch <= d; -- latch cpld data when "1010" => cpld_cs <= '1'; -- chip select inactive when others => cpld_cs <= '1'; end case; process (lled,cpld_rw) if (cpld_rw='0') then d <= lled; else d <= "ZZZZZZZZ";

8 This part was taken from Trenz electronic example
process(clk, rst) -- LCD sub-clocks sequencer begin if rst= '1' then idx <= 0; elsif rising_edge(clk) then if idx= 3 then idx<= 0; else idx<= idx + 1; end if; end if; end process; process(clk, rst) -- LCD local control signals generator cs <= '0'; ext_a <= (others=> '0'); ext_d <= (others=> '0'); case idx is when 0=> ext_a<= "00" & rs; -- set register address when 1=> cs <= '1';ext_d<= cmd; -- write data, activate chip select when 2=> cs <= '0'; -- deactivate chip select when 3=> null; -- data hold time end case; ext_rw<= '0'; always write to LCD cs_lcd <= cs; chip select for LCD csn_lcd<= '0'; always write to LCD This part was taken from Trenz electronic example (see the manual HD44780U Dot Matrix LCD Controller/ Driver for details)

9 Dot Matrix LCD Controller/
process(clk, rst) begin if rst= '1' then cmd <= x"02"; -- clear DDRAM counter, switch off shift rs <= '1'; reset <= '1'; -- activate LCD initialization from the beginning cnt <= (others => '0'); elsif rising_edge(clk) then if idx = 2 then cnt <= cnt + 1; end if; if (reset ='0') then -- normal functionality after initialization case cnt is when "000000" => cmd <= x"80"; rs <= '0'; -- DDRAM address to the beginning of the first line when "000001" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(1)), 8)); rs <= '1'; when "000010" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(2)), 8)); rs <= '1'; when "000011" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(3)), 8)); rs <= '1'; when "000100" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(4)), 8)); rs <= '1'; when "000101" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(5)), 8)); rs <= '1'; when "000110" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(6)), 8)); rs <= '1'; when "000111" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(7)), 8)); rs <= '1'; when "001000" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(8)), 8)); rs <= '1'; when "001001" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(9)), 8)); rs <= '1'; when "001010" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(10)), 8)); rs <= '1'; when "001011" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(11)), 8)); rs <= '1'; when "001100" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(12)), 8)); rs <= '1'; when "001101" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(13)), 8)); rs <= '1'; when "001110" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(14)), 8)); rs <= '1'; when "001111" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(15)), 8)); rs <= '1'; when "010000" => cmd <= std_logic_vector(to_unsigned(character'pos(line1(16)), 8)); rs <= '1'; constant line1: string(1 to 16):= "LCD operations :"; strings to display See the manual HD44780U Dot Matrix LCD Controller/ Driver for details LCD operations : The result of this sequence is

10 For shift left and right
constant line2: string(1 to 4):= "DEMO"; when "010001" => cmd <= x"C0"; rs <= '0'; -- DDRAM address to the beginning of the second line when "010-1-"|"0101--" => cmd <= x"20"; rs <= '1'; when "011000" => cmd <= std_logic_vector(to_unsigned(character'pos(line2(1)), 8)); rs <= '1'; when "011001" => cmd <= std_logic_vector(to_unsigned(character'pos(line2(2)), 8)); rs <= '1'; when "011010" => cmd <= std_logic_vector(to_unsigned(character'pos(line2(3)), 8)); rs <= '1'; when "011011" => cmd <= std_logic_vector(to_unsigned(character'pos(line2(4)), 8)); rs <= '1'; when "0111--"|"10000-" => cmd <= x"20"; rs <= '1'; when "100010" => case dipswitch(1 downto 0) is when "01" => cmd <= x"1C"; rs <= '0'; -- shift display to the right when "10" => cmd <= x"18"; rs <= '0'; -- shift display to the left when others => cmd <= x"80"; rs <= '0'; -- display is unchanged end case; when others => cmd <= x"80"; rs <= '0';--cnt <= "000000"; else -- initialization of LCD from the beginning case cnt is -- delay such as from "000000" to "001000" is important for satisfying LCD timing requirements when "000000" => cmd <= x"38"; rs <= '0'; -- (x"20" Function Set)|(x"10" 8-bit data)| -- (x"08" two lines) when "001000" => cmd <= x"0C"; rs <= '0'; (x"08" display control)|(x"04" display on)| -- (x"00" cursor off - our case; x"02" cursor on) when "010000" => cmd <= x"06"; rs <= '0'; -- (x"04" entry mode set)|(x"02" increment on) when "011000" => cmd <= x"01"; rs <= '0'; (x"01" clear display and DDRAM counter) when "100000" => reset <= '0'; cnt <= "000000"; -- initialization is finished when others => null; end if; end process; end Behavioral; DEMO The result of this sequence is 1 S0...S7 For shift left and right

11 The result is Shift right LCD operations : LCD operations :
DEMO LCD operations : DEMO LCD operations : DEMO 1 S0...S7 when "100010" => case dipswitch(1 downto 0) is when "01" => cmd <= x"1C"; rs <= '0'; -- shift display to the right when "10" => cmd <= x"18"; rs <= '0'; -- shift display to the left when others => cmd <= x"80"; rs <= '0'; -- display is unchanged end case; Shift right

12 The result is Shift left LCD operations : LCD operations :
DEMO LCD operations : DEMO LCD operations : DEMO 1 S0...S7 when "100010" => case dipswitch(1 downto 0) is when "01" => cmd <= x"1C"; rs <= '0'; -- shift display to the right when "10" => cmd <= x"18"; rs <= '0'; -- shift display to the left when others => cmd <= x"80"; rs <= '0'; -- display is unchanged end case; Shift left

13 NET "clk48in" TNM_NET = "clk48in";
TIMESPEC "TS_clk48in" = PERIOD "clk48in" 48 MHz HIGH 50 %; NET "clk48in" LOC = "t9"; NET "init" LOC = "p15"; NET "ext_a<2>" LOC = "H15"; NET "ext_a<1>" LOC = "F16"; # beginning of the changes NET "ext_a<0>" LOC = "H14"; # H14 pin for expansion header # for 2x16 LCD this pin must be H13 #NET "csn_lcd" LOC ="G14"; # uncomment for 2x16 LCD NET "cs_lcd" LOC ="A9"; # for 2x16 LCD this pin must be "G13" # end of changes NET "ext_d<2>" LOC = "D15"; NET "ext_rw" LOC = "D16"; NET "ext_d<6>" LOC = "F13"; NET "ext_d<4>" LOC = "E14"; NET "ext_d<0>" LOC = "C16"; NET "ext_d<7>" LOC = "G12"; NET "ext_d<5>" LOC = "F12"; NET "ext_d<3>" LOC = "E13"; NET "ext_d<1>" LOC = "D14"; NET "cpld_cs" LOC = "m16"; NET "cpld_rw" LOC = "m15"; NET "a<1>" LOC = "t10"; NET "a<2>" LOC = "m10"; NET "d<0>" LOC = "b16"; NET "d<1>" LOC = "e15"; NET "d<2>" LOC = "f14"; NET "d<3>" LOC = "G15"; NET "d<4>" LOC = "J14"; NET "d<5>" LOC = "L13"; NET "d<6>" LOC = "L16"; NET "d<7>" LOC = "P16"; Expansion connector

14 Example 2 library IEEE; use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity EA_DIP4x20_lcd is port ( cpld_rw: inout std_logic; cpld_cs: out std_logic; a : out std_logic_vector(2 downto 1); d : inout std_logic_vector(7 downto 0); clk : in std_logic; -- clock 48 MHz rst : in std_logic; -- reset ext_a : out std_logic_vector(2 downto 0); -- LCD control ext_d : out std_logic_vector(7 downto 0); -- LCD data ext_rw : out std_logic; -- LCD read/write cs_lcd : out std_logic; -- LCD chip select active high csn_lcd : out std_logic -- LCD data direction ); end EA_DIP4x20_lcd;

15 architecture Behavioral of EA_DIP4x20_lcd is
signal state : std_logic_vector(3 downto 0); signal lled : std_logic_vector(7 downto 0); -- onboard leds (3 downto 0) signal lpb : std_logic_vector(7 downto 0); -- onboard pushbuttons signal dipswitch : std_logic_vector(7 downto 0); -- onboard DIP switchers signal clk : std_logic; -- local clock signal div : unsigned (16 downto 0); -- local clock divider signal reset : std_logic; -- lcd reset sequence active signal cmd : character; -- character for LCD signal control : std_logic_vector (7 downto 0); -- control data to lcd signal scroll_dots : std_logic_vector (5 downto 0); -- number of dots for -- horizontal scrolling signal rs : std_logic; -- register select bit for lcd signal idx : integer range 0 to 3; -- sequencer index for lcd timing signal cs : std_logic; -- chip select for lcd signal cnt : unsigned (6 downto 0); -- character, command counter constant line1: string(1 to 16):= "LCD operations :"; constant line2: string(1 to 4):= "DEMO"; begin process(clk48, rst) -- local clock generator if rst= '1' then div <= (others=> '0'); elsif rising_edge(clk48) then div<= div + 1; end if; end process; clk<= div(div'left);

16 This blue text is included just in order to read dip switchers through
process(clk48, rst) begin if rst= '1' then state<= (others=> '0'); elsif rising_edge(clk48) then state<= state + 1; end if; end process; cpld_cs <= '1'; case state is when "0000“ => a <= "00"; -- address = 00 => push buttons cpld_rw <= '1'; -- read from cpld when "0001" => cpld_cs <= '0'; -- chip select for cpld active when "0010" => lpb <= d; -- latch cpld data when "0011" => cpld_cs <= '1'; -- chip select inactive when "0100" => a <= "10"; -- address = 01 => led's cpld_rw <= '0'; -- write to cpld when "0101" => cpld_cs <= '0'; -- generate chip select pulse when "0110" => cpld_cs <= '1'; when "0111" => a <= "01"; -- address = 01 => Dip switch when "1000" => cpld_cs <= '0'; -- chip select for cpld active when "1001" => dipswitch <= d; -- latch cpld data when "1010" => cpld_cs <= '1'; -- chip select inactive when others => cpld_cs <= '1'; end case; process (lled,cpld_rw) if (cpld_rw='0') then d <= lled; else d <= "ZZZZZZZZ"; This blue text is included just in order to read dip switchers through CPLD (see tutorial 2 for details)

17 This part was taken from Trenz electronic example
process(clk, rst) LCD sub-clocks sequencer begin if rst= '1' then idx <= 0; elsif rising_edge(clk) then if idx= 3 then idx<= 0; else idx<= idx + 1; end if; end if; end process; process(clk, rst) -- LCD local control signals generator cs <= '0'; ext_a <= (others=> '0'); ext_d <= (others=> '0'); case idx is when 0=> ext_a<= "00" & rs; -- set register adress when 1=> cs <= '1'; if rs = '1' then ext_d <= std_logic_vector(to_unsigned(character'pos(cmd),8)); else ext_d <= control; end if; -- write data, activate chip select when 2=> cs <= '0'; -- deactivate chip select when 3=> null; -- data hold time end case; ext_rw<= '0'; -- always write to LCD cs_lcd <= cs; -- chip select for LCD csn_lcd<= '0'; -- always write to LCD This part was taken from Trenz electronic example (see the manual HD44780U Dot Matrix LCD Controller/ Driver for details) The only change is shown in green color. It was done to separate data to LCD and control signals to LCD

18 The result of this sequence is Line 1;……..End 1 4 lines 20 characters
process(clk, rst) begin if rst= '1' then control <= x"00"; -- clear DDRAM counter, switch off shift rs <= '1'; reset <= '1'; -- activate LCD initialization from the beginning cnt <= (others => '0'); scroll_dots <= (others => '0'); elsif rising_edge(clk) then if idx = 2 then cnt <= cnt + 1; end if; if (reset ='0') then -- normal functionality after initialization case cnt is when " " => control <= x"80"; rs <= '0'; -- first line when " " => cmd <= 'L'; rs <= '1'; when " " => cmd <= 'i'; rs <= '1'; when " " => cmd <= 'n'; rs <= '1'; when " " => cmd <= 'e'; rs <= '1'; when " " => cmd <= ' '; rs <= '1'; when " " => cmd <= '1'; rs <= '1'; when " " => cmd <= ';'; rs <= '1'; when " " => cmd <= '.'; rs <= '1'; when " " => cmd <= 'E'; rs <= '1'; when " " => cmd <= 'n'; rs <= '1'; when " " => cmd <= 'd'; rs <= '1'; when " " => cmd <= ' '; rs <= '1'; when " " => cmd <= '1'; rs <= '1'; Line 1;……..End 1 The result of this sequence is 4 lines 20 characters

19 The result of this sequence is The result of this sequence is
when " " => control <= x"94"; rs <= '0';-- second line when " " => cmd <= 'L'; rs <= '1'; when " " => cmd <= 'i'; rs <= '1'; when " " => cmd <= 'n'; rs <= '1'; when " " => cmd <= 'e'; rs <= '1'; when " " => cmd <= ' '; rs <= '1'; when " " => cmd <= '2'; rs <= '1'; when " " => cmd <= ';'; rs <= '1'; when " "|" " => cmd <= '.'; rs <= '1'; when " "|" " => cmd <= '#'; rs <= '1'; when " " => control <= x"C0"; rs <= '0'; --third line when " " => cmd <= 'L'; rs <= '1'; when " " => cmd <= 'i'; rs <= '1'; when " " => cmd <= 'n'; rs <= '1'; when " " => cmd <= 'e'; rs <= '1'; when " " => cmd <= ' '; rs <= '1'; when " " => cmd <= '3'; rs <= '1'; when " " => cmd <= ';'; rs <= '1'; when " "|" "|" " => cmd <= ' '; rs <= '1'; when " " => cmd <= 'E'; rs <= '1'; when " " => cmd <= 'n'; rs <= '1'; when " " => cmd <= 'd'; rs <= '1'; when " " => cmd <= ' '; rs <= '1'; when " " => cmd <= '3'; rs <= '1'; Line 1;……..End 1 The result of this sequence is Line 2;…########## Line 1;……..End 1 The result of this sequence is Line 2;…########## Line 3; End 3

20 the number of dots for scroll
when " " => control <= x"E0"; rs <= '0'; -- forth line when " " => cmd <= 'L'; rs <= '1'; when " " => cmd <= 'i'; rs <= '1'; when " " => cmd <= 'n'; rs <= '1'; when " " => cmd <= 'e'; rs <= '1'; when " " => cmd <= ' '; rs <= '1'; when " " => cmd <= '4'; rs <= '1'; when " " => cmd <= ';'; rs <= '1'; when " "|" "|" " => cmd <= ' '; rs <= '1'; when " " => cmd <= 'E'; rs <= '1'; when " " => cmd <= 'N'; rs <= '1'; when " " => cmd <= 'D'; rs <= '1'; -- UNCOMMENT one of the following 4 sections -- sequence of instructions for SHIFT --when " " => control <= x"3A"; rs <= '0'; -- DH=1: display shift enable --when " " => control <= x"3D"; rs <= '0'; -- RE=1: extended function set --when " " => control <= x"1B"; rs <= '0'; -- shift enable for lines 1,2 and 4 --when " " => control <= x"3A"; rs <= '0'; -- RE=0: function set --when " " => case dipswitch(1 downto 0) is -- when "01" => control <= x"1C"; rs <= '0'; -- shift display to the right -- when "10" => control <= x"18"; rs <= '0'; -- shift display to the left -- when others => control <= x"80"; rs <= '0'; -- display is unchanged -- end case; -- sequence of instructions for horizontal SCROLL ----when " " => control <= x"38"; rs <= '0'; -- DH=0: display scroll enable ----when " " => control <= x"3D"; rs <= '0'; -- RE=1: extended function set ----when " " => control <= x"19"; rs <= '0'; scroll_dots <= dipswitch(5 downto 0); -- scroll enable for lines 1 and 4 ----when " " => control <= "10" & scroll_dots; rs <= '0'; ----when " " => control <= x"3A"; rs <= '0'; -- RE=0: function set Line 1;……..End 1 The result of this sequence is Line 2;…########## Line 3; End 3 Line 4; END DIP switchers 5,4,3,2,1,0 specify the number of dots for scroll

21 Initialization on reset signal and power on
-- instruction for reverse display ------when " " => control <= x"3B"; rs <= '0'; -- reverse display -- sequence of instructions for BID mode when " " => control <= x"3D"; rs <= '0'; -- RE=1: extended function set when " " => control <= x"07"; rs <= '0'; -- set BID mode when " " => control <= x"3A"; rs <= '0'; -- RE=0 -- to cansel this sequence set BID bit (less significant bit in the second line) to 0 when others => control <= x"80"; rs <= '0';--cnt <= "000000"; end case; else -- initialization of LCD from the beginning case cnt is -- delay such as from "000000" to "001000" is important -- for satisfying LCD timing requirements when " " => control <= x"3c"; rs <= '0'; RE=1, 8 bits, 4 lines when " " => control <= x"09"; rs <= '0'; lines display mode (less significant bit to 1) when " " => control <= x"38"; rs <= '0'; RE=0 when " " => control <= x"0c"; rs <= '0'; display on, cursor off, cursor blink off when " " => control <= x"06"; rs <= '0'; -- Entry Mode Set (increment on, display shift off) when " " => control <= x"01"; rs <= '0'; Display Clear when " " => reset <= '0'; cnt <= " "; -- initialization is finished when others => null; end if; end process; end Behavioral; Initialization on reset signal and power on

22 There are 2 projects for ISE 5.2 that permit to test the
considered examples The file shift_LCD.zip includes project for the example 1 The file shift_LCD20.zip includes project for the example 2


Download ppt "Software Environment ISE 5.x Interaction with simple LCDs"

Similar presentations


Ads by Google