📄 read_from_24c02.vhd
字号:
--文件名:read_from_24c02.vhd
--功 能:读出存储芯片24c02中数据
--说 明:读出先前写入存储芯片24c02中的数据
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL; --读成功
entity read_from_24c02 is
Port ( sysclk: in std_logic;--系统时钟信号
reset : in std_logic;--系统复位
sda,scl : inout std_logic;
cs: out std_logic;
led: out std_logic_vector(8 downto 1)
);
end read_from_24c02;
architecture Behavioral of read_from_24c02 is
type state is (
prepare,--总线空闲状态下,SDA和SCL必须同时为高电平
start,--启动状态下,SDA出现负跳变,数据传输开始
transmit_slave_address,-- 传送7位地址和读写控制器位R/W,为1表示读数据
check_ack1,--应答信号
transmit_sub_address,
check_ack2,
nack,--非应答位状态下
start1,
transmit_read,
check_ack3,
read_data,
stop,
idel
); --定义状态机的各子状态;
signal current_state:state; --定义信号;
signal clock:std_logic;
begin
pulse:process(sysclk,reset) --进程1,分频得到周期为0.1s的时钟信号
variable count:integer range 0 to 5000000;
begin
if reset='0' then count:=0;
elsif rising_edge(sysclk) then
count:=count+1;
if count=2500000 then clock<='1';
elsif count=5000000 then clock<='0';count:=0; --frequency:10Hz time:0.1s
end if;
end if;
end process pulse;
statemachine:process(clock,reset) --进程2,状态机的转换
variable slave_address,sub_address:std_logic_vector(8 downto 1);
variable cnt:std_logic_vector(6 downto 0);
variable cnt1:integer range 0 to 8;
variable count1:integer range 0 to 40;
begin
if reset='0' then count1:=0;cnt:="0000000";cnt1:=8;cs<='1';
sda<='1';scl<='1';slave_address:="10100000";sub_address:="00000011";
led<="11111111";--复位状态下,
current_state<=prepare;
elsif rising_edge(clock) then
case current_state is
when prepare=>cnt:=cnt+1;-- --准备状态,等各个器件复位
--CNT由0000000变为0000001再次出现低电平时,进入开始状态
if cnt="0000010" then cnt:="0000000";current_state<=start;
else current_state<=prepare;
end if;
when start=>count1:=count1+1; led<="00000001"; --起始信号产生状态
case count1 is--产生SDA和SCL脉宽信号
when 1=>sda<='1';
when 3=>scl<='1';
when 5=>sda<='0';
when 7=>scl<='0';
when 9=>count1:=0;current_state<=transmit_slave_address;
when others=>null;
end case;
when transmit_slave_address=>count1:=count1+1;led<="00000010"; --发送器件从地址
case count1 is
when 1=>sda<=slave_address(cnt1);
when 3=>scl<='1';
when 6=>scl<='0';
when 8=>cnt1:=cnt1-1;count1:=0;
if cnt1=0 then cnt1:=8;
current_state<=check_ack1;
else current_state<=transmit_slave_address;
end if;
when others=>null;
end case;
when check_ack1=>count1:=count1+1;led<="00000100"; --查询应答信号
case count1 is
when 3=>sda<='0';
when 6=>scl<='1';
when 8=>scl<='0';
when 10=>
current_state<=transmit_sub_address;
count1:=0;
when others=>null;
end case;
when transmit_sub_address=>count1:=count1+1;led<="00001000"; --发送器件子地址
case count1 is
when 1=>sda<=sub_address(cnt1);
when 3=>scl<='1';
when 6=>scl<='0';
when 9=>cnt1:=cnt1-1;count1:=0;
if cnt1=0 then cnt1:=8;
current_state<=check_ack2;
else current_state<=transmit_sub_address;
end if;
when others=>null;
end case;
when check_ack2=>count1:=count1+1;led<="00010000"; --查询应答信号
case count1 is
when 3=>sda<='0';
when 6=>scl<='1';
when 8=>scl<='0';
when 10=>
current_state<=start1;
count1:=0;
when others=>null;
end case;
when start1=>count1:=count1+1;led<="01000000"; --重新起始信号产生状态
case count1 is
when 1=>sda<='1';
when 3=>scl<='1';
when 6=>sda<='0';
when 8=>scl<='0';
when 10=>count1:=0;current_state<=transmit_read;
slave_address:="10100001";
when others=>null;
end case;
when transmit_read=>count1:=count1+1;led<="10000000"; --发送器件从地址
case count1 is
when 1=>sda<=slave_address(cnt1);
when 4=>scl<='1';
when 6=>scl<='0';
when 9=>cnt1:=cnt1-1;count1:=0;
if cnt1=0 then cnt1:=8;
current_state<=check_ack3;
else current_state<=transmit_read;
end if;
when others=>null;
end case;
when check_ack3=>count1:=count1+1;led<="00000000"; --查询应答信号
case count1 is
when 3=>sda<='0';
when 6=>scl<='1';
when 8=>scl<='0';
when 10=>
current_state<=read_data;
count1:=0;
when others=>null;
end case;
when read_data=>count1:=count1+1; --读操作
case count1 is
when 1=>sda<='Z';
when 4=>scl<='1';
when 8=>led(cnt1)<=sda;
when 10=>scl<='0';
when 12=>cnt1:=cnt1-1;count1:=0;
if cnt1=0 then cnt1:=8;
current_state<=stop;
else current_state<=read_data;
end if;
when others=>null;
end case;
when stop=>count1:=count1+1; --产生停止信号
case count1 is
when 1=>sda<='0';
when 3=>scl<='1';
when 6=>sda<='1';
when 8=>count1:=0;current_state<=idel;
when others=>null;
end case;
when idel=>sda<='1';scl<='1';current_state<=idel;
when others=>null;
end case;
end if;
end process;
end Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -