ADS8364 VHDL程序正式版

这个程序的寄存器读取时和STM32通讯的,之前有一个是和AVR通讯的,这个程序已经调试通过,原理比较简单,相信认真看的都能够明白。

因为ADS8364为差分AD,所以其输出为补码形式,按照2.5V的参考电压源输出的数据范围为-32768~+32768,如果AIN- 连到VREF(2.5V),那么当AIN+ 输入为0 输出的数据为0x8000,如果AIN+ 输入为2.5V则输出数据为0x0000AIN+ 输入为5V时输出数据位0x7F。程序如下:

--最后修改2011.3.26

--最后测试功能:

--利用第一块板子测试ADS8364

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

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

--此段定义系统的各信号线

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

entity ad is

port(

-- 系统信号线

    clk:         in      std_logic;

led: out std_logic;

    rst:       in      std_logic; 

-- arm相连的信号线

    adr_l:       in      std_logic_vector(7 downto 0); --a7...a0,只使用了低八位地址线

    data:        inout   std_logic_vector(7 downto 0); --只使用了低八位数据线

    fsmc_ne4:    in      std_logic;  

    fsmc_noe:    in      std_logic;

    fsmc_nwe:    in      std_logic;

--ad8364信号线

adc_d:       in    std_logic_vector(15 downto 0);

adc_a0,adc_a1,adc_a2:       out   std_logic;

adc_reset:   out   std_logic;

adc_cs:      out   std_logic;

adc_wr:      out   std_logic;

adc_rd:      out   std_logic;

adc_holda,adc_holdb,adc_holdc: out std_logic;

adc_eoc:     in    std_logic; 

adcclk_out: out   std_logic

);

end entity;

 

--统一编址,地址线数据线为八位,每个地址数据宽度8位

--"00000001" ad0_h_data 0x01

--"00000010" ad0_l_data 0x02

--"00000011" ad1_h_data 0x03

--"00000100" ad1_l_data 0x04

--"00000101" led_ctrl 0x05

 

architecture art of ad is

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

--此段定义内部相应的寄存器和相应变量

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

 

--stm32读写相关信号

 

--设置存储数据的寄存器

signal ad0_h_data,ad0_l_data,ad1_h_data,ad1_l_data,led_ctrl:  std_logic_vector(7 downto 0); 

--数据缓冲寄存器

signal data_buf: std_logic_vector(7 downto 0);

--数据输出控制

signal data_outctl: std_logic;

 

--时钟分频相关变量

signal clkcnt : std_logic_vector(16 downto 0);

signal adc_clk : std_logic; --adc时钟信号

signal adc_data_buf : std_logic_vector(15 downto 0);

 

--定义读取过程的各个状态

--13位控制分别为 hold adc_a rd 状态机状态5位     hhhabcr

---------------------------------------------------98365

constant st0 :std_logic_vector(11 downto 0):="000000100000";--启动转换

constant st1 :std_logic_vector(11 downto 0):="111000100001";--进入17个周期等待转换结束,不检测EOC

constant st2 :std_logic_vector(11 downto 0):="111000100010";

constant st3 :std_logic_vector(11 downto 0):="111000100011";

constant st4 :std_logic_vector(11 downto 0):="111000100100";

constant st5 :std_logic_vector(11 downto 0):="111000100101";

constant st6 :std_logic_vector(11 downto 0):="111000100110";

constant st7 :std_logic_vector(11 downto 0):="111000100111";

constant st8 :std_logic_vector(11 downto 0):="111000101000";

constant st9 :std_logic_vector(11 downto 0):="111000101001";

constant st10 :std_logic_vector(11 downto 0):="111000101010";

constant st11 :std_logic_vector(11 downto 0):="111000101011";

constant st12 :std_logic_vector(11 downto 0):="111000101100";

constant st13 :std_logic_vector(11 downto 0):="111000101101";

constant st14 :std_logic_vector(11 downto 0):="111000101110";

constant st15 :std_logic_vector(11 downto 0):="111000101111";

constant st16 :std_logic_vector(11 downto 0):="111000110000";

constant st17 :std_logic_vector(11 downto 0):="111000110001";

constant st18 :std_logic_vector(11 downto 0):="111000110010";

constant st19 :std_logic_vector(11 downto 0):="111000010011";--读ch1数据

constant st20 :std_logic_vector(11 downto 0):="111001110100";

constant st21 :std_logic_vector(11 downto 0):="111001010101";--读ch2数据

constant st22 :std_logic_vector(11 downto 0):="111001110110";

 

signal state :std_logic_vector(11 downto 0);--用于状态跳转

signal readst :std_logic_vector(3 downto 0);--adc_a,在另一个进程中根据此信号 选择输出的数据

 

begin

------------------------------------------------时钟分频-------------------------------------------------------------------

process(rst,clk) is

begin

if rst='0' then

clkcnt <= "00000000000000000";

elsif(clk'event and clk = '1') then

if(clkcnt = "11111111111111111") then

clkcnt<= "00000000000000000";

else

clkcnt <= clkcnt+1;

end if;

end if;

end process;

--pwm_clk <= clkcnt(7); --分频pwm时钟

--led_clk <= clkcnt(16); --分频led时钟

 

led <= clkcnt(16); --分频led时钟

adc_clk <= clkcnt(3);

adcclk_out <= clkcnt(3);

 

 

 

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

--stm32读写程序

--根据stm32读写时序图和信号线设计,实际上并没有使用全部信号线

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

 

--当读取cpld数据时用来判断何时向总线上输出数据

data_outctl <= (not  fsmc_ne4) and (not fsmc_noe) and (fsmc_nwe);  

data <=  data_buf when (data_outctl='1') else "ZZZZZZZZ";--向数据线输出数据,否则保持为高阻态

 

-- 写操作,模式1,时序图在数据手册p331

process(rst,fsmc_ne4,fsmc_nwe,adr_l,fsmc_noe) is  

begin

if rst='0' then

elsif(fsmc_nwe'event and fsmc_nwe='1') then

if((fsmc_noe and (not fsmc_ne4))='1') then

case (adr_l) is

when "00000001" => --对应的地址   

 

when "00000010" =>  

 

when "00000011" =>

 

when "00000100" =>

 

when "00000101" =>  

 

when others =>

 

end case;

end if;

end if;

end process;

 

--读操作,模式1,p331

process(rst,fsmc_ne4,fsmc_nwe,adr_l,fsmc_noe) is 

begin

if rst= '0' then

data_buf<="00000000";

elsif(fsmc_noe='0' and fsmc_noe'event) then --直接在noe的下降沿更新数据

case (adr_l) is

when "00000001" =>   

data_buf <= ad0_h_data; --0x01

when "00000010" =>  

data_buf <= ad0_l_data; --0x02

when "00000011" =>  

data_buf <= ad1_h_data; --0x03

when "00000100" => 

data_buf <= ad1_l_data; --0x04

when "00000101" => 

data_buf <= "11001100"; --0x05

when others =>  data_buf <= "ZZZZZZZZ";

end case; 

end if;

end process;

--------------------------------------ads8364------------------------------------

--ads8364控制,默认byte=0,add=0

adc_cs <= '0'; --片选一直选中

adc_wr <= '1'; 

--ads状态转移

process(adc_clk,rst)

begin

if(rst='0') then

state<=st0;

adc_reset<='0';

adc_holda<='1';

adc_holdb<='1';

adc_holdc<='1';

elsif(adc_clk'event and adc_clk='1') then

adc_reset<='1';

case state is

when st0=> state<=st1;

when st1=> state<=st2;

when st2=> state<=st3;

when st3=> state<=st4;

when st4=> state<=st5;

when st5=> state<=st6;

when st6=> state<=st7;

when st7=> state<=st8;

when st8=> state<=st9;

when st9=> state<=st10;

when st10=> state<=st11;

when st11=> state<=st12;

when st12=> state<=st13;

when st13=> state<=st14;

when st14=> state<=st15;

when st15=> state<=st16;

when st16=> state<=st17;

when st17=> state<=st18;

when st18=> state<=st19;

when st19=> state<=st20;

when st20=> state<=st21;

when st21=> state<=st22;

when st22=> state<=st0;

when others=> state<=st0;

end case;

end if;

readst<=state(8 downto 5);

adc_holdc<=state(11);

adc_holdb<=state(10);

adc_holda<=state(9);

adc_a2<=state(8);

adc_a1<=state(7);

adc_a0<=state(6);

adc_rd<=state(5);

end process;

 

process(clk,adc_d)

begin

if(clk'event and clk='0')then

adc_data_buf(14 downto 0) <= adc_d(14 downto 0);

adc_data_buf(15) <= not adc_d(15); 

if readst="0000" then

ad0_h_data <= adc_data_buf(15 downto 8);

ad0_l_data <= adc_data_buf(7 downto 0); 

elsif readst="0010" then

ad1_h_data <= adc_data_buf(15 downto 8);

ad1_l_data <= adc_data_buf(7 downto 0); 

end if;

end if;

end process;

end;

 

 

 

你可能感兴趣的:(ADS8364 VHDL程序正式版)