OpenCores
URL https://opencores.org/ocsvn/z80soc/z80soc/trunk

Subversion Repositories z80soc

[/] [z80soc/] [trunk/] [V0.7.3/] [DE2115/] [vhdl/] [lcd.vhd] - Blame information for rev 46

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 46 rrred
-- VHDL CODE by Gerry O'Brien - HD44780 LCD Controller STATE_MACHINE
2
--==================================================--
3
--
4
-- VHDL Architecture DE2_LCD_lib.TOP_LCD_DE2.LCD_DISPLAY_arch
5
--
6
-- Created:
7
--          by - Gerry O'Brien 
8
--          WWW.DIGITAL-CIRCUITRY.COM
9
--          at - 15:30:18 26/03/2015
10
-- 
11
-- using Mentor Graphics HDL Designer(TM) 2010.3 (Build 21)
12
--
13
LIBRARY IEEE;
14
USE  IEEE.STD_LOGIC_1164.all;
15
USE  IEEE.STD_LOGIC_ARITH.all;
16
USE  IEEE.STD_LOGIC_UNSIGNED.all;
17
 
18
 
19
ENTITY LCD IS
20
 
21
   PORT(
22
                reset             : IN     std_logic;  -- Map this Port to a Switch within your [Port Declarations / Pin Planer]  
23
                CLOCK_50          : IN     std_logic;  -- Using the DE2 50Mhz Clk, in order to Genreate the 400Hz signal... clk_count_400hz reset count value must be set to:  <= x"0F424"
24
                LCD_RS            : OUT    std_logic;
25
                LCD_EN            : OUT    std_logic;
26
                LCD_RW            : OUT    std_logic;
27
                LCD_ON            : OUT    std_logic;
28
                LCD_BLON          : OUT    std_logic;
29
                LCD_DATA          : INOUT       STD_LOGIC_VECTOR(7 DOWNTO 0);
30
                lcd_on_sig                : IN          STD_LOGIC;
31
                next_char                 : IN          STD_LOGIC_VECTOR(7 DOWNTO 0);
32
                char_count        : OUT         STD_LOGIC_VECTOR(4 downto 0);
33
                clk400hz              : OUT             STD_LOGIC
34
   );
35
 
36
END LCD ;
37
 
38
--
39
ARCHITECTURE RTL OF LCD IS
40
 
41
  type state_type is (hold, func_set, display_on, mode_set, print_string,
42
                      line2, return_home, drop_LCD_EN, reset1, reset2,
43
                       reset3, display_off, display_clear);
44
 
45
  signal state, next_command         : state_type;
46
 
47
  signal data_bus_value                          : STD_LOGIC_VECTOR(7 downto 0);
48
  signal clk_count_400hz             : STD_LOGIC_VECTOR(19 downto 0);
49
  signal char_count_sig              : STD_LOGIC_VECTOR(4 downto 0);
50
  signal clk_400hz_enable,LCD_RW_int : std_logic;
51
  signal data_bus                    : STD_LOGIC_VECTOR(7 downto 0);
52
  signal LCD_CHAR_ARRAY              : STD_LOGIC_VECTOR(3 DOWNTO 0);
53
 
54
BEGIN
55
 
56
LCD_DATA        <= data_bus;
57
data_bus        <= data_bus_value when LCD_RW_int = '0' else "ZZZZZZZZ";
58
LCD_RW          <= LCD_RW_int;
59
char_count      <= char_count_sig;
60
clk400hz                <= clk_400hz_enable;
61
 
62
--======================= CLOCK SIGNALS ============================--  
63
process(CLOCK_50)
64
begin
65
      if (rising_edge(CLOCK_50)) then
66
         if (reset = '0') then
67
            clk_count_400hz <= x"00000";
68
            clk_400hz_enable <= '0';
69
         else
70
            if (clk_count_400hz <= x"0F424") then          -- If using the DE2 50Mhz Clock,  use clk_count_400hz <= x"0F424"  (50Mhz/400hz = 12500 converted to HEX = 0F424 )   
71
                   clk_count_400hz <= clk_count_400hz + 1; --  In Theory for a 27Mhz Clock,  use clk_count_400hz <= x"01A5E"  (27Mhz/400hz = 6750  converted to HEX = 01A5E )                                       
72
                   clk_400hz_enable <= '0';                --  In Theory for a 25Mhz Clock.  use clk_count_400hz <= x"0186A"  (25Mhz/400hz = 6250  converted to HEX = 0186A )
73
            else
74
                   clk_count_400hz <= x"00000";
75
                   clk_400hz_enable <= '1';
76
            end if;
77
         end if;
78
      end if;
79
end process;
80
--==================================================================--    
81
 
82
--======================== LCD DRIVER CORE ==============================--   
83
--                     STATE MACHINE WITH RESET                          -- 
84
--===================================================-----===============--  
85
process (CLOCK_50, reset)
86
begin
87
        if reset = '0' then
88
           state <= reset1;
89
           data_bus_value <= x"38"; -- RESET
90
           next_command <= reset2;
91
           LCD_EN <= '1';
92
           LCD_RS <= '0';
93
           LCD_RW_int <= '0';
94
 
95
        elsif rising_edge(CLOCK_50) then
96
             if clk_400hz_enable = '1' then
97
 
98
 
99
 
100
              --========================================================--                 
101
              -- State Machine to send commands and data to LCD DISPLAY
102
              --========================================================--
103
                 case state is
104
                 -- Set Function to 8-bit transfer and 2 line display with 5x8 Font size
105
                 -- see Hitachi HD44780 family data sheet for LCD command and timing details
106
 
107
 
108
 
109
--======================= INITIALIZATION START ============================--
110
                       when reset1 =>
111
                            LCD_EN <= '1';
112
                            LCD_RS <= '0';
113
                            LCD_RW_int <= '0';
114
                            data_bus_value <= x"38"; -- EXTERNAL RESET
115
                            state <= drop_LCD_EN;
116
                            next_command <= reset2;
117
                            char_count_sig <= "00000";
118
 
119
                       when reset2 =>
120
                            LCD_EN <= '1';
121
                            LCD_RS <= '0';
122
                            LCD_RW_int <= '0';
123
                            data_bus_value <= x"38"; -- EXTERNAL RESET
124
                            state <= drop_LCD_EN;
125
                            next_command <= reset3;
126
 
127
                       when reset3 =>
128
                            LCD_EN <= '1';
129
                            LCD_RS <= '0';
130
                            LCD_RW_int <= '0';
131
                            data_bus_value <= x"38"; -- EXTERNAL RESET
132
                            state <= drop_LCD_EN;
133
                            next_command <= func_set;
134
 
135
 
136
                       -- Function Set
137
                       --==============--
138
                       when func_set =>
139
                            LCD_EN <= '1';
140
                            LCD_RS <= '0';
141
                            LCD_RW_int <= '0';
142
                            data_bus_value <= x"38";  -- Set Function to 8-bit transfer, 2 line display and a 5x8 Font size
143
                            state <= drop_LCD_EN;
144
                            next_command <= display_off;
145
 
146
 
147
 
148
                       -- Turn off Display
149
                       --==============-- 
150
                       when display_off =>
151
                            LCD_EN <= '1';
152
                            LCD_RS <= '0';
153
                            LCD_RW_int <= '0';
154
                            data_bus_value <= x"08"; -- Turns OFF the Display, Cursor OFF and Blinking Cursor Position OFF.......(0F = Display ON and Cursor ON, Blinking cursor position ON)
155
                            state <= drop_LCD_EN;
156
                            next_command <= display_clear;
157
 
158
 
159
                       -- Clear Display 
160
                       --==============--
161
                       when display_clear =>
162
                            LCD_EN <= '1';
163
                            LCD_RS <= '0';
164
                            LCD_RW_int <= '0';
165
                            data_bus_value <= x"01"; -- Clears the Display    
166
                            state <= drop_LCD_EN;
167
                            next_command <= display_on;
168
 
169
 
170
 
171
                       -- Turn on Display and Turn off cursor
172
                       --===================================--
173
                       when display_on =>
174
                            LCD_EN <= '1';
175
                            LCD_RS <= '0';
176
                            LCD_RW_int <= '0';
177
                            data_bus_value <= x"0C"; -- Turns on the Display (0E = Display ON, Cursor ON and Blinking cursor OFF) 
178
                            state <= drop_LCD_EN;
179
                            next_command <= mode_set;
180
 
181
 
182
                       -- Set write mode to auto increment address and move cursor to the right
183
                       --====================================================================--
184
                       when mode_set =>
185
                            LCD_EN <= '1';
186
                            LCD_RS <= '0';
187
                            LCD_RW_int <= '0';
188
                            data_bus_value <= x"06"; -- Auto increment address and move cursor to the right
189
                            state <= drop_LCD_EN;
190
                            next_command <= print_string;
191
 
192
 
193
--======================= INITIALIZATION END ============================--                          
194
 
195
 
196
 
197
 
198
--=======================================================================--                           
199
--               Write ASCII hex character Data to the LCD
200
--=======================================================================--
201
                       when print_string =>
202
                            state <= drop_LCD_EN;
203
                            LCD_EN <= '1';
204
                            LCD_RS <= '1';
205
                            LCD_RW_int <= '0';
206
 
207
 
208
                               -- ASCII character to output
209
                               if (next_char(7 downto 4) /= x"0") then
210
                                  data_bus_value <= next_char;
211
                               else
212
 
213
                                    -- Convert 4-bit value to an ASCII hex digit
214
                                    if next_char(3 downto 0) >9 then
215
 
216
                                    -- ASCII A...F
217
                                      data_bus_value <= x"4" & (next_char(3 downto 0)-9);
218
                                    else
219
 
220
                                    -- ASCII 0...9
221
                                      data_bus_value <= x"3" & next_char(3 downto 0);
222
                                    end if;
223
                               end if;
224
 
225
                            state <= drop_LCD_EN;
226
 
227
 
228
 
229
                            -- Loop to send out 32 characters to LCD Display (16 by 2 lines)
230
                               if (char_count_sig < 31) AND (next_char /= x"fe") then
231
                                   char_count_sig <= char_count_sig +1;
232
                               else
233
                                   char_count_sig <= "00000";
234
                               end if;
235
 
236
 
237
 
238
                            -- Jump to second line?
239
                               if char_count_sig = 15 then
240
                                  next_command <= line2;
241
 
242
 
243
 
244
                            -- Return to first line?
245
                               elsif (char_count_sig = 31) or (next_char = x"fe") then
246
                                     next_command <= return_home;
247
                               else
248
                                     next_command <= print_string;
249
                               end if;
250
 
251
 
252
 
253
                       -- Set write address to line 2 character 1
254
                       --======================================--
255
                       when line2 =>
256
                            LCD_EN <= '1';
257
                            LCD_RS <= '0';
258
                            LCD_RW_int <= '0';
259
                            data_bus_value <= x"c0";
260
                            state <= drop_LCD_EN;
261
                            next_command <= print_string;
262
 
263
 
264
                       -- Return write address to first character position on line 1
265
                       --=========================================================--
266
                       when return_home =>
267
                            LCD_EN <= '1';
268
                            LCD_RS <= '0';
269
                            LCD_RW_int <= '0';
270
                            data_bus_value <= x"80";
271
                            state <= drop_LCD_EN;
272
                            next_command <= print_string;
273
 
274
 
275
 
276
                       -- The next states occur at the end of each command or data transfer to the LCD
277
                       -- Drop LCD E line - falling edge loads inst/data to LCD controller
278
                       --============================================================================--
279
                       when drop_LCD_EN =>
280
                            LCD_EN <= '0';
281
                            state <= hold;
282
 
283
                       -- Hold LCD inst/data valid after falling edge of E line
284
                       --====================================================--
285
                       when hold =>
286
                            state <= next_command;
287
                            LCD_BLON <= '1';
288
                                                                         LCD_ON <= lcd_on_sig;
289
                       end case;
290
 
291
 
292
 
293
 
294
             end if;-- CLOSING STATEMENT FOR "IF clk_400hz_enable = '1' THEN"
295
 
296
      end if;-- CLOSING STATEMENT FOR "IF reset = '0' THEN" 
297
 
298
end process;
299
 
300
END ARCHITECTURE RTL;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.