⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.vhd

📁 几个SPI
💻 VHD
字号:
---------------------------------------------------------------------------------------------------
--*************************************************************************************************
--  CreateDate  :  2007-08-21 
--  ModifData   :  2007-08-21 
--  Description :  I2C ( 24LC16B )
--  Author      :  Explorer01 
--  Version     :  V1.0  
--*************************************************************************************************
---------------------------------------------------------------------------------------------------

-- VHDL library Declarations 
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.std_logic_unsigned.ALL;

---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- The Entity Declarations 
ENTITY I2C IS
	PORT 
	(
		RESET	: IN STD_LOGIC; 
		GCLK	: IN STD_LOGIC; 
		CLK		: IN STD_LOGIC; 
		
		SCL : OUT 	STD_LOGIC; 
		SDA : INOUT STD_LOGIC; 
		
		I2C_CS  : IN STD_LOGIC; 
		I2C_RW	: IN STD_LOGIC; 
		I2C_STRB: IN STD_LOGIC; 
		
		I2C_Address : IN 	STD_LOGIC_VECTOR(1 DOWNTO 0);
		I2C_Data	: INOUT STD_LOGIC_VECTOR(7 DOWNTO 0)
	);
END I2C;

---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- The Architecture of Entity Declarations 
ARCHITECTURE Behavioral OF I2C IS
	-- 
	CONSTANT CON_IDLE		: STD_LOGIC_VECTOR(2 DOWNTO 0) := "000"; 
	CONSTANT CON_START		: STD_LOGIC_VECTOR(2 DOWNTO 0) := "001"; 
	CONSTANT CON_CONTROL	: STD_LOGIC_VECTOR(2 DOWNTO 0) := "010"; 
	CONSTANT CON_ADDRESS	: STD_LOGIC_VECTOR(2 DOWNTO 0) := "011"; 
	CONSTANT CON_DATA		: STD_LOGIC_VECTOR(2 DOWNTO 0) := "100"; 
	CONSTANT CON_STOP		: STD_LOGIC_VECTOR(2 DOWNTO 0) := "101"; 
	CONSTANT CON_ACK		: STD_LOGIC_VECTOR(2 DOWNTO 0) := "110"; 
	
	SIGNAL STEP : STD_LOGIC_VECTOR(2 DOWNTO 0);
	SIGNAL CountSTEP1, CountSTEP2 : INTEGER RANGE 0 TO 31;	-- 32 
	
	SIGNAL Start, Enable : STD_LOGIC; 
	SIGNAL DataOUT : STD_LOGIC_VECTOR(7 DOWNTO 0); 
	
	-- Clock: 
	SIGNAL CLK200KHz, CLK100KHz, CLKSCL : STD_LOGIC; 
	
	-- 
	SIGNAL Value : STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL COMMAND, ADDRESS, DATA : STD_LOGIC_VECTOR(7 DOWNTO 0);
	
	-- 
	SIGNAL FLAG, READ 	 : STD_LOGIC; 
	SIGNAL SDAIN, SDAOUT : STD_LOGIC; 
	
BEGIN
	--==============================================
	-------------------------------------------------
	-- The Flag of Enable 
	PROCESS( RESET, GCLK, I2C_STRB, I2C_RW )
		VARIABLE Count : STD_LOGIC_VECTOR(1 DOWNTO 0);
	BEGIN 
		IF	 ( RESET='0'  ) THEN Count := "11";
		ELSIF( I2C_RW='0' ) THEN Count := "00";
		ELSIF( GCLK'EVENT AND GCLK='1' 	) THEN 
			IF( Count<"11" ) THEN Count := Count + 1; 
			END IF; 
		END IF; 
		
		IF( Count="10" ) THEN Enable <= '1';
		ELSE 				  Enable <= '0';
		END IF; 
	END PROCESS;
	
	-------------------------------------------------
	-- The main interface 
	PROCESS( RESET, GCLK, I2C_CS, I2C_STRB, I2C_RW, I2C_Address, I2C_Data, DataOUT, Value, COMMAND, CountSTEP1, FLAG, READ )
		VARIABLE Count : STD_LOGIC_VECTOR(1 DOWNTO 0);
	BEGIN 
		-------------------------------------
		-- Bidirectional I/O Port 
		IF( RESET='0' OR I2C_CS='1' ) THEN 
			I2C_Data <= (OTHERS=>'Z');
		ELSE 
			IF( I2C_RW='0' ) THEN Value <= I2C_Data; 	-- Receive Command 
			ELSE 				  I2C_Data <= DataOUT; 	-- Send the data readed from 24LC16B 
			END IF; 
		END IF; 
		
		-------------------------------------
		IF( I2C_RW='0' AND I2C_STRB='1' ) THEN 
			IF	 ( I2C_Address="00" ) THEN COMMAND <= Value; 
			ELSIF( I2C_Address="01" ) THEN ADDRESS <= Value; 
			ELSIF( I2C_Address="10" ) THEN DATA	   <= Value; 
			END IF; 
		END IF; 
		
		-------------------------------------
		-- 
		IF( RESET='0' OR (FLAG='1' AND CountSTEP1=11) ) THEN FLAG <= '0'; 
		ELSIF( I2C_RW'EVENT AND I2C_RW='1' ) THEN 
			IF( COMMAND(0)='1' ) THEN FLAG <= '1'; 
			END IF; 
		END IF; 
		
		-------------------------------------
		IF( RESET='0' OR READ='0' ) THEN Count := (OTHERS=>'0');
		ELSIF( GCLK'EVENT AND GCLK='1' ) THEN 
			IF( Count<"11" ) THEN Count := Count + 1; 
			END IF; 
		END IF; 
		
		IF	 ( RESET='0' OR Count="01" ) THEN READ <= '0';
		ELSIF( FLAG'EVENT AND FLAG='0' ) THEN READ <= '1';
		END IF; 
		
	END PROCESS;
	
	--==============================================
	------------------------------------------------
	-- GCLK: 100K Hz For Clock Frequency 
	PROCESS( RESET, GCLK, Start )
		VARIABLE Count : STD_LOGIC_VECTOR(2 DOWNTO 0);
	BEGIN 
		IF( RESET='0' OR Start='0' ) THEN 
			Count := (OTHERS=>'0');
		ELSIF( GCLK'EVENT AND GCLK='1' ) THEN 
			-- 100K 
			IF( Count>"011" ) THEN Count := (OTHERS=>'0');
			ELSE				   Count := Count + 1;
			END IF;
		END IF;
		
		IF( Count<"011" ) THEN  CLK200KHz <= '0'; 
		ELSE 					CLK200KHz <= '1'; 
		END IF; 
	END PROCESS;
	
	-------------------------------------------------
	-- GCLK: 100K Hz For Data Change 
	PROCESS( RESET, CLK200KHz )
	BEGIN 
		IF	 ( RESET='0' 						 ) THEN CLK100KHz <= '1'; 
		ELSIF( CLK200KHz'EVENT AND CLK200KHz='0' ) THEN CLK100KHz <= NOT CLK100KHz; 
		END IF;
	END PROCESS;
	
	-------------------------------------------------
	-- GCLK: 100K Hz For Clock Frequency 
	PROCESS( RESET, CLK200KHz )
	BEGIN 
		IF	 ( RESET='0' 						 ) THEN CLKSCL <= '1'; 
		ELSIF( CLK200KHz'EVENT AND CLK200KHz='1' ) THEN CLKSCL <= NOT CLKSCL; 
		END IF;
	END PROCESS;
	
	--==============================================
	------------------------------------------------
	-- The Flag of start 
	PROCESS( RESET, Enable, CountSTEP2 )
	BEGIN 
		IF	 ( RESET='0' OR CountSTEP2=1 ) THEN Start <= '0'; 
		ELSIF( Enable='1' ) THEN Start <= '1'; 
		END IF; 
	END PROCESS;
	
	------------------------------------------------
	-- CountSTEP1 For Step Change 
	PROCESS( RESET, Start, CLK100KHz, CountSTEP1, COMMAND, READ )
	BEGIN 
		IF( RESET='0' OR Start='0' OR READ='1' ) THEN CountSTEP1 <= 31; 
		ELSE 
			IF( CLK100KHz'EVENT AND CLK100KHz='0' ) THEN 
				IF( COMMAND(0)='1' AND FLAG='0' AND CountSTEP1=22 ) THEN CountSTEP1 <= 12; -- Read 
				ELSE 													 CountSTEP1 <= CountSTEP1 - 1; 
				END IF; 
			END IF; 
		END IF; 
	END PROCESS;
	
	------------------------------------------------
	-- CountSTEP2 For Stop 
	PROCESS( RESET, Start, CLK100KHz, CountSTEP2, COMMAND, READ )
	BEGIN 
		IF( RESET='0' OR Start='0' OR READ='1' ) THEN CountSTEP2 <= 31; 
		ELSE 
			IF( CLK100KHz'EVENT AND CLK100KHz='1' ) THEN 
				IF( COMMAND(0)='1' AND FLAG='0' AND CountSTEP2=22 ) THEN CountSTEP2 <= 13; -- Read 
				ELSE 													 CountSTEP2 <= CountSTEP2 - 1; 
				END IF; 
			END IF; 
		END IF; 
	END PROCESS;
	
	------------------------------------------------
	-- STEP 
	PROCESS( RESET, CountSTEP1 )
	BEGIN 
		IF	 ( RESET='0'					   ) THEN STEP <= CON_IDLE; 
		ELSIF( CountSTEP1=30				   ) THEN STEP <= CON_START; 
		ELSIF( CountSTEP1>21 AND CountSTEP1<30 ) THEN STEP <= CON_CONTROL; 
		ELSIF( CountSTEP1>12 AND CountSTEP1<21 ) THEN STEP <= CON_ADDRESS; 
		ELSIF( CountSTEP1>3  AND CountSTEP1<12 ) THEN STEP <= CON_DATA; 
		ELSIF( CountSTEP1=2 				   ) THEN STEP <= CON_STOP; 
		ELSIF( CountSTEP1=21 OR CountSTEP1=12 OR CountSTEP1=3 ) THEN STEP <= CON_ACK; 
		ELSE										  STEP <= CON_IDLE; 
		END IF; 
	END PROCESS;
	
	--==============================================
	------------------------------------------------
	-- 
	PROCESS( RESET, SDA, SDAIN, SDAOUT, Start, STEP, CountSTEP1, CountSTEP2, CLK100KHz, CLKSCL, COMMAND, ADDRESS, DATA, FLAG )
	BEGIN 
		-------------------------------------
		-- SCL 
		IF( RESET='0' OR Start='0' ) THEN SCL <= 'Z'; 
		ELSIF( CountSTEP1=31 ) THEN SCL <= 'Z'; 
		ELSIF( CountSTEP1=30 ) THEN SCL <= NOT CLK100KHz; 
		ELSIF( CountSTEP1=2  ) THEN 
			IF( CountSTEP2=3 ) THEN SCL <= '0'; 
			ELSE 					SCL <= '1'; 
			END IF; 
		ELSIF( CountSTEP1>2  ) THEN SCL <= CLKSCL; 
		ELSE SCL <= 'Z'; 
		END IF; 
		
		-------------------------------------
		-- SDA 
		CASE STEP IS 
			WHEN CON_IDLE 	=> SDA <= '1'; 
			WHEN CON_START 	=> SDA <= '0'; 
			WHEN CON_CONTROL=> 
				IF( FLAG='1' AND CountSTEP1=22 ) THEN SDA <= '0'; 
				ELSE 								  SDA <= COMMAND( CountSTEP1-22 ); 
				END IF; 
			WHEN CON_ADDRESS=> 
				SDA <= ADDRESS( CountSTEP1-13 ); 
			WHEN CON_DATA 	=> 
				IF( COMMAND(0)='1' ) THEN 	-- Read From 24LC16B 
					IF( CLKSCL='1' ) THEN DataOUT( CountSTEP1-4 ) <= SDA; 
					ELSE				  SDA <= 'Z'; 
					END IF; 
				ELSE 						-- Write To 24LC16B 
					SDA <= DATA( CountSTEP1-4 );
				END IF; 
			WHEN CON_STOP 	=> SDA <= '0'; 
			------------------------------------
			WHEN CON_ACK 	=> SDA <= 'Z'; 
			WHEN OTHERS 	=> SDA <= '1'; 
		END CASE; 
	END PROCESS;
END Behavioral;

⌨️ 快捷键说明

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