首页 > 技术支持 > EEPROM 存储器

汉字显示程序设计

Victor Lee (WHUT)

设计汉字显示的控制器,读取EEPROM(ATMEL AT28C64B)中存储的汉字显示的数据,并在16*16的点阵上面显示出来,可以一个个字的显示和移动的显示。EEPROM工作速度在6.6M左右,所以我选取2.5M的时钟,关键在于设置地址读取信号,当地址线低5位从00000计数到11111刚好读出一个汉字,因此高7位就是汉字的位置。因为每次要读出16位的data,因此在低0位的时候读取的数据送到LED的低8位,在1位的时候读取的数据送到高8位,同时,将扫描信号和地址线的4~1位相同,这样,扫描一次就可以读取16位数据。于2005年5月25日设计完成,同时还要注意CPLD上面的引脚有些没有标的就不要用,程序设计如下:

------------------------------------------------------------

----------------------------------------------

--2005.05.25 ver0.1(done perfect)

--name:word show on the 16*16 led

--note:read data from the EEPROM 2864

--author:Victor Lee (WHUT)

----------------------------------------------

LIBRARY IEEE;

USE IEEE.Std_Logic_1164.ALL;

USE IEEE.Std_Logic_Arith.ALL;

USE IEEE.Std_Logic_Unsigned.ALL;

ENTITY e2prom IS

PORT(clk:IN STD_LOGIC; --FOR SYSTEM CLOCK 10Mhz

enc:IN STD_LOGIC;--FOR CPLD DATA OUT ENABLE

rst:IN STD_LOGIC;--FOR CPLD RESET

oer:OUT STD_LOGIC;--FOR EEPROM READ ENABLE,'0' are valid

cer:OUT STD_LOGIC;-FOR EEPROM CHIP SELECT ENABLE,'0' are valid

wer:OUT STD_LOGIC;--FOR EEPROM WRITE ENABLE,'0' are valid

led:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);

addr:OUT STD_LOGIC_VECTOR(11 DOWNTO 0);

--ADDRESS LOWER 4 DOWNTO 1 IS THE SCAN SIGNAL

--ADDRESS FOR THE EEPROM TO GET THE DATA

datar:IN STD_LOGIC_VECTOR(7 DOWNTO 0)); --DATAOUT FROM EEPROM

END e2prom;

ARCHITECTURE be OF e2prom IS

SIGNAL q:STD_LOGIC_VECTOR(18 DOWNTO 0);

SIGNAL d:STD_LOGIC_VECTOR(15 DOWNTO 0);--FOR SAVE DATA

SIGNAL ocr:STD_LOGIC;

SIGNAL sclk:STD_LOGIC;

SIGNAL counterh:STD_LOGIC_VECTOR(11 DOWNTO 5);

SIGNAL counterl:STD_LOGIC_VECTOR(4 DOWNTO 0);--ADDR

BEGIN

Free_Counter:BLOCK

BEGIN

PROCESS(clk)

BEGIN

IF clk'event AND clk='1' THEN

q<=q+1;

END IF;

END PROCESS;

sclk<=q(5);--for addr lower counter

cer<=ocr;

led<=d;

addr<=counterh&counterl;

END BLOCK Free_Counter;

Addressl:BLOCK --for a word read out

BEGIN

PROCESS(sclk,rst)

BEGIN

IF rst='1' THEN

counterl<="00000";

ELSIF sclk'event AND sclk='1' THEN

IF counterl="11111" THEN

counterl<="00000";

ELSE

counterl<=counterl+1;

END IF;

END IF;

END PROCESS;

END BLOCK Addressl;

Addressh:BLOCK--for word sel

BEGIN

PROCESS(q(18),rst,d(0))

BEGIN

IF rst='1' OR d(0)='1' THEN

counterh<="0000000";

ELSIF q(18)'event AND q(18)='1' THEN

IF enc='1' THEN

counterh<=counterh+1;

ELSE

counterh<=counterh;

END IF;

END IF;

END PROCESS;

END BLOCK Addressh;

Control_EEPROM:BLOCK

BEGIN

wer<='1';

PROCESS(clk,rst,sclk)

BEGIN

IF rst='1' THEN

oer<='1';

ocr<='1';

ELSE

oer<=not sclk;

ocr<=not sclk;

END IF;

END PROCESS;

END BLOCK Control_EEPROM;

Data:BLOCK

BEGIN

PROCESS(rst,clk)

BEGIN

IF rst='1' THEN

d<="0000000000000000";

ELSIF clk'event AND clk='1' THEN

IF counterl(0)='1' THEN

d(7 DOWNTO 0)<=datar;

d(15 DOWNTO 8)<="00000000";

ELSIF counterl(0)='0' THEN

d(15 DOWNTO 8)<=datar;

d(7 DOWNTO 0)<="00000000";

END IF;

END IF;

END PROCESS;

END BLOCK Data;

END be;

-----------------------------------------

现在需要完成的时动态显示,即滚动显示。

可以考虑在数据读出的时候,扫描信号不与数据信号对应,根据设置的频率进行改变。

滚动显示于2005.05.27日设计完毕,略微有些不足,在时序上面还需要多下功夫。可能是时序问题导致在显示“这是”和“谢谢”的时候会出现data为全FF的情况,使得无法通过判断d(0)是否是1来决定是否显示结束。而在以前静态显示的时候是可以的。多分析了一下时序,出现问题的地方少多了

addrl .00000.00001.00010.00011.00100.00101.00110.00111.

sclk ___---___---___---___---___---___---___---___---

ocr _---___---___---___---___---___---___---___---___---___

data .data1.data2.data3.data4.data5

scan xxx__-------------__________-------------__________

所以当时钟设置好以后,以ocr的上沿读取数据就是准确的

全部例程及相关解释如下:

----------------------------------------------

--2005.05.25 ver0.1(done perfect)

--name:word show on the 16*16 led

--note:read data from the EEPROM 2864

--author:Victor Lee (WHUT)

----------------------------------------------

LIBRARY IEEE;

USE IEEE.Std_Logic_1164.ALL;

USE IEEE.Std_Logic_Arith.ALL;

USE IEEE.Std_Logic_Unsigned.ALL;

ENTITY e2prom IS

GENERIC(word:integer:=37);--FOR word count

PORT( clk:IN STD_LOGIC;--FOR SYSTEM CLOCK 10Mhz

enc:IN STD_LOGIC;--FOR CPLD DATA OUT ENABLE

rst:IN STD_LOGIC;--FOR CPLD RESET

oer:OUT STD_LOGIC;--FOR EEPROM READ ENABLE,'0' are valid

cer:OUT STD_LOGIC;--FOR EEPROM CHIP SELECT ENABLE,'0' are valid

wer:OUT STD_LOGIC;--FOR EEPROM WRITE ENABLE,'0' are valid

led:OUT STD_LOGIC_VECTOR(15 DOWNTO 0);--TO SAVE THE PIN,JUST SHOW A HALF AT A TIME

addr:OUT STD_LOGIC_VECTOR(11 DOWNTO 0);

--ADDRESS FOR THE EEPROM TO GET THE DATA

enscroll:IN STD_LOGIC;

scan:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--for row scan

datar:IN STD_LOGIC_VECTOR(7 DOWNTO 0)); --DATAOUT FROM EEPROM

END e2prom;

ARCHITECTURE be OF e2prom IS

SIGNAL q:STD_LOGIC_VECTOR(16 DOWNTO 0);--for free counter

SIGNAL qh:STD_LOGIC_VECTOR(26 DOWNTO 16);--for scroll scan

SIGNAL d:STD_LOGIC_VECTOR(15 DOWNTO 0);--FOR line DATA

SIGNAL ocr:STD_LOGIC;for EEPROM 2864

SIGNAL sclk:STD_LOGIC;

SIGNAL scans:STD_LOGIC_VECTOR(4 DOWNTO 0);

SIGNAL counterh:STD_LOGIC_VECTOR(11 DOWNTO 5);

SIGNAL counterl:STD_LOGIC_VECTOR(4 DOWNTO 0);--ADDR

SIGNAL addrl:STD_LOGIC_VECTOR(4 DOWNTO 0);--for a word show, read out 32 bit complately

SIGNAL scroll:STD_LOGIC_VECTOR(3 DOWNTO 0);--FOR WORD SCROLL

SIGNAL addrh:STD_LOGIC_VECTOR(11 DOWNTO 5);--for word select

BEGIN

Free_Counter:BLOCK

BEGIN

PROCESS(clk,rst,d)

BEGIN

IF rst='1' THEN-- OR d(0)='1' THEN

q(16 DOWNTO 0)<="00000000000000000";

ELSIF clk'event AND clk='1' THEN

q<=q+1;

END IF;

END PROCESS;

sclk<=q(5);--for addr lower counter

cer<=ocr;

led<=d;

addr<=addrh&addrl;

END BLOCK Free_Counter;

Free_Counter_h:BLOCK

BEGIN

PROCESS(q,rst,d)

BEGIN

IF rst='1' THEN--d(7 DOWNTO 0)="1111111" THEN-- OR d(0)='1' THEN

qh(26 DOWNTO 16)<="00000000000";

ELSIF counterh=word+1 THEN

qh(26 DOWNTO 20)<="0000000";

ELSIF q(16)'event AND q(16)='1' THEN

IF enc='1' THEN

qh<=qh+1;

END IF;

END IF;

scroll<=qh(19 DOWNTO 16);

counterh<=qh(26 DOWNTO 20);

END PROCESS;

END BLOCK Free_Counter_h;

Addressl:BLOCK --for a word read out

BEGIN

PROCESS(sclk,rst)

BEGIN

IF rst='1' THEN

counterl<="00000";

ELSIF sclk'event AND sclk='1' THEN

counterl<=counterl+1;

END IF;

END PROCESS;

END BLOCK Addressl;

PROCESS(clk)

BEGIN

IF clk'event AND clk='1' THEN

IF enscroll='1' THEN

addrl<=(counterl(4 DOWNTO 1)+scroll)&counterl(0);--key step 1:for scan scroll

ELSE

addrl<=counterl;

END IF;

END IF;

END PROCESS;

Flag:PROCESS(clk) --key step 2:for word scroll

BEGIN

IF clk'event AND clk='1' THEN

IF scroll="0000" THEN

IF scans(4 DOWNTO 1)="1111" THEN

IF counterh=word THEN

addrh<="0000000";

ELSE

addrh<=counterh+1;--下个汉字的地址

END IF;

ELSE

addrh<=counterh;--上个汉字的地址

END IF;

ELSIF scans(4 DOWNTO 1)<(("1111"-scroll)+1) THEN

addrh<=counterh;

ELSE

IF counterh=word THEN

addrh<="0000000";

ELSE

addrh<=counterh+1;--下个汉字的地址

END IF;

END IF;

END IF;

END PROCESS Flag;

Control_EEPROM:BLOCK

--SIGNAL qs:STD_LOGIC_VECTOR(4 DOWNTO 0);

BEGIN

wer<='1';

PROCESS(q,rst,sclk)

BEGIN

IF rst='1' THEN

oer<='1';

ocr<='1';

ELSIF q(1)'event AND q(1)='1' THEN

oer<=NOT sclk;--ocr;

ocr<=NOT sclk;

END IF;

END PROCESS;

END BLOCK Control_EEPROM;

scan_critical:BLOCK

BEGIN

PROCESS(q(4))

BEGIN

IF q(4)'event AND q(4)='0' THEN

scans<=counterl;

END IF;

END PROCESS;

END BLOCK scan_critical;

Data:BLOCK

BEGIN

PROCESS(rst,ocr,scans)

BEGIN

IF rst='1' THEN

d<="0000000000000000";

ELSIF ocr'event AND ocr='1' THEN

scan<=scans(4 DOWNTO 1);

IF scans(0)='1' THEN

d(7 DOWNTO 0)<=datar;

d(15 DOWNTO 8)<="00000000";

ELSIF scans(0)='0' THEN

d(15 DOWNTO 8)<=datar;

d(7 DOWNTO 0)<="00000000";

END IF;

END IF;

END PROCESS;

END BLOCK Data;

END be;