|
驱动12864显示的程序
--12864液晶(st7920)的显示--
--时钟频率:10MHZ-----------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity lcd12864 is
generic(
divide_500k:integer:=10000--10000分频后:1000HZ:周期:1ms
);
port(
clk,reset:in std_logic;
rs,rw,en:out std_logic;
data:out std_logic_vector(7 downto 0)
);
end entity;
architecture behavior of lcd12864 is
type word1 is array(0 to 5) of std_logic_vector(7 downto 0);
type word2 is array (0 to 5) of std_logic_vector(7 downto 0);
type state is(
reset_state,
set_dlnf1,set_dlnf2,set_cursor,set_dcb,set_shift,
set_ddram,
write_name,
set_ddram2,
write_name2,
over
);
--constant name:word:=("11010110","11010000","10111001","11111010");--中D6D0 国B9FA
constant name1:word1:=("11001010","10110001","10111100","11100100","10100001","11000011");--时间:
constant name2:word2:=("11001000","11010101","11000110","11011010","10100001","11000011"); ---日期:
signal pr_state:state;
signal newclk:std_logic;
begin
en<=newclk; ----状态机时钟信号,同时也是液晶时钟信号,其周期应该满足液晶数据的建立:频率不能太小,否则液晶无法正常显示。
-- rw<='0'; --写数据
process(clk) is
variable num:integer range 0 to divide_500k;
begin
if(clk'event and clk='1')then
num:=num+1;
if(num=divide_500k) then
num:=0;
end if;
if(num<divide_500k/2) then
newclk<='0';
else newclk<='1';
end if;
end if;
end process;
process(newclk,reset,pr_state) is
variable cnt:integer range 0 to 10:=0;
variable cnt2:integer range 0 to 10:=0;
begin
if(reset='0') then
cnt:=0;
cnt2:=0;
data<="ZZZZZZZZ";
pr_state<=set_dlnf1;--把状态set_dlnf1赋于pr_state
elsif(newclk'event and newclk='1') then
case pr_state is
when set_dlnf1=>
rs<='0';--命令
rw<='0';
data<="00110000";--选择8位数据基本指令集:0x30
pr_state<=set_dlnf2;--把状态set_dlnf2赋于pr_state
when set_dlnf2=>
data<="00110000";--选择8位数据基本指令集:0x30,本人见过的程序中,0x30都被写了两次。尝试着去掉一个0x30的写入,对结果无影响。。不知为何,望指教?
pr_state<=set_cursor;
when set_cursor=>
data<="00001100";--整体显示设置:光标OFF 反光0FF:0x0c
pr_state<=set_dcb;
when set_dcb=>
data<="00000001";--清除显示,并且认定地址指针为00h:0x01
pr_state<=set_shift;
when set_shift=>
data<="00000110";--指定游标的移动方向及指定显示的移位:0x06
pr_state<=set_ddram;
when set_ddram=>
data<="10000000";--从第一行的第一个字开始显示:0x80
pr_state<=write_name;
when write_name=>
rs<='1';
data<=name1(cnt);
cnt:=cnt+1;
if(cnt=6) then
cnt:=0;
pr_state<=set_ddram2;
end if;
when set_ddram2=>
RS<='0';
data<="10010000";--从第一行的第一个字开始显示:0x90
pr_state<=write_name2;
when write_name2=>
rs<='1';
data<=name2(cnt);
cnt:=cnt+1;
if(cnt=6) then
cnt:=0;
pr_state<=over;
end if;
when over=>
rs<='Z'; --此处一定要对rs,rw,data进行操作。
rw<='Z'; --否则使能端时钟信号的驱使下不断地高低变化,会把上次的数据不停的写入液晶
data<=(others=>'Z');
cnt:=0;
when others=>
null;
end case;
end if;
end process;
end architecture;
编译的时候,出现错误,
Error: Design requires 9 output enable signals, but the device can contain only 6 output enable signals
Error: Can't find fit
Error: Quartus II Fitter was unsuccessful. 2 errors, 0 warnings
Error: Peak virtual memory: 163 megabytes
Error: Processing ended: Fri Sep 23 11:08:15 2011
Error: Elapsed time: 00:00:00
Error: Total CPU time (on all processors): 00:00:00
Error: Quartus II Full Compilation was unsuccessful. 4 errors, 1 warning
网上找了段BLOG
最近写了一个程序,老是出现这样的错误:Error: Design requires 7 output enable signals, but the device can contain only 6 output enable signals ,当我写7个(others => 'Z')时,就会出现这样的错误,原以为这是芯片的限制,只能用6个高阻,然后其他的高阻我就用信号转发,signal <= (others => 'Z') ,io <= signal,这样语法上是没错,但实际上io口并不能呈高阻状态,所以一定要有7个高阻状态才能实现我所要的功能,冥思苦想未果,最后认识了网友“水滴”,她告诉我是逻辑单元占用过多造成,我的程序里与门确实过多,简化之后就可以了
我想知道如何简化代码?占用逻辑单元过多,为啥 ,哪些代码会占用过多的呢,谢谢 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|