新闻  |   论坛  |   博客  |   在线研讨会
基于Fpga和VGA显示的AD574采集
gaochy1126 | 2011-09-24 13:39:18    阅读:1531   发布文章

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进行分频后才能使用,否则会出现只能读取一次数据的现象.

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客