?? 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 + -