这个程序是用VHDL编写的,直接上程序了:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY LC IS
PORT(RS,RW:OUT STD_LOGIC;
ENA:OUT STD_LOGIC;
CLK:IN STD_LOGIC;
DATA:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END LC;
ARCHITECTURE ARC OF LC IS
SIGNAL CLKF:STD_LOGIC:='0';
SIGNAL CLKEN:STD_LOGIC:='0';
SIGNAL OCEN1:BOOLEAN:=FALSE;
SIGNAL OCEN2:BOOLEAN:=FALSE;
--SIGNAL ENCO:BOOLEAN:=FALSE;
BEGIN
PROCESS(CLK) --分频,所分的的频率为其他操作执行的最小时间 1ms左右
VARIABLE COUNT:INTEGER RANGE 0 TO 25000:=0;
BEGIN
IF(CLK'EVENT AND CLK='1')THEN
IF(COUNT<=12500) THEN
COUNT:=COUNT+1;
ELSE
COUNT:=0;
CLKF<=NOT CLKF;
END IF;
END IF;
END PROCESS;
PROCESS(CLK) --分频,这个clken信号用来维持rw、rs信号与enable信号的最小建立时间 (100ns下)
VARIABLE COUNT:INTEGER RANGE 0 TO 5:=0;
BEGIN
IF(CLK'EVENT AND CLK='1')THEN
IF(COUNT<3)THEN
COUNT:=COUNT+1;
ELSE
COUNT:=0;
CLKEN<=NOT CLKEN;
END IF;
END IF;
END PROCESS;
PROCESS(CLKEN,OCEN1,OCEN2) --单独用此进程来控制enable信号也是为了搭配上一个进程,建立一个符合时需要求的最小 地址建立时间、地址保持时间
BEGIN
IF(CLKEN'EVENT AND CLKEN='1')THEN
IF(OCEN1=TRUE)THEN
ENA<='1';
-- ENCO<=FALSE;
END IF;
IF(OCEN2=TRUE)THEN
ENA<='0';
-- ENCO<=TRUE;
END IF;
END IF;
END PROCESS;
INITIAL:PROCESS(CLKF) --通过case语句及相关变量(入syb)来进行初始化和最后的数据输入
VARIABLE SYB:INTEGER RANGE 0 TO 15:=0; --标志应该为哪一步初始动作
VARIABLE COUNT:INTEGER RANGE 0 TO 6:=0;
VARIABLE BZYN:BOOLEAN:=FALSE;
BEGIN
IF(CLKF'EVENT AND CLKF='1')THEN --时钟触发
CASE SYB IS
WHEN 0=> --初始话命令38H
IF(COUNT<=5)THEN --要count《=5的目的在于让此步骤维持5ms以上
RW<='0';
RS<='0';
DATA<="00111000";
OCEN1<=TRUE; --触发进程,使enable信号变高,当然,由于使用了专门的进程来控制enable,所以rs、rw会比enable早80ns左右
OCEN2<=FALSE;
COUNT:=COUNT+1;
ELSE
OCEN1<=FALSE; --enable变为低
OCEN2<=TRUE;
SYB:=1; --标志变为1
COUNT:=0;
END IF;
WHEN 1=>
IF(COUNT<=5)THEN --同上,再次进行5ms的38H的命令写入
RW<='0';
RS<='0';
DATA<="00111000";
OCEN1<=TRUE;
OCEN2<=FALSE;
COUNT:=COUNT+1;
ELSE
OCEN1<=FALSE;
OCEN2<=TRUE;
SYB:=2;
COUNT:=0;
END IF;
WHEN 2=> --进行一次38H命令写入
IF(COUNT<1)THEN
RW<='0';
RS<='0';
COUNT:=1;
DATA<="00111000";
OCEN1<=TRUE;
OCEN2<=FALSE;
ELSE
OCEN2<=TRUE;
OCEN1<=FALSE;
COUNT:=0;
SYB:=3;
BZYN:=FALSE;
END IF;
WHEN 3=> --进行一次有检测data(7)忙的38H命令写入
IF(COUNT<2)THEN
IF(BZYN=FALSE)THEN
RS<='0'; --进行读状态操作
RW<='1';
DATA(7)<='1';
OCEN1<=TRUE;
OCEN2<=FALSE;
BZYN:=TRUE;
ELSE
IF(DATA(7)='0')THEN --检测data(7)
IF(COUNT=0)THEN
OCEN2<=TRUE; --在得知不忙后,进行一次enable信号拉低操作
OCEN1<=FALSE;
COUNT:=1;
ELSE
RS<='0'; --38H
RW<='0';
DATA<="00111000";
OCEN1<=TRUE;
OCEN2<=FALSE;
COUNT:=2;
END IF;
END IF;
END IF;
ELSE
SYB:=4;
BZYN:=FALSE;
COUNT:=0;
OCEN1<=FALSE; --在使用完enable后,将它拉低
OCEN2<=TRUE;
END IF;
WHEN 4=> --写入08H命令
IF(COUNT<2)THEN
IF(BZYN=FALSE)THEN
RS<='0';
RW<='1';
DATA(7)<='1';
OCEN1<=TRUE;
OCEN2<=FALSE;
BZYN:=TRUE;
ELSE
IF(DATA(7)='0')THEN
IF(COUNT=0)THEN
OCEN2<=TRUE;
OCEN1<=FALSE;
COUNT:=1;
ELSE
RS<='0';
RW<='0';
DATA<="00001000";
OCEN1<=TRUE;
OCEN2<=FALSE;
COUNT:=2;
END IF;
END IF;
END IF;
ELSE
SYB:=5;
BZYN:=FALSE;
COUNT:=0;
OCEN2<=TRUE;
OCEN1<=FALSE;
END IF;
WHEN 5=> --写入01H命令
IF(COUNT<2)THEN
IF(BZYN=FALSE)THEN
RS<='0';
RW<='1';
DATA(7)<='1';
OCEN1<=TRUE;
OCEN2<=FALSE;
BZYN:=TRUE;
ELSE
IF(DATA(7)='0')THEN
IF(COUNT=0)THEN
OCEN2<=TRUE;
OCEN1<=FALSE;
COUNT:=1;
ELSE
RS<='0';
RW<='0';
DATA<="00000001";
OCEN1<=TRUE;
OCEN2<=FALSE;
COUNT:=2;
END IF;
END IF;
END IF;
ELSE
SYB:=6;
BZYN:=FALSE;
COUNT:=0;
OCEN2<=TRUE;
OCEN1<=FALSE;
END IF;
WHEN 6=> -- 写入06H命令
IF(COUNT<2)THEN
IF(BZYN=FALSE)THEN
RS<='0';
RW<='1';
DATA(7)<='1';
OCEN1<=TRUE;
OCEN2<=FALSE;
BZYN:=TRUE;
ELSE
IF(DATA(7)='0')THEN
IF(COUNT=0)THEN
OCEN2<=TRUE;
OCEN1<=FALSE;
COUNT:=1;
ELSE
RS<='0';
RW<='0';
DATA<="00000110";
OCEN1<=TRUE;
OCEN2<=FALSE;
COUNT:=2;
END IF;
END IF;
END IF;
ELSE
SYB:=7;
BZYN:=FALSE;
OCEN2<=TRUE;
OCEN1<=FALSE;
COUNT:=0;
END IF;
WHEN 7=> 写入0fH命令
IF(COUNT<2)THEN
IF(BZYN=FALSE)THEN
RS<='0';
RW<='1';
DATA(7)<='1';
OCEN1<=TRUE;
OCEN2<=FALSE;
BZYN:=TRUE;
ELSE
IF(DATA(7)='0')THEN
IF(COUNT=0)THEN
OCEN2<=TRUE;
OCEN1<=FALSE;
COUNT:=1;
ELSE
RS<='0';
RW<='0';
DATA<="00001111";
OCEN1<=TRUE;
OCEN2<=FALSE;
COUNT:=2;
END IF;
END IF;
END IF;
ELSE
SYB:=8;
BZYN:=FALSE;
COUNT:=0;
OCEN2<=TRUE;
OCEN1<=FALSE;
END IF;
WHEN 8=> --写入ddram地址0000000h
IF(COUNT<2)THEN
IF(BZYN=FALSE)THEN
RS<='0';
RW<='1';
DATA(7)<='1';
OCEN1<=TRUE;
OCEN2<=FALSE;
BZYN:=TRUE;
ELSE
IF(DATA(7)='0')THEN
IF(COUNT=0)THEN
OCEN2<=TRUE;
OCEN1<=FALSE;
COUNT:=1;
ELSE
RS<='0';
RW<='0';
DATA<="10000000";
OCEN1<=TRUE;
OCEN2<=FALSE;
COUNT:=2;
END IF;
END IF;
END IF;
ELSE
BZYN:=FALSE;
COUNT:=0;
OCEN2<=TRUE;
OCEN1<=FALSE;
SYB:=9;
END IF;
WHEN 9=> --写入数据38H,以后循环此
IF(COUNT<2)THEN
IF(BZYN=FALSE)THEN
RS<='0';
RW<='1';
DATA(7)<='1';
OCEN1<=TRUE;
OCEN2<=FALSE;
BZYN:=TRUE;
ELSE
IF(DATA(7)='0')THEN
IF(COUNT=0)THEN
OCEN2<=TRUE;
OCEN1<=FALSE;
COUNT:=1;
ELSE
RS<='1';
RW<='0';
COUNT:=2;
DATA<="01000001";
OCEN1<=TRUE;
OCEN2<=FALSE;
END IF;
END IF;
END IF;
ELSE
BZYN:=FALSE;
COUNT:=0;
OCEN2<=TRUE;
OCEN1<=FALSE;
END IF;
WHEN OTHERS=>OCEN2<=TRUE; --异常处理
OCEN1<=FALSE;
END CASE;
END IF;
END PROCESS INITIAL;
END ARC;
最后在实验板上跑出来的结果不是高一行没显示,第一行全黑,就是两行都没显示,我用的是cycloneII的EP2C8Q208C8,ps,在quartus上仿时序没有错误啊,汗。。。
希望高人前来踢场子