1 | -------------------------------------------------------------------
|
2 | -- ASCII HEX TABLE
|
3 | -- Hex Low Hex Digit
|
4 | -- Value 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
5 | ------\----------------------------------------------------------------
|
6 | --H 2 | SP ! " # $ % & ' ( ) * + , - . /
|
7 | --i 3 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
|
8 | --g 4 | @ A B C D E F G H I J K L M N O
|
9 | --h 5 | P Q R S T U V W X Y Z [ \ ] ^ _
|
10 | -- 6 | ` a b c d e f g h i j k l m n o
|
11 | -- 7 | p q r s t u v w x y z { | } ~ DEL
|
12 | -----------------------------------------------------------------------
|
13 |
|
14 | LIBRARY IEEE;
|
15 | USE IEEE.STD_LOGIC_1164.all;
|
16 | USE IEEE.STD_LOGIC_ARITH.all;
|
17 | USE IEEE.STD_LOGIC_UNSIGNED.all;
|
18 |
|
19 | entity lcd_control is
|
20 | port
|
21 | (
|
22 | trigger,trigger2, clk : in std_logic;
|
23 | ascii : in std_logic_vector(7 downto 0);
|
24 | lcd_rs, lcd_e, lcd_rw : out std_logic;
|
25 | lcd_data : out std_logic_vector(7 downto 0);
|
26 | lcd_an : out std_logic
|
27 |
|
28 | );
|
29 | end lcd_control;
|
30 |
|
31 | architecture behv of lcd_control is
|
32 |
|
33 | type state_type is ( START, START_WAIT, FUNC_SET_WAIT, DISP_ON_WAIT,
|
34 | DROP_E, HOLD,
|
35 | FUNC_SET, DISP_ON, DISP_CLEAR, MODE_SET,
|
36 | WAIT_CHAR, DISP_CLEAR_WAIT,
|
37 | WAIT_TRIGGER_RESET,
|
38 | CHK_CNT, LINE2, HOME);
|
39 |
|
40 | signal state, next_command : state_type;
|
41 | signal char_cnt : std_logic_vector(5 downto 0);
|
42 | signal wait_cnt : std_logic_vector(7 downto 0);
|
43 |
|
44 | begin
|
45 |
|
46 |
|
47 |
|
48 |
|
49 | process(clk)
|
50 | begin
|
51 |
|
52 | if trigger2='1' then -- a switch to turn the lcd on and off
|
53 | lcd_an<='1';
|
54 | lcd_rw<='0'; -- setting the rw permenantly to 1
|
55 | else
|
56 | lcd_an<='0';
|
57 | end if;
|
58 |
|
59 | state <= START;
|
60 |
|
61 | case state is
|
62 |
|
63 | when START =>
|
64 |
|
65 | lcd_e <= '1';
|
66 | lcd_rs <= '0';
|
67 | lcd_data <= X"38"; -- set the lcd to 8 bit lenght
|
68 | wait_cnt<=X"00";
|
69 | state <= DROP_E; -- function of DROP_E: just sets lcd_e to '1' and state goes to next_command
|
70 | next_command <= START_WAIT;
|
71 |
|
72 | when START_WAIT => -- waiting for a few msec
|
73 | if wait_cnt < X"10" then
|
74 | wait_cnt <= wait_cnt +1;
|
75 | state <= START_WAIT;
|
76 | else
|
77 | state <= FUNC_SET;
|
78 | wait_cnt <= X"00";
|
79 | end if;
|
80 |
|
81 |
|
82 |
|
83 | when FUNC_SET =>
|
84 | lcd_e <= '1';
|
85 | lcd_rs <= '0';
|
86 | lcd_data <= X"38";
|
87 | state <= DROP_E;
|
88 | next_command <= FUNC_SET_WAIT;
|
89 |
|
90 |
|
91 | when FUNC_SET_WAIT =>
|
92 | if wait_cnt < X"10" then
|
93 | wait_cnt <= wait_cnt +1;
|
94 | state <= FUNC_SET_WAIT;
|
95 | else
|
96 | state <= DISP_ON;
|
97 | wait_cnt <= X"00";
|
98 | end if;
|
99 |
|
100 |
|
101 |
|
102 | when DISP_ON =>
|
103 | lcd_e <= '1';
|
104 | lcd_rs <= '0';
|
105 | lcd_data <= X"0F"; -- set the lcd to Display on, Cursor is displayed, Blinking enable,
|
106 | state <= DROP_E;
|
107 | next_command <= DISP_ON_WAIT;
|
108 |
|
109 |
|
110 | when DISP_ON_WAIT =>
|
111 | if wait_cnt < X"10" then
|
112 | wait_cnt <= wait_cnt +1;
|
113 | state <= DISP_ON_WAIT;
|
114 | else
|
115 | state <= DISP_CLEAR;
|
116 | wait_cnt <= X"00";
|
117 | end if;
|
118 |
|
119 |
|
120 | when DISP_CLEAR =>
|
121 |
|
122 | lcd_e <= '1';
|
123 | lcd_rs <= '0';
|
124 | lcd_data <= X"01"; -- command: clear the display
|
125 | wait_cnt <= X"00";
|
126 | state <= DROP_E;
|
127 | next_command <= DISP_CLEAR_WAIT;
|
128 |
|
129 |
|
130 |
|
131 | when DISP_CLEAR_WAIT =>
|
132 |
|
133 | if wait_cnt < X"10" then
|
134 | wait_cnt <= wait_cnt +1;
|
135 | state <= DISP_CLEAR_WAIT;
|
136 | else
|
137 | state <= MODE_SET;
|
138 | wait_cnt <= X"00";
|
139 | end if;
|
140 |
|
141 | when MODE_SET =>
|
142 | lcd_e <= '1';
|
143 | lcd_rs <= '0';
|
144 | lcd_data <= X"06"; -- Cursor moves right, Display shift enabled.
|
145 | state <= DROP_E;
|
146 | next_command <= WAIT_CHAR;
|
147 |
|
148 | ---------------- initialization done, Loop of writing begins -------------------------------------------
|
149 |
|
150 | -- WAIT_CHAR -> DROP_E -> HOLD -> WAIT_TRIGGER_RESET -> CHK_CNT -> LINE2 -> DROP_E -> HOLD -> |
|
151 | -- | |
|
152 | -- ^ -> HOME -> DROP_E -> HOLD -> |
|
153 | -- | | |
|
154 | -- | v v
|
155 | -- |----------------------------------------<<-------------------------------------------|
|
156 |
|
157 | -------------------------------------------------------------------------------------------------
|
158 |
|
159 | when WAIT_CHAR =>
|
160 | if trigger = '0' then -- trigger is set to a switch
|
161 |
|
162 | lcd_e <= '1';
|
163 | lcd_rs <= '1';
|
164 | lcd_data <= ascii; -- ascii is defined through 7 switchs
|
165 | char_cnt <= char_cnt +1; -- a counter for the written letters
|
166 | state <= DROP_E;
|
167 | next_command <= WAIT_TRIGGER_RESET;
|
168 | else
|
169 | next_command <= WAIT_CHAR;
|
170 | end if;
|
171 |
|
172 | when WAIT_TRIGGER_RESET => -- loop, waiting for an change at the switch
|
173 | if trigger = '0' then
|
174 | state <= WAIT_TRIGGER_RESET;
|
175 | else
|
176 | state <= CHK_CNT;
|
177 | end if;
|
178 |
|
179 | when CHK_CNT => -- checking if the first line is full of letters,
|
180 | if char_cnt = X"10" then
|
181 | state <= LINE2;
|
182 | elsif char_cnt = X"20" then
|
183 | state <= HOME; -- clears the display
|
184 | else
|
185 | state <= WAIT_CHAR;
|
186 | end if;
|
187 |
|
188 |
|
189 | when LINE2 => -- starts writing at the secound line
|
190 | lcd_e <= '1';
|
191 | lcd_rs <= '0';
|
192 | lcd_data <= X"C0"; -- sets the DDRAM-Adress to '1000000'
|
193 | state <= DROP_E;
|
194 | next_command <= WAIT_CHAR;
|
195 |
|
196 | when HOME =>
|
197 | lcd_e <= '1';
|
198 | lcd_rs <= '0';
|
199 | lcd_data <= X"80"; -- sets the DDRAM-adress to '0000000'
|
200 | char_cnt <= "000000";
|
201 | state <= DROP_E;
|
202 | next_command <= WAIT_CHAR;
|
203 |
|
204 | when DROP_E =>
|
205 | lcd_e <= '1';
|
206 | state <= HOLD;
|
207 |
|
208 | when HOLD =>
|
209 | state <= next_command;
|
210 |
|
211 | end case;
|
212 |
|
213 | end process;
|
214 |
|
215 |
|
216 | end behv;
|