📄 lcd_display.vhd
字号:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL; --显示满屏淮;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY LCD_DISPLAY IS
GENERIC(N:INTEGER:=16;
DELAY:INTEGER:=2); --改了此延时,造成该情况发生!
PORT (
CLK : IN STD_LOGIC;
RESET:IN STD_LOGIC; --定义一个拔盘
LCDDA : OUT STD_LOGIC; --DI 输出
LCDRW : OUT STD_LOGIC; --RW 输出
LCDEN : OUT STD_LOGIC; --使能信号E
CS1,CS2:OUT STD_LOGIC; --片选信号
TEST : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) --输出
);
END LCD_DISPLAY;
ARCHITECTURE BEHAVIORAL OF LCD_DISPLAY IS
COMPONENT DATA_ROM --例化左区ROM
PORT(
INCLOCK:IN STD_LOGIC;
ADDRESS:IN STD_LOGIC_VECTOR(8 DOWNTO 0);
Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
COMPONENT DATA_ROM2 --例化右区ROM
PORT(
INCLOCK:IN STD_LOGIC;
ADDRESS:IN STD_LOGIC_VECTOR(8 DOWNTO 0);
Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
TYPE STATE IS (S0,S1,S2,S3,S4,S5,S6,S7); --定义状态
SIGNAL CURRENT_STATE:STATE;
SIGNAL CLKK:STD_LOGIC; --分频
SIGNAL DATA1:STD_LOGIC_VECTOR(7 DOWNTO 0); --输出左区ROM信号
SIGNAL DATA2:STD_LOGIC_VECTOR(7 DOWNTO 0); --输出右区ROM信号
SIGNAL COMMAND:STD_LOGIC_VECTOR(7 DOWNTO 0);--写入控制代码;
SIGNAL CNT2:STD_LOGIC_VECTOR(8 DOWNTO 0):="000000000"; --左区ROM地址计数器
SIGNAL CNT3:STD_LOGIC_VECTOR(8 DOWNTO 0):="000000000"; --右区ROM地址计数器
SIGNAL CNT4:STD_LOGIC_VECTOR(9 DOWNTO 0):="0000000000"; --全局计数器
SIGNAL S:STD_LOGIC_VECTOR(7 DOWNTO 0); --左区ROM输出
SIGNAL SL:STD_LOGIC_VECTOR(7 DOWNTO 0); --右区ROM输出
SIGNAL SIG:STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL REG:STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
U1:DATA_ROM PORT MAP(INCLOCK=>CLK,ADDRESS=>CNT2,Q=>S); --例化左区ROM
U2:DATA_ROM2 PORT MAP(INCLOCK=>CLK,ADDRESS=>CNT3,Q=>SL); --例化右区ROM
DIVIDER:PROCESS(CLK,RESET) --分频为1000HZ为1MS
VARIABLE CNT:STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
IF RESET='1' THEN
CNT:="00000000";
CLKK<='0';
ELSIF RISING_EDGE(CLK) THEN
CNT:=CNT+1;
CLKK<=CNT(4);
END IF;
END PROCESS DIVIDER;
CONTROL:PROCESS(CLKK,RESET,CURRENT_STATE)
VARIABLE CNTT:INTEGER;
BEGIN
IF RESET='1' THEN --复位信号初始化
CURRENT_STATE<=S0;
CNTT:=0;
CNT2<="000000000";
ELSIF RISING_EDGE(CLKK)THEN
CASE CURRENT_STATE IS
WHEN S0=> --检测BUSY位
LCDEN<='0';
LCDDA<='0';
LCDRW<='1';
CS1<='1';
SIG<="11";
CS2<='1';
IF CNT4
IF REG(7)='1' THEN
CURRENT_STATE<=S0;
ELSIF CNT2=16 OR CNT2=32 OR CNT2=48 OR CNT2=64 OR CNT2=80 OR CNT2=96 OR CNT2=112
OR CNT2=128 OR CNT2=144 OR CNT2=160 OR CNT2=176 OR CNT2=192 OR CNT2=208 OR CNT2=224
OR CNT2=240 OR CNT2=256 OR CNT2=272 OR CNT2=288 OR CNT2=304 OR CNT2=320 OR CNT2=336
OR CNT2=352 OR CNT2=368 OR CNT2=384 OR CNT2=400 OR CNT2=416 OR CNT2=432 OR CNT2=448
OR CNT2=464 OR CNT2=480 OR CNT2=496
OR CNT3=16 OR CNT3=32 OR CNT3=48 OR CNT3=64 OR CNT3=80 OR CNT3=96 OR CNT3=112
OR CNT3=128 OR CNT3=144 OR CNT3=160 OR CNT3=176 OR CNT3=192 OR CNT3=208 OR CNT3=224
OR CNT3=240 OR CNT3=256 OR CNT3=272 OR CNT3=288 OR CNT3=304 OR CNT3=320 OR CNT3=336
OR CNT3=352 OR CNT3=368 OR CNT3=384 OR CNT3=400 OR CNT3=416 OR CNT3=432 OR CNT3=448
OR CNT3=464 OR CNT3=480 OR CNT3=496 THEN
CURRENT_STATE<=S4;
ELSIF CNT2>0 THEN
CURRENT_STATE<=S6;
ELSIF CNT3>0 THEN
CURRENT_STATE<=S7;
ELSE CURRENT_STATE<=S1;
END IF;
WHEN S1=> --关显示设置;
LCDEN<='0';
LCDDA<='0';
LCDRW<='0';
CS1<='1';
CS2<='1';
SIG<="10";
COMMAND<="00111110";
------------*********延时100MS开始****************---------------
IF CNTT=DELAY AND CNTT<DELAY*2 THEN --DELAY=100 延时100MS
LCDEN<='1';
CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
IF CNTT=DELAY*2 THEN
CURRENT_STATE<=S2;
CNTT:=0;
END IF;
--------***********延时100MS结束************---------------
WHEN S2=> --开显示设置;
LCDEN<='0'; LCDDA<='0';
LCDRW<='0';CS1<='1';
CS2<='1';SIG<="10";
COMMAND<="00111111";
------------*********延时100MS开始****************---------------
IF CNTT=DELAY AND CNTT<DELAY*2 THEN --DELAY=100 延时100MS
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
IF CNTT=DELAY*2 THEN
CURRENT_STATE<=S3;
CNTT:=0;
END IF;
--------***********延时100MS结束************--------------------
WHEN S3=> --显示起始行设置;
LCDEN<='0';LCDDA<='0';
LCDRW<='0';CS1<='1';
CS2<='1';SIG<="10";
COMMAND<="11000000";
------------*********延时100MS开始****************---------------
IF CNTT=DELAY AND CNTT<DELAY*2 THEN --DELAY=100 延时100MS
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
IF CNTT=DELAY*2 THEN
CURRENT_STATE<=S4;
CNTT:=0;
END IF;
--------***********延时100MS结束************---------------------
WHEN S4=> --页面地址设置;
LCDEN<='0';
LCDDA<='0';
LCDRW<='0';
CS1<='1';
CS2<='1';
SIG<="10";
IF CNT2=32 OR CNT2=64 OR CNT2=96
OR CNT3=32 OR CNT3=64 OR CNT3=96 THEN --选择跳向第一页 B8
COMMAND<="10111000";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN --DELAY=100 延时100MS
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
ELSIF CNT2=16 OR CNT2=48 OR CNT2=80 OR CNT2=112
OR CNT3=16 OR CNT3=48 OR CNT3=80 OR CNT3=112 THEN --选择跳向第二页 B9
COMMAND<="10111001";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
ELSIF CNT2=128 OR CNT2=160 OR CNT2=192 OR CNT2=224
OR CNT3=128 OR CNT3=160 OR CNT3=192 OR CNT3=224 THEN
COMMAND<="10111010";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
ELSIF CNT2=144 OR CNT2=176 OR CNT2=208 OR CNT2=240
OR CNT3=144 OR CNT3=176 OR CNT3=208 OR CNT3=240 THEN
COMMAND<="10111011";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
ELSIF CNT2=256 OR CNT2=288 OR CNT2=320 OR CNT2=352
OR CNT3=256 OR CNT3=288 OR CNT3=320 OR CNT3=352 THEN
COMMAND<="10111100";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
ELSIF CNT2=272 OR CNT2=304 OR CNT2=336 OR CNT2=368
OR CNT3=272 OR CNT3=304 OR CNT3=336 OR CNT3=368 THEN
COMMAND<="10111101";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
ELSIF CNT2=384 OR CNT2=416 OR CNT2=448 OR CNT2=480
OR CNT3=384 OR CNT3=416 OR CNT3=448 OR CNT3=480 THEN
COMMAND<="10111110";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
ELSIF CNT2=400 OR CNT2=432 OR CNT2=464 OR CNT2=496
OR CNT3=400 OR CNT3=432 OR CNT3=464 OR CNT3=496 THEN
COMMAND<="10111111";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
ELSIF CNT3=0 OR CNT2=0 THEN ---------特殊情况;
COMMAND<="10111000";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
END IF; --选页结束
IF CNTT=DELAY*2 THEN
CURRENT_STATE<=S5;
CNTT:=0;
END IF;
WHEN S5=> --列地址设置;
LCDEN<='0';LCDDA<='0';
LCDRW<='0';CS1<='1';
CS2<='1';SIG<="10";
IF CNT2=16 OR CNT3=128 OR CNT3=144 OR CNT3=16 OR CNT3=128 OR CNT3=144 OR
CNT2=256 OR CNT2=272 OR CNT2=384 OR CNT2=400 OR CNT3=256 OR CNT3=272 OR CNT3=384 OR CNT3=400 THEN
COMMAND<="01000000";
------------*********延时100MS开始****************---------------
IF CNTT=DELAY AND CNTT<DELAY*2 THEN --DELAY=100 延时100MS
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
--------***********延时100MS结束************---------------
ELSIF CNT2=32 OR CNT2=48 OR CNT2=160 OR CNT2=176 OR CNT3=32 OR CNT3=48 OR CNT3=160 OR CNT3=176
OR CNT2=288 OR CNT2=304 OR CNT2=416 OR CNT2=432 OR CNT3=288 OR CNT3=304 OR
CNT3=416 OR CNT3=432 THEN
COMMAND<="01010000";
IF CNTT=DELAY OR CNTT<DELAY*2 THEN--延时开始;
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF; --延时结束;
ELSIF CNT2=64 OR CNT2=80 OR CNT2=192 OR CNT2=208 OR CNT3=64 OR CNT3=80 OR CNT3=192 OR CNT3=208
OR CNT2=320 OR CNT2=336 OR CNT2=448 OR CNT2=464 OR CNT3=320 OR CNT3=336 OR CNT3=448 OR CNT3=464
THEN
COMMAND<="01100000";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN--延时开始;
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF; --延时结束;
ELSIF CNT2=96 OR CNT2=112 OR CNT2=224 OR CNT2=240 OR CNT3=96 OR CNT3=112 OR CNT3=224 OR CNT3=240
OR CNT2=352 OR CNT2=368 OR CNT2=480 OR CNT2=496 OR CNT3=352 OR CNT3=368 OR CNT3=480 OR CNT3=496
THEN
COMMAND<="01110000";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN------延时开始;
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';
CNTT:=CNTT+1;
END IF; -------延时结束;
ELSIF CNT2=0 OR CNT3=0 THEN -----------特殊情况;
COMMAND<="01000000";
IF CNTT=DELAY AND CNTT<DELAY*2 THEN-----延时开始;
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';
CNTT:=CNTT+1;
END IF; --延时结束;
END IF;
IF CNTT=DELAY*2 THEN
IF CNT4<511 THEN
CURRENT_STATE<=S6;
ELSE CURRENT_STATE<=S7;
END IF;
CNTT:=0;
END IF;
WHEN S6=> --写左区数据
LCDEN<='0';
LCDDA<='1';
CS1<='1';
CS2<='0';
LCDRW<='0';
SIG<="01";
DATA1<=S;
------------*********延时100MS开始****************---------------
IF CNTT=DELAY AND CNTT<DELAY*2 THEN --DELAY=100 延时100MS
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
IF CNTT=DELAY*2 THEN
CNTT:=0;
IF CNT2=511 THEN
CNT2<="000000000";
CURRENT_STATE<=S0;
ELSE
CURRENT_STATE<=S0;
CNT2<=CNT2+1;
CNT4<=CNT4+1;
END IF;
END IF;
-----------***********延时100MS结束************--------------------
WHEN S7=> --写右区数据
LCDEN<='0';
LCDDA<='1';
CS1<='0';
CS2<='1';
LCDRW<='0';
SIG<="00";
DATA2<=SL;
IF CNTT=DELAY AND CNTT<DELAY*2 THEN --DELAY=100 延时100MS
LCDEN<='1';CNTT:=CNTT+1;
ELSE LCDEN<='0';CNTT:=CNTT+1;
END IF;
IF CNTT=DELAY*2 THEN
CNTT:=0;
IF CNT3=511 THEN
CNT3<="000000000";
CNT4<="0000000000";
CURRENT_STATE<=S0;
ELSE
CURRENT_STATE<=S0;
CNT3<=CNT3+1;
CNT4<=CNT4+1;
END IF;
END IF;
END CASE;
END IF;
END PROCESS;
TEST<=DATA1 WHEN SIG="01" ELSE
DATA2 WHEN SIG="00" ELSE
COMMAND WHEN SIG="10";
REG<=TEST WHEN SIG="11" ELSE
"00000000";
END BEHAVIORAL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -