LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_Arith.ALL;
USE IEEE.STD_LOGIC_Unsigned.ALL;
ENTITY adc IS
GENERIC(
CLK_DIV_BITS: Integer:=5;
CLK_DIV_VALUE: Integer:=31
);
PORT(
clock: IN STD_LOGIC;--系统时钟
reset: IN STD_LOGIC;--复位,高电平有效
enable: IN STD_LOGIC;--转换使能
sdat_in: IN STD_LOGIC;--TLC549串行数据输入
adc_clk: OUT STD_LOGIC;--TLC549 I/O时钟
cs_n: OUT STD_LOGIC;--TLC549 片选控制
data_ready: OUT STD_LOGIC;--指示有新的数据输出
data_out: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)--AD转换数据输出
);
END;
ARCHITECTURE one OF adc IS
SIGNAL adc_clk_r: STD_LOGIC;
SIGNAL cs_n_r: STD_LOGIC;
SIGNAL data_ready_r:STD_LOGIC;
SIGNAL data_out_r: STD_LOGIC_VECTOR(7 DOWNTO 0);--AD转换数据输出.
SIGNAL sdat_in_r: STD_LOGIC;--数据输出锁存
SIGNAL q: STD_LOGIC_VECTOR(7 DOWNTO 0);--移位寄存器,用于接收或发送数据
SIGNAL bit_count: STD_LOGIC_VECTOR(5 DOWNTO 0);--移位计数器
SIGNAL bit_count_rst:STD_LOGIC;--ADC时钟计数全能控制.
SIGNAL div_clk: STD_LOGIC;
SIGNAL clk_count: STD_LOGIC_VECTOR(CLK_DIV_BITS-1 DOWNTO 0);--时钟盼频计数器
SIGNAL buf1,buf2: STD_LOGIC;
SIGNAL ready_done: STD_LOGIC;--cs_n拉低(大于1.4us)后的标志
SIGNAL rec_done: STD_LOGIC;--数据读取完毕的标志
SIGNAL conv_done: STD_LOGIC;--数据转换完毕的标志
--SIGNAL adc_state: STD_LOGIC_VECTOR(2 DOWNTO 0);--状态机ADC
--SIGNAL adc_next_state:STD_LOGIC_VECTOR(2 DOWNTO 0);
--CONSTANT idle: STD_LOGIC_VECTOR(2 DOWNTO 0):="000";
--CONSTANT adc_ready: STD_LOGIC_VECTOR(2 DOWNTO 0):="001";
--CONSTANT adc_receive: STD_LOGIC_VECTOR(2 DOWNTO 0):="011";
--CONSTANT adc_conversion: STD_LOGIC_VECTOR(2 DOWNTO 0):="010";
--CONSTANT adc_data_load: STD_LOGIC_VECTOR(2 DOWNTO 0):="110";
TYPE states IS(idle,adc_ready,adc_receive,adc_conversion,adc_data_load);
SIGNAL adc_state,adc_next_state:states;
BEGIN
adc_clk<=adc_clk_r;
cs_n<=cs_n_r;
data_out<=data_out_r;
data_ready<=data_ready_r;
PROCESS (clock)
BEGIN
IF RISING_EDGE(clock) THEN
sdat_in_r<=sdat_in;
END IF;
END PROCESS;
-----------------------------------------<<时钟分频计数器
PROCESS (clock)
BEGIN
IF RISING_EDGE(clock) THEN
IF reset='1' THEN
clk_count<="00000";
ELSE
IF clk_count< CLK_DIV_VALUE THEN
clk_count<=clk_count+1;
div_clk<='0';
ELSE
clk_count<="00000";
div_clk<='1';
END IF;
END IF;
END IF;
END PROCESS;
--------------------------------------------<<状态机ADC
PROCESS (clock)
BEGIN
IF RISING_EDGE(clock) THEN
IF reset='1' THEN
adc_state<=idle;
ELSE
adc_state<=adc_next_state;
END IF;
END IF;
END PROCESS;
---------------------------------------------<<ADC状态机转换逻辑
PROCESS (adc_state,ready_done,rec_done,conv_done,enable)
BEGIN
cs_n_r<='0';
bit_count_rst<='0';
data_ready_r<='0';
CASE adc_state IS --初始状态
WHEN idle=>
cs_n_r<='1';
bit_count_rst<='1'; --复位移位计数器.
IF enable='1' THEN
adc_next_state<=adc_ready;
ELSE
adc_next_state<=idle;
END IF;
WHEN adc_ready=> --准备接收
IF ready_done='1' THEN
adc_next_state<=adc_receive;
ELSE
adc_next_State<=adc_ready;
END IF;
WHEN adc_receive=> --接收数据
IF rec_done='1' THEN
adc_next_state<=adc_conversion;
ELSE
adc_next_state<=adc_receive;
END IF;
WHEN adc_conversion=> --转换前的采样的数据.
cs_n_r<='1';
IF conv_done='1' THEN
adc_next_state<=adc_data_load;
ELSE
adc_next_state<=adc_conversion;
END IF;
WHEN adc_data_load=>
data_ready_r<='1';--数据输出标志.
adc_next_state<=idle;
WHEN OTHERS=>adc_next_state<=idle;
END CASE;
END PROCESS;
PROCESS (clock)--位移位计数器
BEGIN
IF RISING_EDGE(clock) THEN
IF reset='1' THEN
bit_count<="000000";
ELSIF bit_count_rst='1' THEN
bit_count<="000000";
ELSIF div_clk='1' THEN
bit_count<=bit_count+1;
END IF;
END IF;
END PROCESS;
ready_done<='1' WHEN bit_count=4 ELSE '0';--准备读取数据
rec_done<='1' WHEN bit_count=19 ELSE '0';--接收数据完毕
conv_done<='1' WHEN bit_count=63 ELSE '0';--接收数据完毕
---------------------<<在接收位计数器4-20间8个adc clk
PROCESS(bit_count)
BEGIN
IF bit_count<20 AND bit_count>=4 THEN
adc_clk_r<=NOT bit_count(0);
ELSE
adc_clk_r<='0';
END IF;
END PROCESS;
PROCESS(clock)
BEGIN
IF RISING_EDGE(clock) THEN
buf1<=adc_clk_r;
buf2<=buf1;
END IF;
END PROCESS;
PROCESS(clock)--读取数据
BEGIN
IF RISING_EDGE(clock) THEN
IF(buf1='1' AND buf2='0' )THEN--ADC时钟上升沿
q<=q(6 DOWNTO 0) & sdat_in_r;
ELSIF data_ready_r='1' THEN --输出读取的数据.
data_out_r<=q;
END IF;
END IF;
END PROCESS;
END;