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

📄 simple_i2c.vhd

📁 自己写的iic配置芯片的源程序
💻 VHD
字号:
---- Simple I2C controller---- 1) No multimaster-- 2) No slave mode-- 3) No fifo's---- notes:-- Every command is acknowledged. Do not set a new command before previous is acknowledged.-- Dout is available 1 clock cycle later as cmd_ack--library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;entity simple_i2c is	port (		clk : in std_logic;		ena : in std_logic;		nReset : in std_logic;		clk_cnt : in unsigned(7 downto 0);	-- 4x SCL 		-- input signals		start,		stop,		read,		write,		ack_in : std_logic;		Din : in std_logic_vector(7 downto 0);		-- output signals		cmd_ack : out std_logic;		ack_out : out std_logic;		Dout : out std_logic_vector(7 downto 0);				-- i2c signals		SCL : inout std_logic;		SDA : inout std_logic	);end entity simple_i2c;architecture structural of simple_i2c is	component i2c_core is	port (		clk : in std_logic;		nReset : in std_logic;		clk_cnt : in unsigned(7 downto 0);		cmd : in std_logic_vector(2 downto 0);		cmd_ack : out std_logic;		busy : out std_logic;		Din : in std_logic;		Dout : out std_logic;		SCL : inout std_logic;		SDA : inout std_logic	);	end component i2c_core;	-- commands for i2c_core	constant CMD_NOP	: std_logic_vector(2 downto 0) := "000";	constant CMD_START	: std_logic_vector(2 downto 0) := "010";	constant CMD_STOP	: std_logic_vector(2 downto 0) := "011";	constant CMD_READ	: std_logic_vector(2 downto 0) := "100";	constant CMD_WRITE	: std_logic_vector(2 downto 0) := "101";	-- signals for i2c_core	signal core_cmd : std_logic_vector(2 downto 0);	signal core_ack, core_busy, core_txd, core_rxd : std_logic;	-- signals for shift register	signal sr : std_logic_vector(7 downto 0); -- 8bit shift register	signal shift, ld : std_logic;	-- signals for state machine	signal go, host_ack : std_logic;begin	-- hookup i2c core	u1: i2c_core port map (clk, nReset, clk_cnt, core_cmd, core_ack, core_busy, core_txd, core_rxd, SCL, SDA);	-- generate host-command-acknowledge	cmd_ack <= host_ack;		-- generate go-signal	go <= (read or write) and not host_ack;	-- assign Dout output to shift-register	Dout <= sr;	-- assign ack_out output to core_rxd (contains last received bit)	ack_out <= core_rxd;	-- generate shift register	shift_register: process(clk)	begin		if (clk'event and clk = '1') then			if (ld = '1') then				sr <= din;			elsif (shift = '1') then				sr <= (sr(6 downto 0) & core_rxd);			end if;		end if;	end process shift_register;	--	-- state machine	--	statemachine : block		type states is (st_idle, st_start, st_read, st_write, st_ack, st_stop);		signal state : states;		signal dcnt : unsigned(2 downto 0);	begin		--		-- command interpreter, translate complex commands into simpler I2C commands		--		nxt_state_decoder: process(clk, nReset, state)			variable nxt_state : states;			variable idcnt : unsigned(2 downto 0);			variable ihost_ack : std_logic;			variable icore_cmd : std_logic_vector(2 downto 0);			variable icore_txd : std_logic;			variable ishift, iload : std_logic;		begin			-- 8 databits (1byte) of data to shift-in/out			idcnt := dcnt;			-- no acknowledge (until command complete)			ihost_ack := '0';			icore_txd := core_txd;			-- keep current command to i2c_core			icore_cmd := core_cmd;			-- no shifting or loading of shift-register			ishift := '0';			iload := '0';			-- keep current state;			nxt_state := state;			case state is				when st_idle =>					if (go = '1') then						if (start = '1') then							nxt_state := st_start;								icore_cmd := CMD_START;						elsif (read = '1') then							nxt_state := st_read;							icore_cmd := CMD_READ;							idcnt := "111";						else							nxt_state := st_write;							icore_cmd := CMD_WRITE;							idcnt := "111";							iload := '1';						end if;					end if;				when st_start =>					if (core_ack = '1') then						if (read = '1') then							nxt_state := st_read;							icore_cmd := CMD_READ;							idcnt := "111";						else							nxt_state := st_write;							icore_cmd := CMD_WRITE;							idcnt := "111";							iload := '1';						end if;					end if;				when st_write =>					if (core_ack = '1') then						idcnt := dcnt -1;	-- count down Data_counter						icore_txd := sr(7);						core_txd<=icore_txd;--放在时钟同步里面就慢一个时钟周期。						if (dcnt = 0) then							nxt_state := st_ack;							icore_cmd := CMD_READ;						else							ishift := '1';--							icore_txd := sr(7);						end if;					end if;							when st_read =>					if (core_ack = '1') then						idcnt := dcnt -1;	-- count down Data_counter						ishift := '1';						if (dcnt = 0) then							nxt_state := st_ack;							icore_cmd := CMD_WRITE;							icore_txd := ack_in;						end if;					end if;							when st_ack =>					if (core_ack = '1') then						-- generate command acknowledge signal						ihost_ack := '1';						-- Perform an additional shift, needed for 'read' (store last received bit in shift register)						ishift := '1';						-- check for stop; Should a STOP command be generated ?						if (stop = '1') then							nxt_state := st_stop;							icore_cmd := CMD_STOP;						else							nxt_state := st_idle;							icore_cmd := CMD_NOP;						end if;					end if;				when st_stop =>					if (core_ack = '1') then						nxt_state := st_idle;						icore_cmd := CMD_NOP;					end if;				when others => -- illegal states					nxt_state := st_idle;					icore_cmd := CMD_NOP;			end case;			-- generate registers			if (nReset = '0') then				core_cmd <= CMD_NOP;				core_txd <= '0';								shift <= '0';				ld <= '0';				dcnt <= "111";				host_ack <= '0';				state <= st_idle;			elsif (clk'event and clk = '1') then				if (ena = '1') then					state <= nxt_state;					dcnt <= idcnt;					shift <= ishift;					ld <= iload;					core_cmd <= icore_cmd;				--	core_txd <= icore_txd;				--	test<=core_txd;					host_ack <= ihost_ack;				end if;			end if;		end process nxt_state_decoder;	end block statemachine;end architecture structural;------ I2C Core---- Translate simple commands into SCL/SDA transitions-- Each command has 5 states, A/B/C/D/idle---- start:	SCL	~~~~~~~~~~\____--	SDA	~~~~~~~~\______--		 x | A | B | C | D | i---- repstart	SCL	____/~~~~\___--	SDA	__/~~~\______--		 x | A | B | C | D | i---- stop	SCL	____/~~~~~~~~--	SDA	==\____/~~~~~--		 x | A | B | C | D | i----- write	SCL	____/~~~~\____--	SDA	==X=========X=--		 x | A | B | C | D | i----- read	SCL	____/~~~~\____--	SDA	XXXX=====XXXX--		 x | A | B | C | D | i---- Timing:		Normal mode	Fast mode------------------------------------------------------------------- Fscl		100KHz		400KHz-- Th_scl		4.0us		0.6us	High period of SCL-- Tl_scl		4.7us		1.3us	Low period of SCL-- Tsu:sta		4.7us		0.6us	setup time for a repeated start condition-- Tsu:sto		4.0us		0.6us	setup time for a stop conditon-- Tbuf		4.7us		1.3us	Bus free time between a stop and start condition--

⌨️ 快捷键说明

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