AD574的采集及VGA显示程序如下:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.std_logic_arith.all;
entity vga640480 is
port (
clk : in STD_LOGIC;
hs : out STD_LOGIc;
vs : out STD_LOGIc;
r : out STD_LOGIC;
g : out STD_LOGIC;
b : out STD_LOGIC;
rgbin : in std_logic_vector(7 downto 0);
hcntout : out std_logic_vector(9 downto 0);
vcntout : out std_logic_vector(9 downto 0);
ps2clk : in std_logic;
ps2dat : in std_logic;
D :IN STD_LOGIC_VECTOR(11 DOWNTO 0);
STATUS : IN STD_LOGIC;
CS,A0,RC: OUT STD_LOGIC;
Q :out STD_LOGIC_VECTOR(7 DOWNTO 0)
);
end vga640480;
architecture ONE of vga640480 is
signal hcnt : std_logic_vector(9 downto 0);
signal vcnt : std_logic_vector(9 downto 0);
signal rgb : std_logic_vector(7 downto 0);
signal rgb1 : std_logic_vector(7 downto 0);
signal clk_1s:std_logic:='1';
signal clk_1k:std_logic:='1';
type num_buffer is array(0 to 159) of std_logic_vector(7 downto 0);
constant num_b:num_buffer:=(
X"00",X"00",X"00",X"18",X"24",X"42",X"42",X"42",X"42",X"42",X"42",X"42",X"24",X"18",X"00",X"00",--0--0
X"00",X"00",X"00",X"08",X"0E",X"08",X"08",X"08",X"08",X"08",X"08",X"08",X"08",X"3E",X"00",X"00",--1--1
X"00",X"00",X"00",X"3C",X"42",X"42",X"42",X"20",X"20",X"10",X"08",X"04",X"42",X"7E",X"00",X"00",--2--2
X"00",X"00",X"00",X"3C",X"42",X"42",X"20",X"18",X"20",X"40",X"40",X"42",X"22",X"1C",X"00",X"00",--3--3
X"00",X"00",X"00",X"20",X"30",X"28",X"24",X"24",X"22",X"22",X"7E",X"20",X"20",X"78",X"00",X"00",--4--4
X"00",X"00",X"00",X"7E",X"02",X"02",X"02",X"1A",X"26",X"40",X"40",X"42",X"22",X"1C",X"00",X"00",--5--5
X"00",X"00",X"00",X"38",X"24",X"02",X"02",X"1A",X"26",X"42",X"42",X"42",X"24",X"18",X"00",X"00",--6--6
X"00",X"00",X"00",X"7E",X"22",X"22",X"10",X"10",X"08",X"08",X"08",X"08",X"08",X"08",X"00",X"00",--7--7
X"00",X"00",X"00",X"3C",X"42",X"42",X"42",X"24",X"18",X"24",X"42",X"42",X"42",X"3C",X"00",X"00",--8--8
X"00",X"00",X"00",X"18",X"24",X"42",X"42",X"42",X"64",X"58",X"40",X"40",X"24",X"1C",X"00",X"00"--9--9
);
TYPE states IS (st0, st1, st2, st3,st4);
SIGNAL current_state,next_state: states := st0 ;
SIGNAL REGL : STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL LOCK,enable : STD_LOGIC;
function write_hz(h4,v4 : std_logic_vector(9 downto 0) ;h3,v3 :integer range 0 to 1000;num : integer range 0 to 10 )
return std_logic_vector is
variable h1,h2,v1,v2:integer range 0 to 10000;
begin
h2 := conv_integer( h4 );
h1 := h3 ;
v2 := conv_integer( v4 );
v1 := v3 ;
if v2>=v1 and v2<v1+16 and h2>=h1 and h2 <h1+8 then
if buf(v2-v1+32*num)(h2-h1)='1' then rgb(7)<='1';rgb(4)<='1';rgb(1)<='1';
else rgb(7)<='1';rgb(4)<='0';rgb(1)<='0';
end if;
end if;
if v2>= v1 and v2<v1+16 and h2>=h1+8 and h2 <h1+16 then
if buf(v2-v1+16+32*num)(h2-h1-8)='1' then rgb(7)<='1';rgb(4)<='1';rgb(1)<='1';
else rgb(7)<='1';rgb(4)<='0';rgb(1)<='0';
end if;
end if;
return rgb;
end function write_hz;
function write_num(h41,v41 : std_logic_vector(9 downto 0) ;h31,v31 :integer range 0 to 1000;num1 : integer range 0 to 10 )
return std_logic_vector is
variable h11,h21,v11,v21:integer range 0 to 10000;
begin
h21 := conv_integer( h41 );
h11 := h31 ;
v21 := conv_integer( v41 );
v11 := v31 ;
if v21>=v11 and v21<v11+16 and h21>=h11 and h21 <h11+8 then
if num_b(v21-v11+16*num1)(h21-h11)='1' then rgb(7)<='1';rgb(4)<='1';rgb(1)<='1';
else rgb(7)<='1';rgb(4)<='0';rgb(1)<='0';
end if;
end if;
-- if v21>= v11 and v21<v11+16 and h21>=h11+8 and h21 <h11+16 then
-- if num_b(v21-v11+8)(h21-h11-8)='1' then rgb(7)<='1';rgb(4)<='1';rgb(1)<='1';
-- else rgb(7)<='1';rgb(4)<='0';rgb(1)<='0';
-- end if;
-- end if;
return rgb;
end function write_num;
begin
Q <= REGL(11 downto 4);
hcntout <= hcnt;
vcntout <= vcnt;
process(clk)
variable cnt:integer range 0 to 10000;
variable cnt1:integer range 0 to 5000;
begin
if clk'event and clk='1' then
if cnt=2 then
clk_1s <= not clk_1s;cnt:=0;
elsif cnt1=10 then cnt:=cnt+1;cnt1:=0;
else cnt1:=cnt1+1;
end if;
end if;
end process;
process(clk)
variable cnt:integer range 0 to 10000;
variable cnt1:integer range 0 to 5000;
variable cnt2:integer range 0 to 5000;
begin
if clk'event and clk='1' then
if cnt=10000 then
clk_1k <= not clk_1k;cnt:=0;
elsif cnt1=4900 then cnt:=cnt+1;cnt1:=0;
elsif cnt2= 10 then cnt1:=cnt1+1;cnt2:=0;
else cnt2:=cnt2+1;
end if;
end if;
end process;
process(clk_1k)
begin
if clk_1k'event and clk_1k='1' then
enable <= not enable;
end if;
end process;
PROCESS(current_state,STATUS) --决定转换状态的进程
BEGIN
CASE current_state IS
WHEN st0 => if enable'event and enable = '1' then next_state <= st1;
else next_state <= st0;
end if;
WHEN st1 => next_state <= st2;
WHEN st2 => IF (STATUS='1') THEN next_state <= st2;
ELSE next_state <= st3;
END IF ;
WHEN st3=> next_state <= st4;
WHEN st4=> next_state <= st0;
WHEN OTHERS => next_state <= st0;
END CASE ;
END PROCESS ;
PROCESS(current_state) --输出控制信号的进程
BEGIN
CASE current_state IS
WHEN st0=> CS<='1'; A0<='1';RC<='1';LOCK<='0'; --初始化
WHEN st1=> CS<='0'; A0<='0';RC<='0';LOCK<='0'; --启动12位转换
WHEN st2=> CS<='0'; A0<='0';RC<='0';LOCK<='0'; --等待转换
WHEN st3=> CS<='0'; A0<='0';RC<='1';LOCK<='0'; --12位并行输出有效
WHEN st4=> CS<='0'; A0<='0';RC<='1';LOCK<='1'; -- 锁存数据
WHEN OTHERS=>CS<='1'; A0<='1';RC<='1';LOCK<='0';--其它情况返回初始态
END CASE ;
END PROCESS ;
PROCESS (clk_1s) -- 时序进程
BEGIN
IF ( clk_1s'event and clk_1s='1') THEN current_state <= next_state;
END IF;
END PROCESS ;
PROCESS (LOCK) -- 数据锁存器进程
BEGIN
IF LOCK='1' AND LOCK'EVENT THEN REGL <= D ;
END IF;
END PROCESS ;
process(clk)
variable cnt:integer range 0 to 10000;
begin
if clk'event and clk='1' then
if cnt=63 then
clk_400k <= '0';cnt:=cnt+1;
elsif cnt=124 then clk_400k <= '1'; cnt:=0;
else cnt:=cnt+1;
end if;
end if;
end process;
--this is Horizonal counter
process(clk) begin
if (rising_edge(clk)) then
if(hcnt < 800) then
hcnt <= hcnt + 1;
else
hcnt <= (others => '0');
end if;
end if;
end process;
--this is Vertical counter
process(clk) begin
if (rising_edge(clk)) then
if (hcnt = 640+8 ) then
if(vcnt < 525) then
vcnt <= vcnt + 1;
else
vcnt <= (others => '0');
end if;
end if;
end if;
end process;
process(clk) begin
if (rising_edge(clk)) then
if((hcnt>= 640+8+8) and (hcnt<640+8+8+96 )) then
hs <= '0';
else
hs <= '1';
end if;
end if;
end process;
process(vcnt) begin
if ((vcnt >= 480+8+2) and (vcnt < 480+8+2+2)) then
vs <= '0';
else
vs <= '1';
end if;
end process;
process(clk) begin
if (rising_edge(clk)) then
rgb1 <= write_num(hcnt,vcnt,110,0,conv_integer(REGL) / 1000);
rgb1 <= write_num(hcnt,vcnt,120,0,(conv_integer(REGL) / 100)mod 10);
rgb1 <= write_num(hcnt,vcnt,130,0,(conv_integer(REGL) / 10 )mod 10);
rgb1 <= write_num(hcnt,vcnt,140,0,conv_integer(REGL) mod 10);
rgb1 <= write_num(hcnt,vcnt,120,30,conv_integer(key_num) /100);
rgb1 <= write_num(hcnt,vcnt,130,30,(conv_integer(key_num)/10 )mod 10);
rgb1 <= write_num(hcnt,vcnt,140,30,conv_integer(key_num) mod 10);
end if;
end if;
end process;
r<=rgb1(7);
g<=rgb1(4);
b<=rgb1(1);
end ONE;
对于AD574的建立时间是25us,所以我们必须把fpga进行分频后才能使用,否则会出现只能读取一次数据的现象.
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。