library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
en
tity end_iic is
port(scl , sda : out std_logic;
en : in std_logic; --使能
output : out std_logic; --输出为高时出元
reset , clk : in std_logic;
to_wait : inout std_logic;
en_wait : inout std_logic;
to_process : inout std_logic); --进入
元件时为高
end end_iic;
architecture Behavioral of end_iic is
component wait_time is
port(clk , reset : in std_logic;
output : out std_logic; --输出为一时出元件
en : in std_logic; --使能
to_process : inout std_logic --变化时进入外部元件的进程
);
end component;
type state is(sda_down ,scl_up , sda_up , idle); --顺序不对会出错
signal pre_state : state;
signal nex_state : state;
signal a_scl : std_logic;
signal a_sda : std_logic;
signal b_scl : std_logic;
signal b_sda : std_logic;
-- signal to_process : std_logic;
-- signal to_wait : std_logic := '1';
-- signal en_wait : std_logic;
signal out_wait : std_logic;
signal init : std_logic;
-- signal count : integer range 0 to 1;
signal complete : std_logic;
begin
scl <= a_scl or (a_scl or b_scl);
sda <= a_sda or (a_sda or b_sda);
process(reset , clk , en)
begin
if(reset = '1') then --初始化
a_sda <= '1';
a_scl <= '1'; --拉高 时钟线和信号线
init <= '0';
elsif(clk ' event and clk = '1' and en = '1') then
if(complete = '1' or init = '0') then --初始化 init为0表示第一次进入 complete为0表示已经完成过一次
pre_state <= scl_up; --初始化pre_state
a_scl <= '0';
a_sda <= '0';
init <= '1';
else
a_scl <= '0';
a_sda <= '0';
pre_state <= nex_state;
end if;
end if;
end process;
process(pre_state , to_process , out_wait) --定义下一状态
begin
case pre_state is
when scl_up => --进入元件后的第一个状态
b_scl <= '1'; --拉高时钟线
output <= '0'; --输出拉低使外部元件可以进入
complete <= '0'; --使下一个时钟上升沿不再初始化
if(to_wait /= '0') then --初次进入延时使能延时元件 有时间让延时的输出拉低
en_wait <= '1';
to_wait <= '0';
nex_state <= scl_up;
elsif(out_wait = '1') then --延时元件输出为高 延时结束
nex_state <= sda_down;
to_wait <= '1';
else
en_wait <= '0'; --使能为低此时延时内部使能为高
nex_state <= scl_up;
end if;
when sda_down=>
b_sda <= '0';
if(to_wait = '1') then
en_wait <= '1';
to_wait <= '0';
nex_state <= sda_down;
elsif(out_wait = '1') then
nex_state <= sda_up;
to_wait <= '1';
else
en_wait <= '0';
nex_state <= sda_down;
end if;
when sda_up => --scl拉低状态
b_sda <= '1';
if(to_wait = '1') then --初次进入等待元件
en_wait <= '1';
to_wait <= '0';
nex_state <= sda_up;
elsif(out_wait = '1') then
nex_state <= idle; --拉低scl
to_wait <= '1';
else
en_wait <= '0';
nex_state <= sda_up;
end if;
when idle =>
nex_state <= idle;
output <= '1';
complete <= '1';
end case;
end process;
u1 : wait_time port map(clk => clk,
reset => reset,
en => en_wait,
output => out_wait,
to_process => to_process);
end Behavioral;
这个程序红字部分若把sda_down 放到第二位则波形会出错,不知道是为什么。--注附件为本程序和test beach文件。
-
-
end_iic.zip
下载积分: 积分 -1 分
285.13 KB, 下载次数: 4, 下载积分: 积分 -1 分
一周热门 更多>