i2c.txt

来自「基于FPGA的I2C总线主控器的设计与实现」· 文本 代码 · 共 132 行

TXT
132
字号
LIBRARY ieee; 
USE ieee.std_logic_1164.all;
use IEEE.std_logic_ARITH.all;
use IEEE.std_logic_UNSIGNED.all;

--  Entity Declaration

ENTITY STATE_CONTROL IS
	-- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE!
	PORT
	(
		CLK : IN STD_LOGIC;
		RST : IN STD_LOGIC;
		EN : IN STD_LOGIC;
		OV : IN STD_LOGIC;
		SDA_IN : IN STD_LOGIC;
		SCL_IN : IN STD_LOGIC;
		WR : IN STD_LOGIC;
		
		CLK_GATE : OUT STD_LOGIC;
		SDA_OUT : OUT STD_LOGIC;
		SDA_S : OUT STD_LOGIC;
		SDA_T : OUT STD_LOGIC;
		SCL_OUT : OUT STD_LOGIC;
		SCL_S : OUT STD_LOGIC;
		CLR : OUT STD_LOGIC;
		ACK : OUT STD_LOGIC
	);
	-- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE!
	
END STATE_CONTROL;

--  Architecture Body
architecture STATE_CONTROL_arch of STATE_CONTROL is
type StateType is (idle,start,writeB,acks,ackw1,ackw11,ackw12,ackw2,ackw3,stop);
signal present_state,next_state:StateType;

begin
process(CLK)
begin
	if(CLK'event and CLK='1')then
		if RST='1' then
			present_state<=idle;
		else
			present_state<=next_state;
		end if;
	end if;
end process;

process(present_state,EN,OV,SDA_IN,SCL_IN,WR)
begin
	case present_state is
		when idle=>
			CLK_GATE<='1';
			SDA_OUT<='1';SDA_S<='1';SDA_T<='0';
			SCL_OUT<='1';SCL_S<='1';
			CLR<='1';ACK<='1';
			if EN='1' then
				SDA_T<='0';
				next_state<=start; 
			else
				next_state<=idle;
			end if;						
		when start=>
			SDA_OUT<='0';CLR<='0';
			next_state<=acks;
		when writeB=>--写字节
			if EN='0' then
				next_state<=stop;
				SDA_OUT<='0';SDA_T<='0';
				SCL_OUT<='1';SCL_S<='1';
				ACK<='1';		
			elsif WR='0' then
				CLK_GATE<='0';
				SDA_S<='0';SDA_T<='0';
				SCL_S<='0';
				ACK<='1';
				next_state<=ackw1;
			else
				next_state<=writeB;
			end if;
		when acks=>--开始应答
			SDA_T<='0';
			SCL_OUT<='0';
			ACK<='0';
			next_state<=writeB;
		when ackw1=>--写应答 
			if OV='0' then
				CLK_GATE<='1';
				--SDA_S<='1';SDA_OUT<='1';
				next_state<=ackw11;
			else
				next_state<=ackw1;
			end if;	
		when ackw11=>
			CLR<='1';
			if SCL_IN='1' then
				next_state<=ackw12;
			else
				next_state<=ackw11;
			end if;
		when ackw12=>
			CLR<='0';
			if SCL_IN='0' then
				SDA_S<='1';SDA_OUT<='1';
				next_state<=ackw2;	
			else
				next_state<=ackw12;
			end if;	
		when ackw2=>
			SDA_T<='1';
			next_state<=ackw3;
		when ackw3=>
			if SCL_IN='1' then
				if SDA_IN='0' then
					ACK<='0';
					next_state<=writeB;
				else
					CLK_GATE<='0';
					SDA_S<='0';SDA_T<='0';
					next_state<=ackw1;
				end if;
			else
				next_state<=ackw3;
			end if;
		when stop=>
			SDA_OUT<='1';
			next_state<=idle;
	end case;
end process;
end STATE_CONTROL_arch;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?