⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read_from_24c02.vhd

📁 一些很好的FPGA设计实例
💻 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 + -