zoukankan      html  css  js  c++  java
  • 利用I2C总线读写AT24C512的FPGA原创代码

      根据上面一篇研究AT24C512的DATASHEET 心得,设计如下利用FPGA读写 AT24C512的原创代码。在本代码中,设计目的,根据指定的页地址,利用随机顺序读方式和页写方式操作AT24C512, 每次读写128字节,即一页数据。
      端口定义如下:
          clk: 时钟信号,设计为20MHZ;
          rst: 复位信号,设计为0复位,1不复位   
          clk200k: i2c总线读写时钟
          sck:  at24c512时钟控制线
         sdata: at24c512数据线
         page_addr: 读写的页地址
        operate_cmd: 读写命令;“00” 表示---读;“01”---表示写
        i2c_ram_rd: RAM读信号,该RAM存放从EEPROM读出的128字节数据
        i2c_ram_rd_addr: RAM读地址,该RAM存放从EEPROM读出的128字节数据
        i2c_ram_rd_data: RAM读数据,该RAM存放从EEPROM读出的128字节数据
        i2c_ram_wr:  RAM写信号,该RAM存放写入EEPROM的128字节数据
        i2c_ram_wr_addr:  RAM写地址,该RAM存放写入EEPROM的128字节数据
        i2c_ram_wr_data:  RAM写数据,该RAM存放写入EEPROM的128字节数据
        i2c_en: i2c模块读写使能信号,高有效
        update: 数据从EEProm读取完毕标志
       err: 从eeprom读取过程中出错故障指示
     
    library ieee;
    use ieee.std_logic_1164.all; 
    use ieee.std_logic_arith.all;
    use ieee.std_logic_signed.all;
    entity i2c is
    port
      (
       clk: in std_logic;
       rst: in std_logic;  
       
       clk200k: in std_logic;
       sck: out std_logic;
       sdata: inout std_logic;
       page_addr: in std_logic_vector(7 downto 0);
       operate_cmd: in std_logic_vector(1 downto 0);
       i2c_ram_rd: in std_logic;
       i2c_ram_rd_addr: in std_logic_vector(6 downto 0);
       i2c_ram_rd_data: out std_logic_vector(7 downto 0);
       i2c_ram_wr: in std_logic;
       i2c_ram_wr_addr: in std_logic_vector(6 downto 0);
       i2c_ram_wr_data: in std_logic_vector(7 downto 0);
       i2c_en: in std_logic;
       update: out std_logic ;
       err: out std_logic;
       rdy: out std_logic
       );
    end i2c;
    architecture arch_i2c of i2c is
    component  altsyncram
     generic (
      operation_mode      : string;
      width_a        : natural;
      widthad_a       : natural;
      width_b        : natural;
      widthad_b       : natural;
      width_byteena_a      : natural;
      outdata_reg_b      : string;
      address_reg_b      : string;
      rdcontrol_reg_b      : string;
      read_during_write_mode_mixed_ports  : string;
      init_file       : string
     );
     port
      (
       wren_a   : in   std_logic ;
       clock0   : in   std_logic ;
       clock1   : in   std_logic ;
       address_a  : in   std_logic_vector (widthad_a-1 downto 0);
       address_b  : in   std_logic_vector (widthad_b-1 downto 0);
       rden_b   : in   std_logic ;
       q_b    : out std_logic_vector (width_b-1 downto 0);
       data_a   : in   std_logic_vector (width_a-1 downto 0)
       );
     end component;
    constant i2c_device_rd:std_logic_vector(7 downto 0):=x"a1";
    constant i2c_device_wr:std_logic_vector(7 downto 0):=x"a0";
    signal i2c_operate_state: std_logic_vector(7 downto 0);
    signal i2c_operate_cnt : integer range 0 to 7;
    signal i2c_operate_byte_nums:integer range 0 to 127;
    signal i2c_operate_data: std_logic_vector(7 downto 0);
    signal i2c_operate_wr: std_logic;
    signal i2c_operate_wr_addr: std_logic_vector(6 downto 0);
    signal i2c_operate_wr_data: std_logic_vector(7 downto 0);
    signal i2c_operate_rd: std_logic;
    signal i2c_operate_rd_addr: std_logic_vector(6 downto 0);
    signal i2c_operate_rd_data: std_logic_vector(7 downto 0);
    begin
    -----------filter cell data---------------------------------------
    i2c_ram_rd_ins : altsyncram
     generic map
     (
      operation_mode       => "dual_port",
      width_a               => 8,
      widthad_a        => 7,
      width_b               => 8,
      widthad_b        => 7,
      width_byteena_a             => 1,
      outdata_reg_b       => "unregistered",
      address_reg_b       => "clock1",
      rdcontrol_reg_b             => "clock1",
      read_during_write_mode_mixed_pORts  => "old_data",
      init_file              =>"rx_data_ram.mif"
     )
     port map (
      wren_a         => i2c_operate_wr,      
      clock0         => clk,
      clock1         => clk,          
      address_a        => i2c_operate_wr_addr,  
      address_b        => i2c_ram_rd_addr,     
      rden_b         => i2c_ram_rd,           
      data_a         => i2c_operate_wr_data,    
      q_b                => i2c_ram_rd_data            
     );
     
    i2c_ram_wr_ins : altsyncram
     generic map
     (
      operation_mode       => "dual_port",
      width_a               => 8,
      widthad_a        => 7,
      width_b               => 8,
      widthad_b        => 7,
      width_byteena_a             => 1,
      outdata_reg_b       => "unregistered",
      address_reg_b       => "clock1",
      rdcontrol_reg_b             => "clock1",
      read_during_write_mode_mixed_pORts  => "old_data",
      init_file              =>"rx_data_ram.mif"
     )
     port map (
      wren_a         => i2c_ram_wr,      
      clock0         => clk,
      clock1         => clk,          
      address_a        => i2c_ram_wr_addr,  
      address_b        => i2c_operate_rd_addr,     
      rden_b         => i2c_operate_rd,           
      data_a         => i2c_ram_wr_data,    
      q_b         => i2c_operate_rd_data            
     );
     
     i2c_operate: process(clk,rst)
      begin
      if (rst='0') then
          sck<='0';
          sdata<='Z';
          i2c_operate_wr_data<=(others=>'0');
          i2c_operate_wr_addr<=(others=>'0');
          i2c_operate_wr<='0';
          i2c_operate_rd_addr<=(others=>'0');
          i2c_operate_rd<='0';
          i2c_operate_state<=(others=>'0');
          update<='0';
          err<='0';
          rdy<='0';
      elsif clk'event and clk='1' then
        if (clk200k='1') then
      --------------start bit --------------------
          if (i2c_operate_state=x"00") then 
          --  if (i2c_en='1') then       
             if((operate_cmd="00") or  (operate_cmd="10") ) then
               i2c_operate_state<=x"01";
             end if;   
         --  end if;
             sck<='0';  
             sdata<='1';        
          elsif  (i2c_operate_state=x"01") then
             sck<='1';        
             i2c_operate_state<=x"02";    
          elsif  (i2c_operate_state=x"02") then
             sdata<='0';
             i2c_operate_byte_nums<=0;
             i2c_operate_state<=x"03"; 
     -------------Device addre. Firt Page addr Second addr--------------------
          elsif  (i2c_operate_state=x"03") then             
              sck<='0';
             if(i2c_operate_byte_nums=0) then
              i2c_operate_data<=i2c_device_wr;
             elsif (i2c_operate_byte_nums=1) then
              i2c_operate_data<=page_addr;
             elsif (i2c_operate_byte_nums=2) then
              i2c_operate_data<=x"00";
             end if;
             i2c_operate_cnt<=0;
             i2c_operate_state<=x"04";        
         elsif  (i2c_operate_state=x"04") then        
           ----bit data ready---
              sck<='0';    
              sdata<=i2c_operate_data(7);
              i2c_operate_data<=i2c_operate_data(6 downto 0) & '0';
              i2c_operate_state<=x"05";   
         elsif  (i2c_operate_state=x"05") then 
              sck<='1';
              if (i2c_operate_cnt=7) then
                   i2c_operate_cnt<=0;            
                   i2c_operate_state<=x"06"; 
              else
                   i2c_operate_cnt<=i2c_operate_cnt+1;
                   i2c_operate_state<=x"04";   -----clocked data
              end if;
         elsif  (i2c_operate_state=x"06") then
             -----check eeprom ack bit---       
              sck<='0';
              sdata<='Z';
              i2c_operate_state<=x"20"; 
         elsif  (i2c_operate_state=x"20") then
              sck<='1';                 
              if (sdata='0') then                
                    if(i2c_operate_byte_nums=2) then
                      i2c_operate_byte_nums<=0;
                      i2c_operate_state<=x"07"; 
                      i2c_operate_rd_addr<=(others=>'0');
                      i2c_operate_rd<='1';              
                   else
                      i2c_operate_byte_nums<=i2c_operate_byte_nums+1;
                      i2c_operate_state<=x"03"; 
                   end if;
                  i2c_operate_cnt<=0;
              elsif (i2c_operate_cnt=7) then
                  i2c_operate_cnt<=0;
                --  err<='1';
                  ------err------------------
              else
                  i2c_operate_cnt<=i2c_operate_cnt+1;           
              end if;
           elsif  (i2c_operate_state=x"07") then
                 sck<='0';
                 if (operate_cmd="00") then ---read;
                    i2c_operate_state<=x"23";
                 elsif (operate_cmd="01") then --write;
                    i2c_operate_state<=x"31";
                 end if;
                  
                 i2c_operate_rd<='0';
                 i2c_operate_byte_nums<=0;
           elsif  (i2c_operate_state=x"23") then
                 sck<='0';
                 sdata<='1';
                 i2c_operate_state<=x"08";
          ------------read start bit----------------------
           elsif  (i2c_operate_state=x"08") then
                 sck<='1';     
                 i2c_operate_state<=x"09";
           elsif  (i2c_operate_state=x"09") then
                 sdata<='0';
                 i2c_operate_state<=x"0b";
         ------------tx device addre and control cmd------
           elsif  (i2c_operate_state=x"0b") then
                 sck<='0';
                 i2c_operate_data<=i2c_device_rd;
                 i2c_operate_state<=x"0c";
                 i2c_operate_cnt<=0;
           elsif  (i2c_operate_state=x"0c") then
                 sck<='0';
                 sdata<=i2c_operate_data(7);
                 i2c_operate_data<=i2c_operate_data(6 downto 0) &  '0' ;
                 i2c_operate_state<=x"0d";
           elsif  (i2c_operate_state=x"0d") then
                 sck<='1';
                 if (i2c_operate_cnt=7) then
                     i2c_operate_cnt<=0;
                     i2c_operate_state<=x"0e";
                 else
                     i2c_operate_cnt<=i2c_operate_cnt+1;
                     i2c_operate_state<=x"0c";         
                 end if;  
           elsif  (i2c_operate_state=x"0e") then
                  sck<='0';
                  sdata<='Z';
                  i2c_operate_state<=x"21";   
           elsif  (i2c_operate_state=x"21") then
                  sck<='1';
                          
                 if (sdata='0') then 
                   -- err<='1'; 
                   i2c_operate_cnt<=0;
                   i2c_operate_state<=x"22"; 
                 elsif (i2c_operate_cnt=7) then
                   i2c_operate_cnt<=0;
                  -- err<='1';
                   ------err----
                 else
                   i2c_operate_cnt<=i2c_operate_cnt+1;
                 end if;           
           elsif (i2c_operate_state=x"22") then
                 sck<='0';    
                 i2c_operate_state<=x"0f";       
           elsif  (i2c_operate_state=x"0f") then  
                 sck<='1';
                 i2c_operate_data<=i2c_operate_data(6 downto 0) &  sdata ;
                 i2c_operate_wr<='0';
                 i2c_operate_state<=x"10";
                 update<='0';
           elsif  (i2c_operate_state=x"10") then  
                 sck<='0';
                 if(i2c_operate_cnt=7) then
                   i2c_operate_cnt<=0;          
                   i2c_operate_wr_data<=i2c_operate_data;
                   i2c_operate_wr<='1';
                   i2c_operate_state<=x"24";
                 else
                    i2c_operate_cnt<=i2c_operate_cnt+1;
                    i2c_operate_state<=x"0f";
                 end if; 
           elsif (i2c_operate_state=x"24") then  
                  if(i2c_operate_byte_nums=127) then
                      i2c_operate_state<=x"13";  
                      i2c_operate_byte_nums<=0;       
                      i2c_operate_wr_addr<=(others=>'0');  
                      update<='1';  
                      sdata<='1';         
                   else
                      i2c_operate_byte_nums<=i2c_operate_byte_nums+1;
                      i2c_operate_wr_addr<=i2c_operate_wr_addr+"0000001";
                      i2c_operate_state<=x"11";
                      sdata<='0'; 
                   end if;
        
        --------------------tx ACK bit=zero-------------------
           elsif  (i2c_operate_state=x"11") then  
                 i2c_operate_wr<='0';
                 sck<='1';       
                 i2c_operate_state<=x"12";
           elsif  (i2c_operate_state=x"12") then  
                 sck<='0';
                 sdata<='Z';
                 i2c_operate_state<=x"0f";    ----------receive next data
       ---------------------tx NO ACK bit=one------------------
           elsif  (i2c_operate_state=x"13") then 
                 update<='0';
                 i2c_operate_wr<='0';
                 sck<='1';
                 i2c_operate_state<=x"14";  
           elsif  (i2c_operate_state=x"14") then 
                 sck<='0';
                 sdata<='Z';
                 i2c_operate_state<=x"15"; 
      ---------------------write operate------------------------ 
           elsif (i2c_operate_state=x"31") then 
                 sck<='0';
                 i2c_operate_data<=i2c_operate_rd_data;
               --  if (i2c_operate_rd_data="00001111") then
               --       err<='1';
               --  end if;
                 i2c_operate_cnt<=0;
                 i2c_operate_state<=x"32"; 
           elsif (i2c_operate_state=x"32") then 
                 sck<='0';
                 sdata<=i2c_operate_data(7);
                 i2c_operate_data<=i2c_operate_data(6 downto 0) & '0';
                 i2c_operate_state<=x"33"; 
                 i2c_operate_rd<='0';
           elsif  (i2c_operate_state=x"33") then 
                 sck<='1';
                 if (i2c_operate_cnt=7) then 
                     i2c_operate_cnt<=0;
                     i2c_operate_state<=x"34"; 
                    if (i2c_operate_rd_addr="1111111") then
                         i2c_operate_rd_addr<=(others=>'0');
                    else
                         i2c_operate_rd_addr<=i2c_operate_rd_addr+"0000001"; 
                    end if;
                    i2c_operate_rd<='1';
                    
                 else
                     i2c_operate_cnt<=i2c_operate_cnt+1;
                     i2c_operate_state<=x"32"; 
                 end if; 
           elsif  (i2c_operate_state=x"34") then 
                 i2c_operate_rd<='0';
                 sck<='0';
                 sdata<='Z';
                 i2c_operate_state<=x"35"; 
           elsif  (i2c_operate_state=x"35") then 
                 sck<='1';        
                 if (sdata='0') then
                    i2c_operate_cnt<=0;            
                    if ( i2c_operate_byte_nums=127) then
                         i2c_operate_byte_nums<=0;
                         i2c_operate_state<=x"15";   -----stop bit
                    --     err<='1';
                    else
                         i2c_operate_byte_nums<=i2c_operate_byte_nums+1;
                         i2c_operate_state<=x"31";
                    end if;
                                      
                 elsif (i2c_operate_cnt=7) then
                    i2c_operate_cnt<=0;
                   -- err<='1';
                    ----err---
                 else
                    i2c_operate_cnt<=i2c_operate_cnt+1;
                 end if;           
       --------------------stop bit -------------------------------------
           elsif  (i2c_operate_state=x"15") then 
                 sdata<='0';
                 sck<='0';
                 rdy<='1';
                 i2c_operate_state<=x"16";  
           elsif  (i2c_operate_state=x"16") then 
                 sck<='1';
                 i2c_operate_state<=x"17";  
          elsif  (i2c_operate_state=x"17") then 
                 sdata<='1';
                 i2c_operate_state<=x"18"; 
          elsif  (i2c_operate_state=x"18") then 
                 sck<='0';
                 i2c_operate_state<=x"00"; 
                 rdy<='0';
                -- err<='1';
          else
                 i2c_operate_data<=(others=>'0');
                 i2c_operate_cnt<=0;
                 i2c_operate_byte_nums<=0;
                 i2c_operate_state<=x"00";
                 sck<='1';
                 sdata<='Z';      
           end if;
         end if;
       end if;
       end process i2c_operate;
       end arch_i2c;
  • 相关阅读:
    贷款计算公式
    P2P行业专业术语(最全)
    p2p投资理财入门篇(新手必备)
    2015年p2p网络借贷平台的发展现状
    MyEclipse中SVN的常见的使用方法
    linux下打开、关闭tomcat,实时查看tomcat运行日志
    Spring 向页面传值以及接受页面传过来的参数的方式
    Spring自定义一个拦截器类SomeInterceptor,实现HandlerInterceptor接口及其方法的实例
    PowerDesigner概述(系统分析与建模)以及如何用PowerDesigner快速的创建出这个数据库
    MySQL 8.x 函数和操作符,官方网址:https://dev.mysql.com/doc/refman/8.0/en/functions.html
  • 原文地址:https://www.cnblogs.com/zcf287/p/2801193.html
Copyright © 2011-2022 走看看