基于FPGA的AD7303/ADCS7476模拟数字转换VHDL开发

目录

一、理论基础

二、核心程序

三、测试结果


 

一、理论基础

在Altera NIOS板上设计和实现一个格式转换系统,该系统读取模拟输入,将其转换为数字数据,然后将其反向转换为模拟格式。这将通过使用SPI MCP3202 12位A/D转换器进行模拟输入来实现,以生成数字数据流,然后使用Analog Devices 8位SPI AD7303 D/A转换器将数字数据用于生成模拟输出。数字输出还通过中间的低通滤波器(FIR)。分配给我的采样频率和截止频率分别为23 kHz和2.3 kHz。

12bit位宽的ADCS7476,根据技术文档datasheet可知:

 

 

主要接口包括CS片选接口,SCLK时钟,SDATA数据,然后这个芯片是2路信号,然后我这里接口都预留了,然后实际用一个就可以了。

      他的时序如下所示:

 

 然后看AD7303。

 

 这个的话,确实得按这个状态图进行设计。通过状态机的方式实现。

二、核心程序


LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY adcs7476 IS
PORT (
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
adc_cs_b : OUT STD_LOGIC;
adc_clk : OUT STD_LOGIC;
adc_data0 : IN STD_LOGIC;
adc_data1 : IN STD_LOGIC;
v0 : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
v1 : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
rdy : OUT STD_LOGIC;
delay : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
count : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)
);
END adcs7476;
ARCHITECTURE trans OF adcs7476 IS
SIGNAL tmp0 : STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL tmp1 : STD_LOGIC_VECTOR(11 DOWNTO 0);
-- Declare intermediate signals for referenced outputs
SIGNAL adc_cs_b_Reg1 : STD_LOGIC;
SIGNAL adc_clk_Reg0 : STD_LOGIC;
SIGNAL v0_Reg5 : STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL v1_Reg6 : STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL rdy_Reg4 : STD_LOGIC;
SIGNAL delay_Reg3 : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL count_Reg2 : STD_LOGIC_VECTOR(6 DOWNTO 0);
BEGIN
-- Drive referenced outputs
adc_cs_b <= adc_cs_b_Reg1;
adc_clk <= adc_clk_Reg0;
v0 <= v0_Reg5;
v1 <= v1_Reg6;
rdy <= rdy_Reg4;
delay <= delay_Reg3;
count <= count_Reg2;
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
delay_Reg3 <= "00000000000000000000000000000000";
ELSIF (clk'EVENT AND clk = '1') THEN
IF (delay_Reg3 = "00000000000000000000000000000010") THEN
delay_Reg3 <= "00000000000000000000000000000000";
ELSE
delay_Reg3 <= delay_Reg3 + "00000000000000000000000000000001";
END IF;
END IF;
END PROCESS;
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
count_Reg2 <= "0000000";
ELSIF (clk'EVENT AND clk = '1') THEN
IF (delay_Reg3 = "00000000000000000000000000000000") THEN
IF (count_Reg2 = "0101110") THEN
count_Reg2 <= "0000000";
ELSE
count_Reg2 <= count_Reg2 + "0000001";
END IF;
END IF;
END IF;
END PROCESS;
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
adc_cs_b_Reg1 <= '0';
adc_clk_Reg0 <= '0';
rdy_Reg4 <= '0';
ELSIF (clk'EVENT AND clk = '1') THEN
IF (count_Reg2 < "0100000") THEN
adc_cs_b_Reg1 <= '0';
ELSE
adc_cs_b_Reg1 <= '1';
END IF;
IF (count_Reg2 = "0100000") THEN
rdy_Reg4 <= '1';
ELSE
rdy_Reg4 <= '0';
END IF;
adc_clk_Reg0 <= count_Reg2(0);
END IF;
END PROCESS;
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
tmp0 <= "000000000000";
tmp1 <= "000000000000";
ELSIF (clk'EVENT AND clk = '1') THEN
IF (delay_Reg3 = "00000000000000000000000000000000") THEN
IF (((NOT(adc_clk_Reg0)) = '1' OR adc_cs_b_Reg1 = '1') = true) THEN
tmp0 <= tmp0;
ELSE
tmp0 <= (tmp0(10 DOWNTO 0) & adc_data0);
END IF;
IF (((NOT(adc_clk_Reg0)) = '1' OR adc_cs_b_Reg1 = '1') = true) THEN
tmp1 <= tmp1;
ELSE
tmp1 <= (tmp1(10 DOWNTO 0) & adc_data1);
END IF;
END IF;
END IF;
END PROCESS;
PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
v0_Reg5 <= "000000000000";
v1_Reg6 <= "000000000000";
ELSIF (clk'EVENT AND clk = '1') THEN
IF (delay_Reg3 = "00000000000000000000000000000000") THEN
IF (rdy_Reg4 = '1') THEN
v0_Reg5 <= tmp0;
ELSE
v0_Reg5 <= v0_Reg5;
END IF;
IF (rdy_Reg4 = '1') THEN
v1_Reg6 <= tmp1;
ELSE
v1_Reg6 <= v1_Reg6;
END IF;
END IF;
END IF;
END PROCESS;
END trans;

三、测试结果

ADCS7476然后位宽是12位,根据这些信息,我们的测试仿真结果如下所示:

 

 AD7303

 

 A28-63

posted @ 2022-11-26 21:11  fpga和matlab  阅读(168)  评论(0编辑  收藏  举报