📄 i2c_controller.vhd
字号:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY I2C_Controller IS
port
(
CLOCK : in STD_LOGIC;
I2C_SCLK : out STD_LOGIC; --I2C CLOCK
I2C_SDAT : inout STD_LOGIC; --I2C DATA
I2C_DATA : in STD_LOGIC_VECTOR(23 downto 0); --DATA:[SLAVE_ADDR,SUB_ADDR,DATA]
GO : in STD_LOGIC; --GO transfor
ENDE : out STD_LOGIC; --END transfor
ACK : out STD_LOGIC; --ACK
RESET : in STD_LOGIC--;
);
END I2C_Controller;
ARCHITECTURE I2C OF I2C_Controller IS
SIGNAL SD_COUNTER : UNSIGNED(5 DOWNTO 0);
SIGNAL SCLK : STD_LOGIC;
SIGNAL SDO : STD_LOGIC;
SIGNAL ACK1 : STD_LOGIC;
SIGNAL ACK2 : STD_LOGIC;
SIGNAL ACK3 : STD_LOGIC;
SIGNAL SD : STD_LOGIC_VECTOR(23 downto 0);
BEGIN
I2C_SCLK <= ((SCLK)or(not CLOCK))when((SD_COUNTER >= 4)and(SD_COUNTER <=30))else SCLK;
I2C_SDAT <= 'Z' when SDO='1' else '0';
ACK <= ACK1 or ACK2 or ACK3;
process(CLOCK,RESET)
begin
if(RESET = '0')then
SD_COUNTER<="111111";
SCLK<='1';
SDO<='1';
ACK1<='0';
ACK2<='0';
ACK3<='0';
ENDE<='1';
elsif(rising_edge(CLOCK))then
if (GO='0')then
SD_COUNTER<="000000";
else
if(SD_COUNTER < "111111")then SD_COUNTER<=SD_COUNTER+1; end if;
end if;
---
case(SD_COUNTER)is
when "000000" => ACK1<='0'; ACK2<='0'; ACK3<='0'; ENDE<='0'; SDO<='1'; SCLK<='1';
--start
when "000001" => SD<=I2C_DATA; SDO<='0';
when "000010" => SCLK<='0';
--SLAVE ADDR
when "000011" => SDO<=SD(23);
when "000100" => SDO<=SD(22);
when "000101" => SDO<=SD(21);
when "000110" => SDO<=SD(20);
when "000111" => SDO<=SD(19);
when "001000" => SDO<=SD(18);
when "001001" => SDO<=SD(17);
when "001010" => SDO<=SD(16);
when "001011" => SDO<='1';--ACK
--SUB ADDR
when "001100" => SDO<=SD(15); ACK1<=I2C_SDAT;
when "001101" => SDO<=SD(14);
when "001110" => SDO<=SD(13);
when "001111" => SDO<=SD(12);
when "010000" => SDO<=SD(11);
when "010001" => SDO<=SD(10);
when "010010" => SDO<=SD(09);
when "010011" => SDO<=SD(08);
when "010100" => SDO<='1';--ACK
--DATA
when "010101" => SDO<=SD(07); ACK2<=I2C_SDAT;
when "010110" => SDO<=SD(06);
when "010111" => SDO<=SD(05);
when "011000" => SDO<=SD(04);
when "011001" => SDO<=SD(03);
when "011010" => SDO<=SD(02);
when "011011" => SDO<=SD(01);
when "011100" => SDO<=SD(00);
when "011101" => SDO<='1';--ACK
--stop
when "011110" => SDO<='0'; SCLK<='0'; ACK3<=I2C_SDAT;
when "011111" => SCLK<='1';
when "111111" => SDO<='1'; ENDE<='1';
when others => NULL;
end case;
---
end if;
end process;
END I2C;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -