VHDL ADS8364采集程序

这个程序是在上一篇和AVR通讯 以及PWM控制的基础之上写的,这个程序是有问题的,具体问题在8364的EOC信号低电平时间只有不到1us,时间很短,而他的时钟信号不能超过5M,这个eoc信号触发外部中断来读取数据没有问题,但是在这个程序的第二第三个状态机中病没有检测到这个信号,所以出现的状况就是一直卡在第二个状态机。

 

另外由于每个状态机可能有不同的延迟,通过仿真发现毛刺现象比较突出,现在正在写改进的程序,这个程序仅作参考。

 

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

 

entity kbctest is

port(

rst,clk : in std_logic; --时钟和复位信号

--avr 读写相关信号线

ale,rd,wr : in std_logic; --地址锁存、读、写信号

ad : inout std_logic_vector(7 downto 0); --地址数据信号线

--指示灯

led1,led2 : out std_logic;

--pwm

pwm1,pwm2 : out std_logic;

--ad8364信号线

adc_d:       in    std_logic_vector(15 downto 0);

adc_a:       out   std_logic_vector(2 downto 0);   --a2,a1,a0 

adc_reset:   out   std_logic;

adc_cs:      out   std_logic;

adc_wr:      out   std_logic;

adc_rd:      out   std_logic;

adc_hold:    out   std_logic_vector(2 downto 0); --只用两路ad 开启一路hold信号

adc_eoc:     in    std_logic; 

adcclk_out: out   std_logic;

statepoint: out std_logic_vector(3 downto 0)--用来指示处于第几个状态,方便调试

--放大增益控制

);

end kbctest;

 

architecture art of  kbctest is

------------------------------------------------全局信号定义-------------------------------------------------------------------

--avr访问操作相关信号

signal adr :   std_logic_vector(7 downto 0);  --地址寄存器

signal data_buf :   std_logic_vector(7 downto 0);

signal data_outctl : std_logic;

 

 

--pwm部分相关寄存器定义 寄存器暂时定义为8位

signal pwmfreq_reg : std_logic_vector(7 downto 0);

signal pwmocr1_reg : std_logic_vector(7 downto 0);

signal pwmocr2_reg : std_logic_vector(7 downto 0);

 

signal pwm_cnt : std_logic_vector(7 downto 0);

 

--时钟分频相关变量

signal clkcnt : std_logic_vector(16 downto 0);

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

signal pwm_clk : std_logic; --pwm时钟信号

 

--led指示相关变量

signal led_clk : std_logic; --led时钟信

signal led1_cnt : std_logic_vector(7 downto 0);

signal led2_cnt : std_logic_vector(7 downto 0);

signal led1s : std_logic;

signal led2s : std_logic;

 

--ads8364信号

type states is (st0,st1,st2,st3,st4,st5,st6,st7,st8,st9,st10,st11,st12,st13,st14,st15);  --定义各状态的子类型

signal adcdata0h_reg,adcdata0l_reg,adcdata1h_reg,adcdata1l_reg : std_logic_vector(7 downto 0);

signal current_state,next_state: states:=st0; 

 

 

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时钟

 

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

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

adc_clk <= clkcnt(2);

adcclk_out <= clkcnt(2);

 

------------------------------------------------avr访问操作----------------------------------------------------------------

data_outctl <= (not ale) and (not rd) and (wr);

ad <=  data_buf when (data_outctl='1') else "ZZZZZZZZ";

 

--锁存avr地址数据

process(rst,ale) is

begin

if rst='0' then 

adr <= "00000000";

elsif(ale'event and ale='0') then --在ale信号的下降沿锁存地址数据

adr <= ad;

end if;

end process;

 

-------------------------------------avr写数据-----------------------------------

process(rst,wr,ale) is

begin

if rst='0' then --对各寄存器给定初值

pwmfreq_reg <= "11111111";

pwmocr1_reg <= "01000000";

elsif (wr='1' and wr'event) then --在wr信号上升沿进行写操作

if ale = '0' then 

case adr is

when "00000001" => pwmfreq_reg <= ad;

when "00000010" => pwmocr1_reg <= ad;

 

when others =>

pwmfreq_reg <= pwmfreq_reg;

end case;

end if;

end if;

end process;

 

------------------------------------avr读数据-------------------------------------

process(rst,rd,ale) is

begin

if rst='0' then

data_buf<="00000000";

elsif (rd='0'and rd'event) then

case adr is

when "00000001" => data_buf <= adcdata0h_reg;--1

when "00000010" => data_buf <= adcdata0l_reg;--2

when "00000011" => data_buf <= adcdata1h_reg;--3

when "00000100" => data_buf <= adcdata1l_reg;--4

when "00000101" => data_buf <= "00110011"; --5

when others => 

data_buf <= "ZZZZZZZZ";

end case;

end if;

end process;

------------------------------------led指示-------------------------------------

process(led_clk)is

begin

if(led_clk'event and led_clk='1') then

led1_cnt <= led1_cnt+1;

if (led1_cnt >= pwmfreq_reg) then

led1s <= not led1s; 

led1_cnt <="00000000";

end if;

end if;

end process;

led1<=led1s;

--process(led_clk)is

--begin

-- if(led_clk'event and led_clk='1') then

-- led2_cnt <= led2_cnt+1;

-- if (led2_cnt >= pwmocr1_reg) then

-- led2s <= not led2s; 

-- led2_cnt <="00000000";

-- end if;

-- end if;

--end process;

--led2<=led2s;

 

--------------------------------------pwm---------------------------------------

process(pwm_clk) is

begin

if rst='0' then             

pwm_cnt<="00000000";

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

if(pwm_cnt > pwmfreq_reg) then

pwm_cnt <= "00000000";

else  

pwm_cnt<=pwm_cnt+1;

end if;

--数据比较模块

if(pwm_cnt>=pwmocr1_reg) then  

pwm1<= '1';

else 

pwm1<= '0';

end if;

end if;

end process;

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

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

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

adc_wr <= '1'; 

--ads状态转移

process(rst,adc_clk) is 

begin

if rst = '0' then 

adc_reset<='0';

current_state <= st0;

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

current_state <= next_state;

adc_reset<='1';

end if;

end process;

 

process(current_state,adc_eoc) is

begin

   case current_state is

        when st0=> 

adc_hold <= "111";

adc_rd <= '1';

adc_a <="000";

statepoint <= "0000";

led2<='1';

next_state <= st1;

        when st1=> 

adc_hold <= "000"; 

adc_rd <= '1'; 

adc_a <="000";

statepoint <= "0001";

led2<='1';

next_state <= st2; --启动转换

        when st2=> 

adc_hold <= "111"; 

adc_rd <= '1';  

adc_a <="000";

statepoint <= "0010";

led2<='0';

--检测adc_eoc下降沿

if adc_eoc = '1' then

next_state <= st2;

else 

next_state <= st3;

end if;

        when st3=> 

adc_hold <= "111"; 

adc_rd <= '1'; 

adc_a <="000";

statepoint <= "0011";

led2<='1';

--检测adc_eoc上升沿

if adc_eoc = '0' then 

next_state <= st3; 

else

next_state <= st4;

end if;

        when st4=> 

adc_hold <= "111"; 

adc_rd <= '0';--使能读信号 读取数据    

adc_a <="000";

statepoint <= "0100";

adcdata0h_reg <= adc_d(15 downto 8);

adcdata0l_reg <= adc_d(7 downto 0);

led2<='1';

next_state <= st5; 

        when st5=> 

adc_hold <= "111"; 

adc_rd <= '1';

adc_a <="001";--rd上升沿之后给出下一通道读取地址

statepoint <= "0101";

next_state <= st6;

led2<='1';

        when st6=> 

adc_hold <= "111"; 

adc_a <="001";

adc_rd <= '0';    --读ch1数据

adcdata1h_reg <= adc_d(15 downto 8);

adcdata1l_reg <= adc_d(7 downto 0);  

statepoint <= "0110";

led2<='1';

next_state <= st7; 

        when st7=> 

adc_hold <= "111"; 

adc_rd <= '1'; 

adc_a <="001";

statepoint <= "0111";

led2<='1';

next_state <= st0;

        when others=> 

adc_hold <= "111";

adc_rd <= '1'; 

adc_a <="000";

next_state <= st0;

    end case;

end process;

 

 

end;

 

你可能感兴趣的:(VHDL ADS8364采集程序)