📄 write_to_24c02.vhd
字号:
--文件名:write_to_24c02.vhd
--功 能:将数据写入存储芯片24c02中
--说 明:程序设计中使用了状态机,在写的时候变化到每个状态均点亮相应的二极管,
--使我们能一目了然的看到状态的变化以及何时写成功,在点亮最左边的二极
--管时,表示写成功;该程序写入的数据是7,操作的从机地址是第三单元,对
--数据写入的地址单元用户可以通过改变从机地址sub_address来修改,数据
--的设置用户也可以通过改写程序中的data的数据来自行设置。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL; --写成功
entity write_to_24c02 is
Port ( sysclk,reset : in std_logic;
sda,scl : inout std_logic;
cs: out std_logic;
s:out std_logic_vector(7 downto 0)
);
end write_to_24c02;
architecture Behavioral of write_to_24c02 is
type state is (prepare,start,transmit_slave_address,check_ack1,transmit_sub_address,check_ack2,
transmit_data,check_ack3,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,data: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";
current_state<=prepare;data:="00000111";
s<="11111111";
elsif rising_edge(clock) then
case current_state is
when prepare=>cnt:=cnt+1;-- --准备状态,等各个器件复位
if cnt="0000010" then cnt:="0000000";current_state<=start;
else current_state<=prepare;
end if;
when start=>count1:=count1+1; --起始信号产生状态
case count1 is
when 1=>sda<='1';
when 2=>scl<='1';
when 3=>sda<='0';
when 4=>scl<='0';
when 5=>count1:=0;current_state<=transmit_slave_address;
when others=>null;
end case;
when transmit_slave_address=>count1:=count1+1;s<="01111111"; --发送器件从地址
case count1 is
when 1=>sda<=slave_address(cnt1);
when 2=>scl<='1';
when 3=>scl<='0';
when 4=>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;s<="10111111"; --查询应答信号
case count1 is
when 1=>sda<='0';
when 2=>scl<='1';
when 3=>scl<='0';
when 4=>
current_state<=transmit_sub_address;
count1:=0;
when others=>null;
end case;
when transmit_sub_address=>count1:=count1+1;s<="11011111"; --发送器件子地址
case count1 is
when 1=>sda<=sub_address(cnt1);
when 2=>scl<='1';
when 3=>scl<='0';
when 4=>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; s<="11101111"; --查询应答信号
case count1 is
when 1=>sda<='0';
when 2=>scl<='1';
when 3=>scl<='0';
when 4=>current_state<=transmit_data;
count1:=0;
when others=>null;
end case;
when transmit_data=>count1:=count1+1;s<="11110111"; --发送数据
case count1 is
when 1=>sda<=data(cnt1);
when 2=>scl<='1';
when 3=>scl<='0';
when 4=>cnt1:=cnt1-1;count1:=0;
if cnt1=0 then cnt1:=8;
current_state<=check_ack3;
else current_state<=transmit_data;
end if;
when others=>null;
end case;
when check_ack3=>count1:=count1+1;s<="11111011"; --查询应答信号
case count1 is
when 1=>sda<='0';
when 2=>scl<='1';
when 3=>scl<='0';
when 4=>
current_state<=stop;
count1:=0;
when others=>null;
end case;
when stop=>count1:=count1+1; s<="11111101"; --产生停止信号
case count1 is
when 1=>sda<='0';
when 3=>scl<='1';
when 10=>sda<='1';
when 15=>count1:=0;current_state<=idel;
when others=>null;
end case;
when idel=>sda<='1';scl<='1';current_state<=idel; s<="11111110";
when others=>null;
end case;
end if;
end process;
end Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -