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

📄 i2c_core.vhd

📁 自己写的iic配置芯片的源程序
💻 VHD
字号:
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;entity 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 entity i2c_core;architecture structural of i2c_core is	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";	type cmds is (idle, start_a, start_b, start_c, start_d, stop_a, stop_b, stop_c, rd_a, rd_b, rd_c, rd_d, wr_a, wr_b, wr_c, wr_d);	signal state : cmds;	signal SDAo, SCLo : std_logic;	signal txd : std_logic;	signal clk_en, slave_wait :std_logic;	signal cnt : unsigned(7 downto 0) := clk_cnt;begin 	-- whenever the slave is not ready it can delay the cycle by pulling SCL low	slave_wait <= '1' when ((SCLo = '1') and (SCL = '0')) else '0';	-- generate clk enable signal	gen_clken: process(clk, nReset)	begin		if (nReset = '0') then			cnt <= (others => '0');			clk_en <= '1'; --'0';		elsif (clk'event and clk = '1') then			if (cnt = 0) then				clk_en <= '1';				cnt <= clk_cnt;			else				if (slave_wait = '0') then					cnt <= cnt -1;				end if;				clk_en <= '0';			end if;		end if;	end process gen_clken;	-- generate statemachine	nxt_state_decoder : process (clk, nReset, state, cmd, SDA)		variable nxt_state : cmds;		variable icmd_ack, ibusy, store_sda : std_logic;		variable itxd : std_logic;	begin		nxt_state := state;       --  state<=nxt_state;		icmd_ack := '0'; -- default no acknowledge		ibusy := '1'; -- default busy		store_sda := '0';		itxd := txd;		case (state) is			-- idle			when idle =>				case cmd is					when CMD_START =>						nxt_state := start_a;						icmd_ack := '1'; -- command completed					when CMD_STOP =>						nxt_state := stop_a;						icmd_ack := '1'; -- command completed					when CMD_WRITE =>						nxt_state := wr_a;						icmd_ack := '1'; -- command completed						itxd := Din;					when CMD_READ =>						nxt_state := rd_a;						icmd_ack := '1'; -- command completed					when others =>						nxt_state := idle;-- don't acknowledge NOP command						icmd_ack := '1'; -- command completed						ibusy := '0';				end case;			-- start			when start_a =>				nxt_state := start_b;			when start_b =>				nxt_state := start_c;			when start_c =>				nxt_state := start_d;			when start_d =>				nxt_state := idle;				ibusy := '0'; -- not busy when idle			-- stop			when stop_a =>				nxt_state := stop_b;			when stop_b =>				nxt_state := stop_c;			when stop_c =>--				nxt_state := stop_d;--			when stop_d =>				nxt_state := idle;				ibusy := '0'; -- not busy when idle			-- read			when rd_a =>				nxt_state := rd_b;			when rd_b =>				nxt_state := rd_c;			when rd_c =>				nxt_state := rd_d;				store_sda := '1';			when rd_d =>				nxt_state := idle;				ibusy := '0'; -- not busy when idle			-- write			when wr_a =>				nxt_state := wr_b;			when wr_b =>				nxt_state := wr_c;			when wr_c =>				nxt_state := wr_d;			when wr_d =>				nxt_state := idle;				ibusy := '0'; -- not busy when idle		end case;		-- generate regs		if (nReset = '0') then			state <= idle;			cmd_ack <= '0';			busy <= '0';			txd <= '0';			Dout <= '0';		elsif (clk'event and clk = '1') then			if (clk_en = '1') then				state <= nxt_state;				busy <= ibusy;				txd <= itxd;				if (store_sda = '1') then					Dout <= SDA;				end if;			end if;			cmd_ack <= icmd_ack and clk_en;		end if;	end process nxt_state_decoder;	--	-- convert states to SCL and SDA signals	--	output_decoder: process (clk, nReset, state)		variable iscl, isda : std_logic;	begin		case (state) is			when idle =>				iscl := SCLo; -- keep SCL in same state				isda := SDA; -- keep SDA in same state			-- start			when start_a =>				iscl := SCLo; -- keep SCL in same state (for repeated start)				isda := '1'; -- set SDA high			when start_b =>				iscl := '1';	-- set SCL high				isda := '1'; -- keep SDA high			when start_c =>				iscl := '1';	-- keep SCL high				isda := '0'; -- sel SDA low			when start_d =>				iscl := '0'; -- set SCL low				isda := '0'; -- keep SDA low			-- stop			when stop_a =>				iscl := '0'; -- keep SCL disabled				isda := '0'; -- set SDA low			when stop_b =>				iscl := '1'; -- set SCL high				isda := '0'; -- keep SDA low			when stop_c =>				iscl := '1'; -- keep SCL high				isda := '1'; -- set SDA high			-- write			when wr_a =>				iscl := '0';	-- keep SCL low--				isda := txd; -- set SDA				isda := Din;			when wr_b =>				iscl := '1';	-- set SCL high--				isda := txd; -- set SDA				isda := Din;			when wr_c =>				iscl := '1';	-- keep SCL high--				isda := txd; -- set SDA				isda := Din;			when wr_d =>				iscl := '0'; -- set SCL low--				isda := txd; -- set SDA				isda := Din;			-- read			when rd_a =>				iscl := '0'; -- keep SCL low				isda := '1'; -- tri-state SDA			when rd_b =>				iscl := '1'; -- set SCL high				isda := '1'; -- tri-state SDA			when rd_c =>				iscl := '1'; -- keep SCL high				isda := '1'; -- tri-state SDA			when rd_d =>				iscl := '0'; -- set SCL low				isda := '1'; -- tri-state SDA		end case;		-- generate registers		if (nReset = '0') then			SCLo <= '1';			SDAo <= '1';		elsif (clk'event and clk = '1') then			if (clk_en = '1') then				SCLo <= iscl;				SDAo <= isda;			end if;		end if;	end process output_decoder;	SCL <= '0' when (SCLo = '0') else '1'; -- since SCL is externally pulled-up convert a '1' to a 'Z'(tri-state)	SDA <= '0' when (SDAo = '0') else '1'; -- since SDA is externally pulled-up convert a '1' to a 'Z'(tri-state) --   test<=clk_en;--	SCL <= SCLo;--	SDA <= SDAo;end architecture structural;

⌨️ 快捷键说明

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