📄 rei2c.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity rei2c is
port(
reset : in std_logic;
clk : in std_logic;
rd : in std_logic;
dout : out std_logic_vector(7 downto 0);
oe : out std_logic;
sda : inout std_logic;
scl : out std_logic
);
end rei2c;
architecture RTL of rei2c is
constant control1data : std_logic_vector(7 downto 0):="10100000";--"1010","000"-A2A1A0,"0"-write
constant control2data : std_logic_vector(7 downto 0):="10100001";--"1010","000"-A2A1A0,"1"-read
constant highaddress : std_logic_vector(7 downto 0):="00000000";
constant lowaddress : std_logic_vector(7 downto 0):="00000000";
signal datacount : integer range 0 to 8;
signal data : std_logic_vector(7 downto 0);
signal i2c_active : std_logic;
signal i : integer range 0 to 32767;
TYPE STATE_TYPE IS (initial1,start1,control1,highadd,lowadd,initial2,start2,control2,transfer,stop,quit);
signal state : STATE_TYPE;
signal count : std_logic_vector(2 downto 0);
begin
process(reset,clk) --procduce scl
begin
if reset='0' then
scl<='0';
elsif clk'event and clk='1' then
scl<=count(2);
end if;
end process;
process(reset,clk) --produce sda
begin
if reset='0' then
i2c_active<='0';
sda<='1';
count<="000";
datacount<=0;
state<=initial1;
i<=0;
dout<="00000000";
oe<='0';
elsif clk'event and clk='1' then
if count(0)='0' then
case state is
when initial1 =>
i2c_active<='0';
if count(2 downto 1)="11" then
sda<= '1';
state<=start1;
end if;
when start1 =>
if count(2 downto 1)="11" then
sda <= '0';
state <= control1;
end if;
when control1 =>
if count(2 downto 1)="01" then
if(datacount = 0) then sda <= control1data(7);
elsif(datacount = 1)then sda <= control1data(6);
elsif(datacount = 2) then sda <= control1data(5);
elsif(datacount = 3) then sda <= control1data(4);
elsif(datacount = 4) then sda <= control1data(3);
elsif(datacount = 5) then sda <= control1data(2);
elsif(datacount = 6) then sda <= control1data(1);
elsif(datacount = 7) then sda <= control1data(0);
else sda<='0'; state<=highadd;
end if;
if(datacount=8)then datacount<=0;
else datacount<=datacount+1;
end if;
end if;
when highadd =>
if count(2 downto 1)="01" then
if(datacount = 0) then sda <= highaddress(7);
elsif(datacount = 1)then sda <= highaddress(6);
elsif(datacount = 2) then sda <= highaddress(5);
elsif(datacount = 3) then sda <= highaddress(4);
elsif(datacount = 4) then sda <= highaddress(3);
elsif(datacount = 5) then sda <= highaddress(2);
elsif(datacount = 6) then sda <= highaddress(1);
elsif(datacount = 7) then sda <= highaddress(0);
else sda<='0'; state<=lowadd;
end if;
if(datacount=8)then datacount<=0;
else datacount<=datacount+1;
end if;
end if;
when lowadd =>
if count(2 downto 1)="01" then
if(datacount = 0) then sda <= lowaddress(7);
elsif(datacount = 1)then sda <= lowaddress(6);
elsif(datacount = 2) then sda <= lowaddress(5);
elsif(datacount = 3) then sda <= lowaddress(4);
elsif(datacount = 4) then sda <= lowaddress(3);
elsif(datacount = 5) then sda <= lowaddress(2);
elsif(datacount = 6) then sda <= lowaddress(1);
elsif(datacount = 7) then sda <= lowaddress(0);
else sda<='0'; state<=initial2;
end if;
if(datacount=8)then datacount<=0;
else datacount<=datacount+1;
end if;
end if;
when initial2 =>
i2c_active<='0';
if count="010" then
state<=start2;
sda<= '1';
end if;
when start2 =>
if count(2 downto 1)="11" then
sda <= '0';
state <= control2;
end if;
when control2 =>
if count(2 downto 1)="01" then
if(datacount = 0) then sda <= control2data(7);
elsif(datacount = 1)then sda <= control2data(6);
elsif(datacount = 2) then sda <= control2data(5);
elsif(datacount = 3) then sda <= control2data(4);
elsif(datacount = 4) then sda <= control2data(3);
elsif(datacount = 5) then sda <= control2data(2);
elsif(datacount = 6) then sda <= control2data(1);
elsif(datacount = 7) then sda <= control2data(0);
else sda<='0'; state<=transfer;
end if;
if(datacount=8)then datacount<=0;
else datacount<=datacount+1;
end if;
end if;
when transfer =>
if rd='1' then
if count(2 downto 1)="01" then
if(datacount=8)then datacount<=0;
if i=32767 then
i<=0;
state<=stop;
else i<=i+1;
end if;
else datacount<=datacount+1;
end if;
end if;
if count="010" then
if datacount<8 then
sda<='Z';
else sda<='0';
end if;
end if;
if count="110" then
if datacount>0 then
data(8-datacount)<=sda;
-- elsif datacount=0 then
-- dout<=data;
end if;
end if;
if count="010" then
if datacount=8 then
dout<=data;
oe<='1';
else oe<='0';
end if;
end if;
end if;
when stop =>
if count(2 downto 1)="11" then
sda<='1';
elsif count(2 downto 1) ="01" then
state <= quit;
end if;
if count="010" then
oe<='0';
end if;
when quit =>
sda<='1';
count<="000";
i2c_active<='1';
end case;
end if;
if i2c_active='0' then
if count="111" then
count<=(others=>'0');
else count <=count+1;
end if;
else
count<=(others=>'0');
end if;
end if;
end process;
end RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -